cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
mech_acl.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Mechanism ACLs *
4 * Copyright Peter Gutmann 1997-2004 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "acl.h"
11  #include "kernel.h"
12 #else
13  #include "crypt.h"
14  #include "kernel/acl.h"
15  #include "kernel/kernel.h"
16 #endif /* Compiler-specific includes */
17 
18 /* A pointer to the kernel data block */
19 
20 static KERNEL_DATA *krnlData = NULL;
21 
22 /****************************************************************************
23 * *
24 * Mechanism ACLs *
25 * *
26 ****************************************************************************/
27 
28 /* The ACL tables for each mechanism class */
29 
30 static const MECHANISM_ACL FAR_BSS mechanismWrapACL[] = {
31  /* PKCS #1 encrypt */
33  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped key */
35  MKACP_S_NONE(),
37  ACL_FLAG_HIGH_STATE ), /* Ctx containing key */
38  MKACP_O( ST_CTX_PKC, /* Wrap PKC context */
40  MKACP_UNUSED(),
41  MKACP_UNUSED() } },
42 
43  /* PKCS #1 encrypt using PGP formatting */
44 #ifdef USE_PGP
46  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped key */
48  MKACP_S_NONE(),
49  MKACP_O( ST_CTX_CONV, /* Ctx containing key */
51  MKACP_O( ST_CTX_PKC, /* Wrap PKC context */
53  MKACP_UNUSED(),
54  MKACP_UNUSED() } },
55 #endif /* USE_PGP */
56 
57  /* PKCS #1 encrypt of raw data */
59  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped raw data */
61  MKACP_S( MIN_KEYSIZE, /* Raw data */
63  MKACP_UNUSED(),
64  MKACP_O( ST_CTX_PKC, /* Wrap PKC context */
66  MKACP_UNUSED(),
67  MKACP_UNUSED() } },
68 
69  /* OAEP encrypt */
70 #ifdef USE_OAEP
72  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped key */
74  MKACP_S_NONE(),
76  ACL_FLAG_HIGH_STATE ), /* Ctx containing key */
77  MKACP_O( ST_CTX_PKC, /* Wrap PKC context */
79  MKACP_UNUSED(),
81  /* The algoID CRYPT_ALGO_SHA2 + 1 (= CRYPT_ALGO_SHAng) is a
82  special-case placeholder for SHA2-512 until its fate/
83  potential future usage becomes a bit clearer */
84 #endif /* USE_OAEP */
85 
86  /* CMS key wrap */
88  { MKACP_S_OPT( 8 + 8, CRYPT_MAX_KEYSIZE + 16 ),/* Wrapped key */
89  MKACP_S_NONE(),
91  ACL_FLAG_HIGH_STATE ), /* Ctx containing key */
92  MKACP_O( ST_CTX_CONV, /* Wrap context */
94  MKACP_UNUSED(),
95  MKACP_UNUSED() } },
96 
97  /* PKCS #15 private key wrap */
100  MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
101  MKACP_S_NONE(),
102  MKACP_O( ST_CTX_PKC, /* Ctx containing private key */
104  MKACP_O( ST_CTX_CONV, /* Wrap context */
106  MKACP_UNUSED(),
107  MKACP_UNUSED() } },
108 
109  /* PKCS #8 private key wrap */
110 #ifdef USE_PKCS12
113  MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
114  MKACP_S_NONE(),
115  MKACP_O( ST_CTX_PKC, /* Ctx containing private key */
117  MKACP_O( ST_CTX_CONV, /* Wrap context */
119  MKACP_UNUSED(),
120  MKACP_UNUSED() } },
121 #endif /* USE_PKCS12 */
122 
123  /* End-of-ACL marker */
124  { MECHANISM_NONE,
125  { MKACP_END() } },
126  { MECHANISM_NONE,
127  { MKACP_END() } }
128  };
129 
130 static const MECHANISM_ACL FAR_BSS mechanismUnwrapACL[] = {
131  /* PKCS #1 decrypt */
133  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped key */
135  MKACP_S_NONE(),
137  ACL_FLAG_LOW_STATE ), /* Ctx to contain key */
138  MKACP_O( ST_CTX_PKC, /* Unwrap PKC context */
140  MKACP_UNUSED(),
141  MKACP_UNUSED() } },
142 
143  /* PKCS #1 decrypt using PGP formatting */
144 #ifdef USE_PGP
146  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped key */
148  MKACP_S_NONE(),
149  MKACP_UNUSED(), /* Placeholder for ctx to contain key */
150  MKACP_O( ST_CTX_PKC, /* Unwrap PKC context */
152  MKACP_UNUSED(),
153  MKACP_UNUSED() } },
154 #endif /* USE_PGP */
155 
156  /* PKCS #1 decrypt of raw data */
158  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped raw data */
160  MKACP_S( MIN_KEYSIZE, /* Raw data */
162  MKACP_UNUSED(),
163  MKACP_O( ST_CTX_PKC, /* Unwrap PKC context */
165  MKACP_UNUSED(),
166  MKACP_UNUSED() } },
167 
168  /* OAEP decrypt */
169 #ifdef USE_OAEP
171  { MKACP_S_OPT( MIN_PKCSIZE, /* Wrapped key */
173  MKACP_S_NONE(),
175  ACL_FLAG_LOW_STATE ), /* Ctx to contain key */
176  MKACP_O( ST_CTX_PKC, /* Unwrap PKC context */
178  MKACP_UNUSED(),
180  /* The algoID CRYPT_ALGO_SHA2 + 1 (= CRYPT_ALGO_SHAng) is a
181  special-case placeholder for SHA2-512 until its fate/
182  potential future usage becomes a bit clearer */
183 #endif /* USE_OAEP */
184 
185  /* CMS key unwrap */
187  { MKACP_S( 8 + 8, CRYPT_MAX_KEYSIZE + 16 ),/* Wrapped key */
188  MKACP_S_NONE(),
190  ACL_FLAG_LOW_STATE ), /* Ctx to contain key */
191  MKACP_O( ST_CTX_CONV, /* Unwrap context */
193  MKACP_UNUSED(),
194  MKACP_UNUSED() } },
195 
196  /* PKCS #15 private key unwrap */
199  MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
200  MKACP_S_NONE(),
201  MKACP_O( ST_CTX_PKC, /* Ctx to contain private key */
203  MKACP_O( ST_CTX_CONV, /* Unwrap context */
205  MKACP_UNUSED(),
206  MKACP_UNUSED() } },
207 
208  /* PKCS #8 private key unwrap */
209 #ifdef USE_PKCS12
212  MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
213  MKACP_S_NONE(),
214  MKACP_O( ST_CTX_PKC, /* Ctx to contain private key */
216  MKACP_O( ST_CTX_CONV, /* Unwrap context */
218  MKACP_UNUSED(),
219  MKACP_UNUSED() } },
220 #endif /* USE_PKCS12 */
221 
222  /* PGP 2.x private key unwrap */
223 #ifdef USE_PGPKEYS
226  MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
227  MKACP_S_NONE(),
228  MKACP_O( ST_CTX_PKC, /* Ctx to contain private key */
230  MKACP_O( ST_CTX_CONV, /* Unwrap context */
232  MKACP_UNUSED(),
233  MKACP_UNUSED() } },
234 #endif /* USE_PGPKEYS */
235 
236  /* PGP 5.x private key unwrap */
237 #ifdef USE_PGPKEYS
240  MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
241  MKACP_S_NONE(),
242  MKACP_O( ST_CTX_PKC, /* Ctx to contain private key */
244  MKACP_O( ST_CTX_CONV, /* Unwrap context */
246  MKACP_UNUSED(),
247  MKACP_UNUSED() } },
248 #endif /* USE_PGPKEYS */
249 
250  /* OpenPGP private key unwrap */
251 #ifdef USE_PGPKEYS
254  MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
255  MKACP_S_NONE(),
256  MKACP_O( ST_CTX_PKC, /* Ctx to contain private key */
258  MKACP_O( ST_CTX_CONV, /* Unwrap context */
260  MKACP_UNUSED(),
261  MKACP_UNUSED() } },
262 #endif /* USE_PGPKEYS */
263 
264  /* End-of-ACL marker */
265  { MECHANISM_NONE,
266  { MKACP_END() } },
267  { MECHANISM_NONE,
268  { MKACP_END() } }
269  };
270 
271 static const MECHANISM_ACL FAR_BSS mechanismSignACL[] = {
272  /* PKCS #1 sign */
274  { MKACP_S_OPT( MIN_PKCSIZE, /* Signature */
276  MKACP_O( ST_CTX_HASH, /* Hash context */
278  MKACP_UNUSED(), /* Secondary hash context */
279  MKACP_O( ST_CTX_PKC, /* Signing context */
281 
282  /* SSL sign with dual hashes */
283 #ifdef USE_SSL
285  { MKACP_S_OPT( MIN_PKCSIZE, /* Signature */
287  MKACP_O( ST_CTX_HASH, /* Hash context */
289  MKACP_O( ST_CTX_HASH, /* Secondary hash context */
291  MKACP_O( ST_CTX_PKC, /* Signing context */
293 #endif /* USE_SSL */
294 
295  /* End-of-ACL marker */
296  { MECHANISM_NONE,
297  { MKACP_END() } },
298  { MECHANISM_NONE,
299  { MKACP_END() } }
300  };
301 
302 static const MECHANISM_ACL FAR_BSS mechanismSigCheckACL[] = {
303  /* PKCS #1 sig check */
305  { MKACP_S( MIN_PKCSIZE, /* Signature */
307  MKACP_O( ST_CTX_HASH, /* Hash context */
309  MKACP_UNUSED(), /* Secondary hash context */
310  MKACP_O( ST_CTX_PKC, /* Sig.check context */
312 
313  /* SSL sign with dual hashes */
314 #ifdef USE_SSL
316  { MKACP_S( MIN_PKCSIZE, /* Signature */
318  MKACP_O( ST_CTX_HASH, /* Hash context */
320  MKACP_O( ST_CTX_HASH, /* Secondary hash context */
322  MKACP_O( ST_CTX_PKC, /* Sig.check context */
324 #endif /* USE_SSL */
325 
326  /* End-of-ACL marker */
327  { MECHANISM_NONE,
328  { MKACP_END() } },
329  { MECHANISM_NONE,
330  { MKACP_END() } }
331  };
332 
333 static const MECHANISM_ACL FAR_BSS mechanismDeriveACL[] = {
334  /* PKCS #5 derive */
336  { MKACP_S( 1, CRYPT_MAX_KEYSIZE ), /* Key data */
337  MKACP_S( MIN_NAME_LENGTH, MAX_ATTRIBUTE_SIZE ),/* Keying material */
339  MKACP_N( 0, CRYPT_MAX_HASHSIZE ), /* Hash parameters */
340  MKACP_S( 4, 512 ), /* Salt */
341  MKACP_N( 1, MAX_KEYSETUP_ITERATIONS ) } }, /* Iterations */
342 
343  /* SSL derive */
344 #ifdef USE_SSL
346  { MKACP_S( 48, 512 ), /* Master secret/key data */
347  MKACP_S( 48, CRYPT_MAX_PKCSIZE ), /* Premaster secret/master secret */
348  MKACP_N( CRYPT_USE_DEFAULT, CRYPT_USE_DEFAULT ),/* SSL uses dual hash */
349  MKACP_N( 0, 0 ), /* Hash parameters */
350  MKACP_S( 64, 64 ), /* Salt */
351  MKACP_N( 1, 1 ) } }, /* Iterations */
352 #endif /* USE_SSL */
353 
354  /* TLS/TLS 1.2 derive. The odd lower bounds on the output and salt are
355  needed when generating the TLS hashed MAC and (for the salt and
356  output) and when generating a master secret from a fixed shared key
357  (for the input) */
358 #ifdef USE_SSL
360  { MKACP_S( 12, 512 ), /* Master secret/key data (usually 48) */
361  MKACP_S( 6, CRYPT_MAX_PKCSIZE ), /* Premaster secret/master secret (us'ly 48) */
362  MKACP_N( CRYPT_USE_DEFAULT, CRYPT_USE_DEFAULT ),/* TLS uses dual hash */
363  MKACP_N( 0, 0 ), /* Hash parameters */
364  MKACP_S( 13, 512 ), /* Salt (usually 64) */
365  MKACP_N( 1, 1 ) } }, /* Iterations */
367  { MKACP_S( 12, 512 ), /* Master secret/key data (usually 48) */
368  MKACP_S( 6, CRYPT_MAX_PKCSIZE ), /* Premaster secret/master secret (us'ly 48) */
369  MKACP_N( CRYPT_ALGO_SHA2, CRYPT_ALGO_SHAng ),/* Hash algo */
370  MKACP_N( 0, CRYPT_MAX_HASHSIZE ), /* Hash parameters */
371  MKACP_S( 13, 512 ), /* Salt (usually 64) */
372  MKACP_N( 1, 1 ) } }, /* Iterations */
373 #endif /* USE_SSL */
374 
375  /* CMP/Entrust derive */
376 #ifdef USE_CMP
378  { MKACP_S( 20, 20 ), /* HMAC-SHA key */
379  MKACP_S( 1, 512 ), /* Key data */
380  MKACP_N( CRYPT_ALGO_SHA1, CRYPT_ALGO_SHA1 ),/* Hash algo */
381  MKACP_N( 0, 0 ), /* Hash parameters */
382  MKACP_S( 1, 512 ), /* Salt */
383  MKACP_N( 1, MAX_KEYSETUP_ITERATIONS ) } }, /* Iterations */
384 #endif /* USE_CMP */
385 
386  /* OpenPGP S2K derive. The INT_MAX bound on the iterations instead of
387  the more usual MAX_KEYSETUP_ITERATIONS is because of PGP's strange
388  handling of this value by counting bytes to process through the
389  PRF rather than actual PRF iterations. The value passed in is the
390  byte count without an additional '* 64' scaling factor which is
391  applied by the S2K code so we divide the INT_MAX bound by 64 to
392  ensure that the scaled result will still fit into an integer */
393 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
395  { MKACP_S( 16, CRYPT_MAX_KEYSIZE ), /* Key data */
396  MKACP_S( MIN_NAME_LENGTH, MAX_ATTRIBUTE_SIZE ),/* Keying material */
397  MKACP_N( CRYPT_ALGO_MD5, CRYPT_ALGO_SHA256 ),/* Hash algo */
398  MKACP_N( 0, 0 ), /* Hash parameters */
399  MKACP_S( 8, 8 ), /* Salt */
400  MKACP_N( 0, INT_MAX >> 6 ) } }, /* Iterations (0 = don't iterate) */
401 #endif /* USE_PGP || USE_PGPKEYS */
402 
403  /* PKCS #12 derive */
404 #ifdef USE_PKCS12
406  { MKACP_S( 5, CRYPT_MAX_KEYSIZE ), /* Key data (5 for RC2-40) */
407  MKACP_S( MIN_NAME_LENGTH, CRYPT_MAX_TEXTSIZE ),/* Keying material */
408  MKACP_N( CRYPT_ALGO_SHA1, CRYPT_ALGO_SHA1 ),/* Hash algo */
409  MKACP_N( 0, 0 ), /* Hash parameters */
410  MKACP_S( 9, 512 ), /* Salt (+ ID byte) */
411  MKACP_N( 1, MAX_KEYSETUP_ITERATIONS ) } }, /* Iterations */
412 #endif /* USE_PKCS12 */
413 
414  /* End-of-ACL marker */
415  { MECHANISM_NONE,
416  { MKACP_END() } },
417  { MECHANISM_NONE,
418  { MKACP_END() } }
419  };
420 
421 static const MECHANISM_ACL FAR_BSS mechanismKDFACL[] = {
422  /* PKCS #5 KDF */
425  ACL_FLAG_LOW_STATE ), /* Key data */
427  ACL_FLAG_HIGH_STATE ), /* Keying material */
429  MKACP_N( 0, CRYPT_MAX_HASHSIZE ), /* Hash parameters */
430  MKACP_S( 8, CRYPT_MAX_TEXTSIZE ) } }, /* Salt */
431 
432  /* End-of-ACL marker */
433  { MECHANISM_NONE,
434  { MKACP_END() } },
435  { MECHANISM_NONE,
436  { MKACP_END() } }
437  };
438 
439 /****************************************************************************
440 * *
441 * Init/Shutdown Functions *
442 * *
443 ****************************************************************************/
444 
446 int initMechanismACL( INOUT KERNEL_DATA *krnlDataPtr )
447  {
448  assert( isWritePtr( krnlDataPtr, sizeof( KERNEL_DATA ) ) );
449 
450  /* Set up the reference to the kernel data block */
451  krnlData = krnlDataPtr;
452 
453  return( CRYPT_OK );
454  }
455 
456 void endMechanismACL( void )
457  {
458  krnlData = NULL;
459  }
460 
461 /****************************************************************************
462 * *
463 * Mechanism ACL Check Functions *
464 * *
465 ****************************************************************************/
466 
467 /* Functions to implement the checks in the mechanism ACL tables */
468 
470 int preDispatchCheckMechanismWrapAccess( IN_HANDLE const int objectHandle,
472  IN_BUFFER_C( sizeof( MECHANISM_WRAP_INFO ) ) \
474  const void *messageDataPtr,
475  IN_ENUM( MECHANISM ) const int messageValue,
476  STDC_UNUSED const void *dummy )
477  {
479  ( MECHANISM_WRAP_INFO * ) messageDataPtr;
480  const MECHANISM_ACL *mechanismACL = \
481  ( ( message & MESSAGE_MASK ) == MESSAGE_DEV_EXPORT ) ? \
482  mechanismWrapACL : mechanismUnwrapACL;
483  const OBJECT_INFO *objectTable = krnlData->objectTable;
484  const int mechanismAclSize = \
485  ( ( message & MESSAGE_MASK ) == MESSAGE_DEV_EXPORT ) ? \
486  FAILSAFE_ARRAYSIZE( mechanismWrapACL, MECHANISM_ACL ) : \
487  FAILSAFE_ARRAYSIZE( mechanismUnwrapACL, MECHANISM_ACL );
488  BOOLEAN isRawMechanism;
489  int contextHandle, i;
490 
491  assert( isReadPtr( messageDataPtr, sizeof( MECHANISM_WRAP_INFO ) ) );
492 
493  /* Precondition */
494  REQUIRES( isValidObject( objectHandle ) );
495  REQUIRES( message == MESSAGE_DEV_EXPORT || \
496  message == IMESSAGE_DEV_EXPORT || \
497  message == MESSAGE_DEV_IMPORT || \
498  message == IMESSAGE_DEV_IMPORT );
499  REQUIRES( messageValue == MECHANISM_ENC_PKCS1 || \
500  messageValue == MECHANISM_ENC_PKCS1_PGP || \
501  messageValue == MECHANISM_ENC_PKCS1_RAW || \
502  messageValue == MECHANISM_ENC_OAEP || \
503  messageValue == MECHANISM_ENC_CMS || \
504  messageValue == MECHANISM_PRIVATEKEYWRAP || \
505  messageValue == MECHANISM_PRIVATEKEYWRAP_PKCS8 || \
506  messageValue == MECHANISM_PRIVATEKEYWRAP_PGP2 || \
507  messageValue == MECHANISM_PRIVATEKEYWRAP_OPENPGP_OLD || \
508  messageValue == MECHANISM_PRIVATEKEYWRAP_OPENPGP );
509 
510  /* Find the appropriate ACL for this mechanism */
511  for( i = 0; i < mechanismAclSize && \
512  mechanismACL[ i ].type != messageValue && \
513  mechanismACL[ i ].type != MECHANISM_NONE; i++ );
514  ENSURES( i < mechanismAclSize );
515  ENSURES( mechanismACL[ i ].type != MECHANISM_NONE );
516  mechanismACL = &mechanismACL[ i ];
517  isRawMechanism = \
518  ( paramInfo( mechanismACL, 2 ).valueType == PARAM_VALUE_UNUSED ) ? \
519  TRUE : FALSE;
520 
521  /* Inner precondition: We have an ACL for this mechanism, and the non-
522  user-supplied parameters (the ones supplied by cryptlib that must
523  be OK) are in order */
524  REQUIRES( mechanismACL->type != MECHANISM_NONE );
525  REQUIRES( checkParamString( paramInfo( mechanismACL, 0 ),
526  mechanismInfo->wrappedData,
527  mechanismInfo->wrappedDataLength ) );
528  REQUIRES( checkParamString( paramInfo( mechanismACL, 1 ),
529  mechanismInfo->keyData,
530  mechanismInfo->keyDataLength ) );
531  REQUIRES( checkParamObject( paramInfo( mechanismACL, 4 ),
532  mechanismInfo->auxContext ) );
533 
534  /* Make sure that the user-supplied parameters are in order, part 1: The
535  session key is a valid object of the correct type, and there's a key
536  loaded/not loaded as appropriate */
537  if( !isRawMechanism )
538  {
539  if( !fullObjectCheck( mechanismInfo->keyContext, message ) )
540  return( CRYPT_ARGERROR_NUM1 );
541  if( paramInfo( mechanismACL, 2 ).flags & ACL_FLAG_ROUTE_TO_CTX )
542  {
543  /* The key being wrapped may be accessed via an object such as a
544  certificate that isn't the required object type, in order to
545  perform the following check on it we have to first find the
546  ultimate target object */
547  contextHandle = findTargetType( mechanismInfo->keyContext,
549  if( cryptStatusError( contextHandle ) )
550  return( CRYPT_ARGERROR_NUM1 );
551  }
552  else
553  contextHandle = mechanismInfo->keyContext;
554  if( !checkParamObject( paramInfo( mechanismACL, 2 ), contextHandle ) )
555  return( CRYPT_ARGERROR_NUM1 );
556  }
557  else
558  {
559  /* For raw wrap/unwrap mechanisms the data is supplied as string
560  data. In theory this would be somewhat risky since it allows
561  bypassing of object ownership checks, however these mechanisms
562  are only accessed from deep within cryptlib (e.g. by the SSH and
563  SSL/TLS session code, which needs to handle protocol-specific
564  secret data in special ways) so there's no chance for problems
565  since the contexts it ends up in are cryptlib-internal,
566  automatically-created ones belonging to the owner of the session
567  object */
568  REQUIRES( checkParamObject( paramInfo( mechanismACL, 2 ),
569  mechanismInfo->keyContext ) );
570  }
571 
572  /* Make sure that the user-supplied parameters are in order, part 2: The
573  wrapping key is a valid object of the correct type with a key loaded */
574  if( !fullObjectCheck( mechanismInfo->wrapContext, message ) )
575  return( CRYPT_ARGERROR_NUM2 );
576  if( paramInfo( mechanismACL, 3 ).flags & ACL_FLAG_ROUTE_TO_CTX )
577  {
578  /* The wrapping key may be accessed via an object such as a
579  certificate that isn't the required object type, in order to
580  perform the following check on it we have to first find the
581  ultimate target object */
582  contextHandle = findTargetType( mechanismInfo->wrapContext,
584  if( cryptStatusError( contextHandle ) )
585  return( CRYPT_ARGERROR_NUM2 );
586  }
587  else
588  contextHandle = mechanismInfo->wrapContext;
589  if( !checkParamObject( paramInfo( mechanismACL, 3 ), contextHandle ) )
590  return( CRYPT_ARGERROR_NUM2 );
591 
592  /* Make sure that the user-supplied parameters are in order, part 3: Any
593  auxiliary info needed for the wrapping/unwrapping is OK. Reporting
594  the specific problem with these checks is a bit tricky because they
595  apply to parameters coming from deep within cryptlib-internal
596  functions that will never been seen by the user, so it doesn't really
597  make sense to report a parameter error for a parameter that the user
598  doesn't know exists. The best that we can do is return a bad-data
599  error (sol lucet omnibus), since the auxInfo value has been read from
600  externally-supplied encoded data */
601  if( !checkParamNumeric( paramInfo( mechanismACL, 5 ),
602  mechanismInfo->auxInfo ) )
603  return( CRYPT_ERROR_BADDATA );
604 
605  /* Postcondition: The wrapping key and session key are of the appropriate
606  type, there are keys loaded/not loaded as appropriate, and the access
607  is valid. We don't explicitly state this since it's just
608  regurgitating the checks already performed above */
609 
610  /* Make sure that all of the objects have the same owner */
611  if( isRawMechanism )
612  {
613  if( !isSameOwningObject( objectHandle, mechanismInfo->wrapContext ) )
614  return( CRYPT_ARGERROR_NUM2 );
615  }
616  else
617  {
618  if( !isSameOwningObject( objectHandle, mechanismInfo->keyContext ) )
619  return( CRYPT_ARGERROR_NUM1 );
620  if( !isSameOwningObject( mechanismInfo->keyContext,
621  mechanismInfo->wrapContext ) )
622  return( CRYPT_ARGERROR_NUM2 );
623  }
624 
625  /* Postcondition: All the objects have the same owner */
626 #ifndef __WINCE__ /* String too long for compiler */
627  ENSURES( ( isRawMechanism && \
628  isSameOwningObject( objectHandle, mechanismInfo->wrapContext ) ) || \
629  ( !isRawMechanism && \
630  isSameOwningObject( objectHandle, mechanismInfo->keyContext ) && \
631  isSameOwningObject( mechanismInfo->keyContext, \
632  mechanismInfo->wrapContext ) ) );
633 #endif /* !__WINCE__ */
634 
635  return( CRYPT_OK );
636  }
637 
639 int preDispatchCheckMechanismSignAccess( IN_HANDLE const int objectHandle,
640  IN_MESSAGE const MESSAGE_TYPE message,
641  IN_BUFFER_C( sizeof( MECHANISM_SIGN_INFO ) ) \
643  const void *messageDataPtr,
644  IN_ENUM( MECHANISM ) const int messageValue,
645  STDC_UNUSED const void *dummy )
646  {
648  ( MECHANISM_SIGN_INFO * ) messageDataPtr;
649  const MECHANISM_ACL *mechanismACL = \
650  ( ( message & MESSAGE_MASK ) == MESSAGE_DEV_SIGN ) ? \
651  mechanismSignACL : mechanismSigCheckACL;
652  const OBJECT_INFO *objectTable = krnlData->objectTable;
653  const int mechanismAclSize = \
654  ( ( message & MESSAGE_MASK ) == MESSAGE_DEV_SIGN ) ? \
655  FAILSAFE_ARRAYSIZE( mechanismSignACL, MECHANISM_ACL ) : \
656  FAILSAFE_ARRAYSIZE( mechanismSigCheckACL, MECHANISM_ACL );
657  int contextHandle, i;
658 
659  assert( isReadPtr( messageDataPtr, sizeof( MECHANISM_WRAP_INFO ) ) );
660 
661  /* Precondition */
662  REQUIRES( isValidObject( objectHandle ) );
663  REQUIRES( message == MESSAGE_DEV_SIGN || \
664  message == IMESSAGE_DEV_SIGN || \
665  message == MESSAGE_DEV_SIGCHECK || \
666  message == IMESSAGE_DEV_SIGCHECK );
667  REQUIRES( messageValue == MECHANISM_SIG_PKCS1 || \
668  messageValue == MECHANISM_SIG_SSL );
669 
670  /* Find the appropriate ACL for this mechanism */
671  for( i = 0; i < mechanismAclSize && \
672  mechanismACL[ i ].type != messageValue && \
673  mechanismACL[ i ].type != MECHANISM_NONE; i++ );
674  ENSURES( i < mechanismAclSize );
675  ENSURES( mechanismACL[ i ].type != MECHANISM_NONE );
676  mechanismACL = &mechanismACL[ i ];
677 
678  /* Inner precondition: We have an ACL for this mechanism, and the non-
679  user-supplied parameters (the ones supplied by cryptlib that must
680  be OK) are in order */
681  REQUIRES( mechanismACL->type != MECHANISM_NONE );
682  REQUIRES( checkParamString( paramInfo( mechanismACL, 0 ),
683  mechanismInfo->signature,
684  mechanismInfo->signatureLength ) );
685 
686  /* Make sure that the user-supplied parameters are in order, part 1: The
687  hash contexts are valid objects of the correct type. If there's a
688  secondary hash context present we report problems with it as a problem
689  with the (logical) single hash context */
690  if( !fullObjectCheck( mechanismInfo->hashContext, message ) )
691  return( CRYPT_ARGERROR_NUM1 );
692  if( !checkParamObject( paramInfo( mechanismACL, 1 ),
693  mechanismInfo->hashContext ) )
694  return( CRYPT_ARGERROR_NUM1 );
695  if( paramInfo( mechanismACL, 2 ).valueType != PARAM_VALUE_UNUSED && \
696  !fullObjectCheck( mechanismInfo->hashContext2, message ) )
697  return( CRYPT_ARGERROR_NUM1 );
698  if( !checkParamObject( paramInfo( mechanismACL, 2 ),
699  mechanismInfo->hashContext2 ) )
700  return( CRYPT_ARGERROR_NUM1 );
701 
702  /* Make sure that the user-supplied parameters are in order, part 2: The
703  sig/sig check context is a valid object of the correct type, and
704  there's a key loaded */
705  if( !fullObjectCheck( mechanismInfo->signContext, message ) )
706  return( CRYPT_ARGERROR_NUM2 );
707  if( paramInfo( mechanismACL, 3 ).flags & ACL_FLAG_ROUTE_TO_CTX )
708  {
709  /* The sig.check key may be accessed via an object such as a
710  certificate that isn't the required object type, in order to
711  perform the following check on it we have to first find the
712  ultimate target object */
713  contextHandle = findTargetType( mechanismInfo->signContext,
715  if( cryptStatusError( contextHandle ) )
716  return( CRYPT_ARGERROR_NUM2 );
717  }
718  else
719  contextHandle = mechanismInfo->signContext;
720  if( !checkParamObject( paramInfo( mechanismACL, 3 ), contextHandle ) )
721  return( CRYPT_ARGERROR_NUM2 );
722 
723  /* Postcondition: The hash and sig/sig check contexts are of the
724  appropriate type, there's a key loaded in the sig/sig check context,
725  and the access is valid. We don't explicitly state this since it's
726  just regurgitating the checks already performed above */
727 
728  /* Make sure that all of the objects have the same owner */
729  if( !isSameOwningObject( objectHandle, mechanismInfo->hashContext ) )
730  return( CRYPT_ARGERROR_NUM1 );
731  if( !isSameOwningObject( mechanismInfo->hashContext, \
732  mechanismInfo->signContext ) )
733  return( CRYPT_ARGERROR_NUM2 );
734  if( paramInfo( mechanismACL, 2 ).valueType != PARAM_VALUE_UNUSED )
735  {
736  if( !isSameOwningObject( objectHandle, mechanismInfo->hashContext2 ) )
737  return( CRYPT_ARGERROR_NUM1 );
738  if( !isSameOwningObject( mechanismInfo->hashContext, \
739  mechanismInfo->signContext ) )
740  return( CRYPT_ARGERROR_NUM2 );
741  }
742 
743  /* Postcondition: All of the objects have the same owner */
744  ENSURES( isSameOwningObject( objectHandle, mechanismInfo->hashContext ) && \
745  isSameOwningObject( mechanismInfo->hashContext, \
746  mechanismInfo->signContext ) );
747 
748  return( CRYPT_OK );
749  }
750 
752 int preDispatchCheckMechanismDeriveAccess( IN_HANDLE const int objectHandle,
753  IN_MESSAGE const MESSAGE_TYPE message,
754  IN_BUFFER_C( sizeof( MECHANISM_DERIVE_INFO ) ) \
756  const void *messageDataPtr,
757  IN_ENUM( MECHANISM ) const int messageValue,
758  STDC_UNUSED const void *dummy )
759  {
760  const MECHANISM_DERIVE_INFO *mechanismInfo = \
761  ( MECHANISM_DERIVE_INFO * ) messageDataPtr;
762  const MECHANISM_ACL *mechanismACL = mechanismDeriveACL;
763  int i;
764 
765  assert( isReadPtr( messageDataPtr, sizeof( MECHANISM_WRAP_INFO ) ) );
766 
767  /* Precondition */
768  REQUIRES( isValidObject( objectHandle ) );
769  REQUIRES( message == MESSAGE_DEV_DERIVE || \
770  message == IMESSAGE_DEV_DERIVE );
771  REQUIRES( messageValue == MECHANISM_DERIVE_PKCS5 || \
772  messageValue == MECHANISM_DERIVE_PKCS12 || \
773  messageValue == MECHANISM_DERIVE_SSL || \
774  messageValue == MECHANISM_DERIVE_TLS || \
775  messageValue == MECHANISM_DERIVE_TLS12 || \
776  messageValue == MECHANISM_DERIVE_CMP || \
777  messageValue == MECHANISM_DERIVE_PGP );
778 
779  /* Find the appropriate ACL for this mechanism */
780  for( i = 0; mechanismACL[ i ].type != messageValue && \
781  mechanismACL[ i ].type != MECHANISM_NONE && \
782  i < FAILSAFE_ARRAYSIZE( mechanismDeriveACL, MECHANISM_ACL );
783  i++ );
784  ENSURES( i < FAILSAFE_ARRAYSIZE( mechanismDeriveACL, MECHANISM_ACL ) );
785  ENSURES( mechanismACL[ i ].type != MECHANISM_NONE );
786  mechanismACL = &mechanismACL[ i ];
787 
788  /* Inner precondition: We have an ACL for this mechanism, and the non-
789  user-supplied parameters (the ones supplied by cryptlib that must
790  be OK) are in order */
791  REQUIRES( mechanismACL->type != MECHANISM_NONE );
792  REQUIRES( checkParamString( paramInfo( mechanismACL, 0 ),
793  mechanismInfo->dataOut,
794  mechanismInfo->dataOutLength ) );
795  REQUIRES( checkParamString( paramInfo( mechanismACL, 1 ),
796  mechanismInfo->dataIn,
797  mechanismInfo->dataInLength ) );
798  REQUIRES( checkParamNumeric( paramInfo( mechanismACL, 2 ),
799  mechanismInfo->hashAlgo ) );
800  REQUIRES( checkParamNumeric( paramInfo( mechanismACL, 3 ),
801  mechanismInfo->hashParam ) );
802  REQUIRES( checkParamString( paramInfo( mechanismACL, 4 ),
803  mechanismInfo->salt,
804  mechanismInfo->saltLength ) );
805  REQUIRES( checkParamNumeric( paramInfo( mechanismACL, 5 ),
806  mechanismInfo->iterations ) );
807 
808  /* This is a pure data-transformation mechanism, there are no objects
809  used so there are no further checks to perform */
810 
811  return( CRYPT_OK );
812  }
813 
815 int preDispatchCheckMechanismKDFAccess( IN_HANDLE const int objectHandle,
816  IN_MESSAGE const MESSAGE_TYPE message,
817  IN_BUFFER_C( sizeof( MECHANISM_KDF_INFO ) ) \
819  const void *messageDataPtr,
820  IN_ENUM( MECHANISM ) const int messageValue,
821  STDC_UNUSED const void *dummy )
822  {
823  const MECHANISM_KDF_INFO *mechanismInfo = \
824  ( MECHANISM_KDF_INFO * ) messageDataPtr;
825  const MECHANISM_ACL *mechanismACL = mechanismKDFACL;
826  const OBJECT_INFO *objectTable = krnlData->objectTable;
827  int i;
828 
829  assert( isReadPtr( messageDataPtr, sizeof( MECHANISM_WRAP_INFO ) ) );
830 
831  /* Precondition */
832  REQUIRES( isValidObject( objectHandle ) );
833  REQUIRES( message == MESSAGE_DEV_KDF || message == IMESSAGE_DEV_KDF );
834  REQUIRES( messageValue == MECHANISM_DERIVE_PKCS5 );
835 
836  /* Find the appropriate ACL for this mechanism */
837  for( i = 0; mechanismACL[ i ].type != messageValue && \
838  mechanismACL[ i ].type != MECHANISM_NONE && \
839  i < FAILSAFE_ARRAYSIZE( mechanismKDFACL, MECHANISM_ACL );
840  i++ );
841  ENSURES( i < FAILSAFE_ARRAYSIZE( mechanismKDFACL, MECHANISM_ACL ) );
842  ENSURES( mechanismACL[ i ].type != MECHANISM_NONE );
843  mechanismACL = &mechanismACL[ i ];
844 
845  /* Inner precondition: We have an ACL for this mechanism, and the non-
846  user-supplied parameters (the ones supplied by cryptlib that must
847  be OK) are in order */
848  REQUIRES( mechanismACL->type != MECHANISM_NONE );
849  REQUIRES( fullObjectCheck( mechanismInfo->keyContext, message ) );
850  REQUIRES( checkParamObject( paramInfo( mechanismACL, 0 ),
851  mechanismInfo->keyContext ) );
852  REQUIRES( fullObjectCheck( mechanismInfo->masterKeyContext, message ) );
853  REQUIRES( checkParamObject( paramInfo( mechanismACL, 1 ),
854  mechanismInfo->masterKeyContext ) );
855  REQUIRES( checkParamNumeric( paramInfo( mechanismACL, 2 ),
856  mechanismInfo->hashAlgo ) );
857  REQUIRES( checkParamNumeric( paramInfo( mechanismACL, 3 ),
858  mechanismInfo->hashParam ) );
859  REQUIRES( checkParamString( paramInfo( mechanismACL, 4 ),
860  mechanismInfo->salt,
861  mechanismInfo->saltLength ) );
862 
863  /* This is a pure data-transformation mechanism, there are no objects
864  used so there are no further checks to perform */
865 
866  return( CRYPT_OK );
867  }