1 /****************************************************************************
2 * *
3 * cryptlib Encryption Context Attribute Routines *
4 * Copyright Peter Gutmann 1992-2011 *
5 * *
6 ****************************************************************************/
7
8 #define PKC_CONTEXT /* Indicate that we're working with PKC contexts */
9 #include "crypt.h"
10 #ifdef INC_ALL
11 #include "context.h"
12 #include "asn1.h"
13 #else
14 #include "context/context.h"
15 #include "enc_dec/asn1.h"
16 #endif /* Compiler-specific includes */
17
18 /****************************************************************************
19 * *
20 * Utility Functions *
21 * *
22 ****************************************************************************/
23
24 /* Exit after setting extended error information */
25
26 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
exitError(INOUT CONTEXT_INFO * contextInfoPtr,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus,IN_ENUM (CRYPT_ERRTYPE)const CRYPT_ERRTYPE_TYPE errorType,IN_ERROR const int status)27 static int exitError( INOUT CONTEXT_INFO *contextInfoPtr,
28 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus,
29 IN_ENUM( CRYPT_ERRTYPE ) const CRYPT_ERRTYPE_TYPE errorType,
30 IN_ERROR const int status )
31 {
32 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
33
34 REQUIRES( isAttribute( errorLocus ) || \
35 isInternalAttribute( errorLocus ) );
36 REQUIRES( errorType > CRYPT_ERRTYPE_NONE && \
37 errorType < CRYPT_ERRTYPE_LAST );
38 REQUIRES( cryptStatusError( status ) );
39
40 setErrorInfo( contextInfoPtr, errorLocus, errorType );
41 return( status );
42 }
43
44 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
exitErrorInited(INOUT CONTEXT_INFO * contextInfoPtr,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus)45 static int exitErrorInited( INOUT CONTEXT_INFO *contextInfoPtr,
46 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
47 {
48 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
49
50 REQUIRES( isAttribute( errorLocus ) || \
51 isInternalAttribute( errorLocus ) );
52
53 return( exitError( contextInfoPtr, errorLocus,
54 CRYPT_ERRTYPE_ATTR_PRESENT, CRYPT_ERROR_INITED ) );
55 }
56
57 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
exitErrorNotInited(INOUT CONTEXT_INFO * contextInfoPtr,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus)58 static int exitErrorNotInited( INOUT CONTEXT_INFO *contextInfoPtr,
59 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
60 {
61 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
62
63 REQUIRES( isAttribute( errorLocus ) || \
64 isInternalAttribute( errorLocus ) );
65
66 return( exitError( contextInfoPtr, errorLocus,
67 CRYPT_ERRTYPE_ATTR_ABSENT, CRYPT_ERROR_NOTINITED ) );
68 }
69
70 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
exitErrorNotFound(INOUT CONTEXT_INFO * contextInfoPtr,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus)71 static int exitErrorNotFound( INOUT CONTEXT_INFO *contextInfoPtr,
72 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
73 {
74 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
75
76 REQUIRES( isAttribute( errorLocus ) || \
77 isInternalAttribute( errorLocus ) );
78
79 return( exitError( contextInfoPtr, errorLocus,
80 CRYPT_ERRTYPE_ATTR_ABSENT, CRYPT_ERROR_NOTFOUND ) );
81 }
82
83 /****************************************************************************
84 * *
85 * Get Attributes *
86 * *
87 ****************************************************************************/
88
89 /* Get a numeric/boolean attribute */
90
91 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
getContextAttribute(INOUT CONTEXT_INFO * contextInfoPtr,OUT_INT_Z int * valuePtr,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute)92 int getContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
93 OUT_INT_Z int *valuePtr,
94 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
95 {
96 const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
97 const CONTEXT_TYPE contextType = contextInfoPtr->type;
98 int value;
99
100 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
101 assert( isWritePtr( valuePtr, sizeof( int ) ) );
102
103 REQUIRES( isAttribute( attribute ) || \
104 isInternalAttribute( attribute ) );
105
106 /* Clear return value */
107 *valuePtr = 0;
108
109 switch( attribute )
110 {
111 case CRYPT_ATTRIBUTE_ERRORTYPE:
112 *valuePtr = contextInfoPtr->errorType;
113 return( CRYPT_OK );
114
115 case CRYPT_ATTRIBUTE_ERRORLOCUS:
116 *valuePtr = contextInfoPtr->errorLocus;
117 return( CRYPT_OK );
118
119 case CRYPT_OPTION_MISC_SIDECHANNELPROTECTION:
120 *valuePtr = ( contextInfoPtr->flags & \
121 CONTEXT_FLAG_SIDECHANNELPROTECTION ) ? 1 : 0;
122 /* This is actually a protection level rather than a
123 boolean value, although internally it's stored as
124 a boolean flag */
125 return( CRYPT_OK );
126
127 case CRYPT_CTXINFO_ALGO:
128 *valuePtr = capabilityInfoPtr->cryptAlgo;
129 return( CRYPT_OK );
130
131 case CRYPT_CTXINFO_MODE:
132 REQUIRES( contextType == CONTEXT_CONV );
133
134 *valuePtr = contextInfoPtr->ctxConv->mode;
135 return( CRYPT_OK );
136
137 case CRYPT_CTXINFO_KEYSIZE:
138 switch( contextType )
139 {
140 case CONTEXT_CONV:
141 value = contextInfoPtr->ctxConv->userKeyLength;
142 break;
143
144 case CONTEXT_PKC:
145 value = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
146 break;
147
148 case CONTEXT_MAC:
149 value = contextInfoPtr->ctxMAC->userKeyLength;
150 break;
151
152 case CONTEXT_GENERIC:
153 value = contextInfoPtr->ctxGeneric->genericSecretLength;
154 break;
155
156 default:
157 retIntError();
158 }
159 if( value <= 0 )
160 {
161 /* If a key hasn't been loaded yet then we return the
162 default key size */
163 value = capabilityInfoPtr->keySize;
164 }
165 *valuePtr = value;
166 return( CRYPT_OK );
167
168 case CRYPT_CTXINFO_BLOCKSIZE:
169 if( contextType == CONTEXT_CONV && \
170 contextInfoPtr->ctxConv->mode == CRYPT_MODE_CFB )
171 *valuePtr = 1; /* Block cipher in stream mode */
172 else
173 *valuePtr = capabilityInfoPtr->blockSize;
174 return( CRYPT_OK );
175
176 case CRYPT_CTXINFO_IVSIZE:
177 REQUIRES( contextType == CONTEXT_CONV );
178
179 if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
180 isStreamCipher( capabilityInfoPtr->cryptAlgo ) )
181 return( CRYPT_ERROR_NOTAVAIL );
182 *valuePtr = capabilityInfoPtr->blockSize;
183 return( CRYPT_OK );
184
185 case CRYPT_CTXINFO_KEYING_ALGO:
186 case CRYPT_OPTION_KEYING_ALGO:
187 switch( contextType )
188 {
189 case CONTEXT_CONV:
190 value = contextInfoPtr->ctxConv->keySetupAlgorithm;
191 break;
192
193 case CONTEXT_MAC:
194 value = contextInfoPtr->ctxMAC->keySetupAlgorithm;
195 break;
196
197 default:
198 retIntError();
199 }
200 if( value <= 0 )
201 return( exitErrorNotInited( contextInfoPtr,
202 CRYPT_CTXINFO_KEYING_ALGO ) );
203 *valuePtr = value;
204 return( CRYPT_OK );
205
206 case CRYPT_CTXINFO_KEYING_ITERATIONS:
207 case CRYPT_OPTION_KEYING_ITERATIONS:
208 switch( contextType )
209 {
210 case CONTEXT_CONV:
211 value = contextInfoPtr->ctxConv->keySetupIterations;
212 break;
213
214 case CONTEXT_MAC:
215 value = contextInfoPtr->ctxMAC->keySetupIterations;
216 break;
217
218 default:
219 retIntError();
220 }
221 if( value <= 0 )
222 return( exitErrorNotInited( contextInfoPtr,
223 CRYPT_CTXINFO_KEYING_ITERATIONS ) );
224 *valuePtr = value;
225 return( CRYPT_OK );
226
227 case CRYPT_CTXINFO_PERSISTENT:
228 *valuePtr = ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ? \
229 TRUE : FALSE;
230 return( CRYPT_OK );
231
232 case CRYPT_IATTRIBUTE_KEYFEATURES:
233 REQUIRES( contextType == CONTEXT_PKC );
234
235 *valuePtr = ( contextInfoPtr->flags & CONTEXT_FLAG_PBO ) ? 1 : 0;
236 #ifdef USE_DEVICES
237 *valuePtr |= isHandleRangeValid( contextInfoPtr->deviceObject ) ? 2 : 0;
238 #endif /* USE_DEVICES */
239 return( CRYPT_OK );
240
241 case CRYPT_IATTRIBUTE_DEVICEOBJECT:
242 #ifdef USE_DEVICES
243 if( isHandleRangeValid( contextInfoPtr->deviceObject ) )
244 {
245 *valuePtr = contextInfoPtr->deviceObject;
246 return( CRYPT_OK );
247 }
248 #endif /* USE_DEVICES */
249 return( CRYPT_ERROR_NOTFOUND );
250 }
251
252 retIntError();
253 }
254
255 /* Get a string attribute */
256
257 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
getContextAttributeS(INOUT CONTEXT_INFO * contextInfoPtr,INOUT MESSAGE_DATA * msgData,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute)258 int getContextAttributeS( INOUT CONTEXT_INFO *contextInfoPtr,
259 INOUT MESSAGE_DATA *msgData,
260 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
261 {
262 const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
263 const CONTEXT_TYPE contextType = contextInfoPtr->type;
264 int status;
265
266 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
267 assert( isWritePtr( msgData, sizeof( MESSAGE_DATA ) ) );
268
269 REQUIRES( isAttribute( attribute ) || \
270 isInternalAttribute( attribute ) );
271
272 switch( attribute )
273 {
274 case CRYPT_CTXINFO_NAME_ALGO:
275 return( attributeCopy( msgData, capabilityInfoPtr->algoName,
276 capabilityInfoPtr->algoNameLen ) );
277
278 case CRYPT_CTXINFO_NAME_MODE:
279 REQUIRES( contextType == CONTEXT_CONV );
280
281 switch( contextInfoPtr->ctxConv->mode )
282 {
283 case CRYPT_MODE_ECB:
284 return( attributeCopy( msgData, "ECB", 3 ) );
285 case CRYPT_MODE_CBC:
286 return( attributeCopy( msgData, "CBC", 3 ) );
287 case CRYPT_MODE_CFB:
288 return( attributeCopy( msgData, "CFB", 3 ) );
289 case CRYPT_MODE_GCM:
290 return( attributeCopy( msgData, "GCM", 3 ) );
291 }
292 retIntError();
293
294 case CRYPT_CTXINFO_KEYING_SALT:
295 REQUIRES( contextType == CONTEXT_CONV || \
296 contextType == CONTEXT_MAC );
297
298 if( contextType == CONTEXT_CONV )
299 {
300 if( contextInfoPtr->ctxConv->saltLength <= 0 )
301 return( exitErrorInited( contextInfoPtr,
302 CRYPT_CTXINFO_KEYING_SALT ) );
303 return( attributeCopy( msgData, contextInfoPtr->ctxConv->salt,
304 contextInfoPtr->ctxConv->saltLength ) );
305 }
306 if( contextInfoPtr->ctxMAC->saltLength <= 0 )
307 return( exitErrorInited( contextInfoPtr,
308 CRYPT_CTXINFO_KEYING_SALT ) );
309 return( attributeCopy( msgData, contextInfoPtr->ctxMAC->salt,
310 contextInfoPtr->ctxMAC->saltLength ) );
311
312 case CRYPT_CTXINFO_IV:
313 REQUIRES( contextType == CONTEXT_CONV );
314
315 if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
316 isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
317 return( CRYPT_ERROR_NOTAVAIL );
318 if( !( contextInfoPtr->flags & CONTEXT_FLAG_IV_SET ) )
319 return( exitErrorNotInited( contextInfoPtr, CRYPT_CTXINFO_IV ) );
320 return( attributeCopy( msgData, contextInfoPtr->ctxConv->iv,
321 contextInfoPtr->ctxConv->ivLength ) );
322
323 case CRYPT_CTXINFO_HASHVALUE:
324 REQUIRES( contextType == CONTEXT_HASH || \
325 contextType == CONTEXT_MAC );
326
327 if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_INITED ) )
328 return( CRYPT_ERROR_NOTINITED );
329 if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_DONE ) )
330 return( CRYPT_ERROR_INCOMPLETE );
331 return( attributeCopy( msgData, ( contextType == CONTEXT_HASH ) ? \
332 contextInfoPtr->ctxHash->hash : \
333 contextInfoPtr->ctxMAC->mac,
334 capabilityInfoPtr->blockSize ) );
335
336 case CRYPT_CTXINFO_LABEL:
337 if( contextInfoPtr->labelSize <= 0 )
338 return( exitErrorNotInited( contextInfoPtr,
339 CRYPT_CTXINFO_LABEL ) );
340 return( attributeCopy( msgData, contextInfoPtr->label,
341 contextInfoPtr->labelSize ) );
342
343 case CRYPT_IATTRIBUTE_KEYID:
344 REQUIRES( contextType == CONTEXT_PKC );
345 REQUIRES( memcmp( contextInfoPtr->ctxPKC->keyID,
346 "\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) );
347
348 return( attributeCopy( msgData, contextInfoPtr->ctxPKC->keyID,
349 KEYID_SIZE ) );
350
351 case CRYPT_IATTRIBUTE_KEYID_PGP2:
352 REQUIRES( contextType == CONTEXT_PKC );
353
354 if( !( contextInfoPtr->flags & CONTEXT_FLAG_PGPKEYID_SET ) )
355 return( CRYPT_ERROR_NOTFOUND );
356 return( attributeCopy( msgData, contextInfoPtr->ctxPKC->pgp2KeyID,
357 PGP_KEYID_SIZE ) );
358
359 case CRYPT_IATTRIBUTE_KEYID_OPENPGP:
360 REQUIRES( contextType == CONTEXT_PKC );
361
362 if( !( contextInfoPtr->flags & CONTEXT_FLAG_OPENPGPKEYID_SET ) )
363 return( CRYPT_ERROR_NOTFOUND );
364 return( attributeCopy( msgData, contextInfoPtr->ctxPKC->openPgpKeyID,
365 PGP_KEYID_SIZE ) );
366
367 case CRYPT_IATTRIBUTE_KEY_SPKI:
368 case CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL:
369 /* CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL is used to read from dummy
370 contexts used as placeholders for external crypto hardware
371 functionality, these aren't necessarily in the high state as
372 required by a CRYPT_IATTRIBUTE_KEY_SPKI read when they're
373 accessed because the hardware may not be ready yet but we
374 can still fetch the stored public-key data from them */
375 REQUIRES( contextType == CONTEXT_PKC && \
376 !needsKey( contextInfoPtr ) );
377
378 if( contextInfoPtr->ctxPKC->publicKeyInfo != NULL )
379 {
380 /* If the data is available in pre-encoded form, copy it
381 out */
382 return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicKeyInfo,
383 contextInfoPtr->ctxPKC->publicKeyInfoSize ) );
384 }
385 ENSURES( attribute == CRYPT_IATTRIBUTE_KEY_SPKI );
386 /* Drop through */
387
388 case CRYPT_IATTRIBUTE_KEY_PGP:
389 case CRYPT_IATTRIBUTE_KEY_SSH:
390 case CRYPT_IATTRIBUTE_KEY_SSL:
391 {
392 const PKC_WRITEKEY_FUNCTION writePublicKeyFunction = \
393 FNPTR_GET( contextInfoPtr->ctxPKC->writePublicKeyFunction );
394 STREAM stream;
395 KEYFORMAT_TYPE formatType;
396
397 REQUIRES( contextType == CONTEXT_PKC && \
398 !needsKey( contextInfoPtr ) );
399 REQUIRES( writePublicKeyFunction != NULL );
400
401 /* Writing a key in PGP format requires that it have a creation
402 time associated with it, however keys from non-PGP sources
403 don't have this. In order to be able to write the key we
404 have to set one in order to have something to write out.
405 This means that a side-effect of writing the key is to give
406 it a creation time. This is somewhat unfortunate, however
407 the standard never actually explains what this field is for
408 so it probably doesn't matter what we set it to.
409
410 A bigger problem though is that the creation time is hashed
411 into the key ID when the ID is generated, which means that
412 moving a key via a non-PGP format changes its key ID.
413 Because of this we leave the ID for any key that we write at
414 its default value, zero for one from a non-PGP source, or the
415 PGP time for one from a PGP source (and hope it doesn't go
416 via a non-PGP form at some point) */
417 #if defined( USE_PGP ) && 0
418 if( contextInfoPtr->ctxPKC->pgpCreationTime <= MIN_TIME_VALUE )
419 {
420 /* We're not too fussed about the value given for the
421 creation time (see the comment above), as long as it's
422 approximately valid */
423 contextInfoPtr->ctxPKC->pgpCreationTime = getApproxTime();
424 }
425 #endif /* USE_PGP */
426
427 /* Write the appropriately-formatted key data from the context */
428 status = attributeToFormatType( attribute, &formatType );
429 if( cryptStatusError( status ) )
430 return( status );
431 sMemOpenOpt( &stream, msgData->data, msgData->length );
432 status = writePublicKeyFunction( &stream, contextInfoPtr,
433 formatType, "public_key", 10 );
434 if( cryptStatusOK( status ) )
435 msgData->length = stell( &stream );
436 sMemDisconnect( &stream );
437 return( status );
438 }
439
440 case CRYPT_IATTRIBUTE_PGPVALIDITY:
441 REQUIRES( contextType == CONTEXT_PKC );
442
443 *( ( time_t * ) msgData->data ) = \
444 contextInfoPtr->ctxPKC->pgpCreationTime;
445 return( CRYPT_OK );
446
447 case CRYPT_IATTRIBUTE_DEVICESTORAGEID:
448 #ifdef USE_HARDWARE
449 if( contextInfoPtr->deviceStorageIDset )
450 return( attributeCopy( msgData, contextInfoPtr->deviceStorageID,
451 KEYID_SIZE ) );
452 #endif /* USE_HARDWARE */
453 return( CRYPT_ERROR_NOTFOUND );
454
455 case CRYPT_IATTRIBUTE_KDFPARAMS:
456 REQUIRES( contextType == CONTEXT_GENERIC );
457
458 if( contextInfoPtr->ctxGeneric->kdfParamSize <= 0 )
459 return( CRYPT_ERROR_NOTFOUND );
460 return( attributeCopy( msgData,
461 contextInfoPtr->ctxGeneric->kdfParams,
462 contextInfoPtr->ctxGeneric->kdfParamSize ) );
463
464 case CRYPT_IATTRIBUTE_ENCPARAMS:
465 REQUIRES( contextType == CONTEXT_GENERIC );
466
467 if( contextInfoPtr->ctxGeneric->encAlgoParamSize <= 0 )
468 return( CRYPT_ERROR_NOTFOUND );
469 return( attributeCopy( msgData,
470 contextInfoPtr->ctxGeneric->encAlgoParams,
471 contextInfoPtr->ctxGeneric->encAlgoParamSize ) );
472
473 case CRYPT_IATTRIBUTE_MACPARAMS:
474 REQUIRES( contextType == CONTEXT_GENERIC );
475
476 if( contextInfoPtr->ctxGeneric->macAlgoParamSize <= 0 )
477 return( CRYPT_ERROR_NOTFOUND );
478 return( attributeCopy( msgData,
479 contextInfoPtr->ctxGeneric->macAlgoParams,
480 contextInfoPtr->ctxGeneric->macAlgoParamSize ) );
481
482 case CRYPT_IATTRIBUTE_ICV:
483 REQUIRES( contextType == CONTEXT_CONV );
484
485 if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_GCM )
486 return( CRYPT_ERROR_NOTAVAIL );
487 return( capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_ICV,
488 contextInfoPtr, msgData->data,
489 msgData->length ) );
490 }
491
492 retIntError();
493 }
494
495 /****************************************************************************
496 * *
497 * Set Attributes *
498 * *
499 ****************************************************************************/
500
501 /* Set a numeric/boolean attribute */
502
503 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
setContextAttribute(INOUT CONTEXT_INFO * contextInfoPtr,IN_INT_Z const int value,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute)504 int setContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
505 IN_INT_Z const int value,
506 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
507 {
508 const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
509 const CONTEXT_TYPE contextType = contextInfoPtr->type;
510 int *valuePtr, status;
511
512 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
513
514 REQUIRES( ( value >= 0 && value < MAX_INTLENGTH ) || \
515 attribute == CRYPT_IATTRIBUTE_DEVICEOBJECT );
516 /* Some PKCS #11 device handles are most likely disguised
517 pointers so we have to allow for outrageous values for
518 these */
519 REQUIRES( isAttribute( attribute ) || \
520 isInternalAttribute( attribute ) );
521
522 switch( attribute )
523 {
524 case CRYPT_OPTION_MISC_SIDECHANNELPROTECTION:
525 if( value > 0 )
526 contextInfoPtr->flags |= CONTEXT_FLAG_SIDECHANNELPROTECTION;
527 else
528 contextInfoPtr->flags &= ~CONTEXT_FLAG_SIDECHANNELPROTECTION;
529 return( CRYPT_OK );
530
531 case CRYPT_CTXINFO_MODE:
532 REQUIRES( contextType == CONTEXT_CONV );
533
534 /* If the mode for the context isn't set to the initial default
535 value, it's already been explicitly set and we can't change
536 it again. This isn't quite as straightforward as it seems
537 because the definition of "initial default mode" is a bit
538 vague, for stream ciphers it's CTR, for block ciphers it's
539 usually CBC unless we're working with specific hardware
540 crypto that only supports one mode and that mode isn't CBC.
541 For now this only seems to be ECB so we add a special-case
542 check for ECB-only operation */
543 if( isStreamCipher( capabilityInfoPtr->cryptAlgo ) )
544 {
545 /* It's a stream cipher, the only possible mode is an
546 implicit CTR so any attempt to change it isn't valid */
547 return( exitErrorInited( contextInfoPtr,
548 CRYPT_CTXINFO_MODE ) );
549 }
550 else
551 {
552 #if 1 /* So far no devices without CBC support have been
553 encountered, so we always assume a default of CBC */
554 if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_CBC )
555 return( exitErrorInited( contextInfoPtr,
556 CRYPT_CTXINFO_MODE ) );
557 #else
558 if( capabilityInfoPtr->encryptCBCFunction != NULL )
559 {
560 if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_CBC )
561 return( exitErrorInited( contextInfoPtr,
562 CRYPT_CTXINFO_MODE ) );
563 }
564 else
565 {
566 /* This algorithm isn't available in CBC mode, the
567 default will be ECB */
568 if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_ECB )
569 return( exitErrorInited( contextInfoPtr,
570 CRYPT_CTXINFO_MODE ) );
571 }
572 #endif
573 }
574
575 /* Set the en/decryption mode */
576 return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
577 KEYPARAM_MODE, NULL, value ) );
578
579 case CRYPT_CTXINFO_KEYSIZE:
580 /* Make sure that the requested size is within range */
581 if( value < capabilityInfoPtr->minKeySize || \
582 value > capabilityInfoPtr->maxKeySize )
583 return( CRYPT_ARGERROR_NUM1 );
584
585 /* Get the location to store the key size and make sure that
586 it's not already set */
587 switch( contextType )
588 {
589 case CONTEXT_CONV:
590 valuePtr = &contextInfoPtr->ctxConv->userKeyLength;
591 break;
592
593 case CONTEXT_PKC:
594 valuePtr = &contextInfoPtr->ctxPKC->keySizeBits;
595 break;
596
597 case CONTEXT_MAC:
598 valuePtr = &contextInfoPtr->ctxMAC->userKeyLength;
599 break;
600
601 case CONTEXT_GENERIC:
602 valuePtr = &contextInfoPtr->ctxGeneric->genericSecretLength;
603 break;
604
605 default:
606 retIntError();
607 }
608 if( *valuePtr != 0 )
609 return( exitErrorInited( contextInfoPtr,
610 CRYPT_CTXINFO_KEYSIZE ) );
611
612 /* Trim the user-supplied value to the correct shape, taking
613 into account various issues such as limitations with the
614 underlying crypto code/hardware and interop problems with
615 algorithms that allow excessively long keys. In virtute sunt
616 multi ascensus.
617
618 If it's a PKC key then there's nothing further to do, since
619 the range check above is all that we need. ECC keys are a
620 bit complicated because if we're using fixed curve parameters
621 (which in practice we always do) there are only a small
622 number of quantised key sizes that we can use, but since some
623 of those correspond to very odd bit sizes like 521 bits that
624 can't be specified as an integral byte count what we do in
625 the ECC code is use the nearest fixed curve parameters equal
626 to or above the given value, avoiding the need for the caller
627 to play guessing games as to which byte-count value
628 corresponds to which curve.
629
630 For conventional/MAC keys we need to limit the maximum
631 working key length to a sane size since the other side may
632 not be able to handle stupidly large keys */
633 if( contextType == CONTEXT_PKC )
634 *valuePtr = bytesToBits( value );
635 else
636 *valuePtr = min( value, MAX_WORKING_KEYSIZE );
637 return( CRYPT_OK );
638
639 case CRYPT_CTXINFO_BLOCKSIZE:
640 REQUIRES( contextType == CONTEXT_HASH || \
641 contextType == CONTEXT_MAC );
642
643 /* Some hash (and corresponding MAC) algorithms have variable-
644 length outputs, in which case the blocksize is user-
645 definable */
646 if( capabilityInfoPtr->initParamsFunction == NULL )
647 return( CRYPT_ERROR_NOTAVAIL );
648 return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
649 KEYPARAM_BLOCKSIZE, NULL, value ) );
650
651 case CRYPT_CTXINFO_KEYING_ALGO:
652 case CRYPT_OPTION_KEYING_ALGO:
653 {
654 CRYPT_ALGO_TYPE *algoValuePtr;
655
656 REQUIRES( contextType == CONTEXT_CONV || \
657 contextType == CONTEXT_MAC );
658
659 /* The kernel only allows (potentially) valid values to be set,
660 but these may be disabled at the algorithm level so we have
661 to perform an additional check here */
662 if( !algoAvailable( value ) )
663 {
664 return( exitError( contextInfoPtr, attribute,
665 CRYPT_ERRTYPE_ATTR_VALUE,
666 CRYPT_ERROR_NOTAVAIL ) );
667 }
668
669 algoValuePtr = ( contextType == CONTEXT_CONV ) ? \
670 &contextInfoPtr->ctxConv->keySetupAlgorithm : \
671 &contextInfoPtr->ctxMAC->keySetupAlgorithm;
672 if( *algoValuePtr != CRYPT_ALGO_NONE )
673 return( exitErrorInited( contextInfoPtr, attribute ) );
674 *algoValuePtr = value;
675 return( CRYPT_OK );
676 }
677
678 case CRYPT_CTXINFO_KEYING_ITERATIONS:
679 case CRYPT_OPTION_KEYING_ITERATIONS:
680 REQUIRES( contextType == CONTEXT_CONV || \
681 contextType == CONTEXT_MAC );
682
683 valuePtr = ( contextType == CONTEXT_CONV ) ? \
684 &contextInfoPtr->ctxConv->keySetupIterations : \
685 &contextInfoPtr->ctxMAC->keySetupIterations;
686 if( *valuePtr )
687 return( exitErrorInited( contextInfoPtr,
688 CRYPT_CTXINFO_KEYING_ITERATIONS ) );
689 *valuePtr = value;
690 return( CRYPT_OK );
691
692 case CRYPT_CTXINFO_PERSISTENT:
693 /* The is-object-persistent attribute functions as follows:
694
695 | Software | Hardware
696 -----+----------+-------------------
697 PKC | R/O (1) | R/O (2)
698 -----+----------+-------------------
699 Conv | R/O (1) | R/W low state (3)
700 | | R/O high state
701
702 (1) = Set if stored to or read from a keyset.
703 (2) = Always set. Private-key objects are automatically
704 created as persistent objects, public-key objects
705 are (transparently) created as software objects since
706 the operation is much faster on the host system than
707 by going via the device.
708 (3) = Can be set in the low state, if set then the object
709 is created as a persistent object in the device.
710
711 Most of these checks are enforced by the kernel, the one
712 thing that the ACL language can't specify is the requirement
713 that a persistent conventional-encryption object be tied to
714 a device, which we do explicitly here */
715 if( ( value != 0 ) && \
716 !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
717 return( CRYPT_ERROR_PERMISSION );
718
719 /* Set or clear the persistent flag as required */
720 if( value != 0 )
721 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
722 else
723 contextInfoPtr->flags &= ~CONTEXT_FLAG_PERSISTENT;
724 return( CRYPT_OK );
725
726 case CRYPT_IATTRIBUTE_KEYSIZE:
727 /* If it's a private key context or a persistent context we need
728 to have a key label set before we can continue */
729 if( ( ( contextInfoPtr->type == CONTEXT_PKC ) || \
730 ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ) && \
731 contextInfoPtr->labelSize <= 0 )
732 retIntError();
733
734 /* If the key is held outside the context (e.g. in a device) we
735 may need to manually supply the key-related information
736 needed by the context if it can't be obtained through other
737 means such as when the SubjectPublicKeyInfo is set */
738 switch( contextType )
739 {
740 case CONTEXT_CONV:
741 contextInfoPtr->ctxConv->userKeyLength = value;
742 break;
743
744 case CONTEXT_PKC:
745 contextInfoPtr->ctxPKC->keySizeBits = bytesToBits( value );
746 break;
747
748 case CONTEXT_MAC:
749 contextInfoPtr->ctxMAC->userKeyLength = value;
750 break;
751
752 case CONTEXT_GENERIC:
753 contextInfoPtr->ctxGeneric->genericSecretLength = value;
754 break;
755
756 default:
757 retIntError();
758 }
759 return( CRYPT_OK );
760
761 case CRYPT_IATTRIBUTE_KEY_DLPPARAM:
762 status = loadDHparams( contextInfoPtr, value );
763 if( cryptStatusOK( status ) )
764 status = completeKeyLoad( contextInfoPtr, FALSE );
765 return( status );
766
767 #if defined( USE_ECDH ) || defined( USE_ECDSA )
768 case CRYPT_IATTRIBUTE_KEY_ECCPARAM:
769 status = loadECCparams( contextInfoPtr, value );
770 if( cryptStatusOK( status ) )
771 status = completeKeyLoad( contextInfoPtr, FALSE );
772 return( status );
773 #endif /* USE_ECDH || USE_ECDSA */
774
775 case CRYPT_IATTRIBUTE_DEVICEOBJECT:
776 #ifdef USE_DEVICES
777 /* Setting the device object means that the crypto functionality
778 for the context is enabled, which means that it's effectively
779 in the key-loaded state, however for standard key-loaded
780 operations to be possible certain other preconditions need to
781 be met, which we check for here */
782 REQUIRES( ( contextType == CONTEXT_CONV && \
783 contextInfoPtr->ctxConv->userKeyLength > 0 ) || \
784 ( contextType == CONTEXT_PKC && \
785 contextInfoPtr->ctxPKC->keySizeBits > 0 && \
786 contextInfoPtr->ctxPKC->publicKeyInfo != NULL ) || \
787 ( contextType == CONTEXT_MAC && \
788 contextInfoPtr->ctxMAC->userKeyLength > 0 ) || \
789 ( contextType == CONTEXT_GENERIC && \
790 contextInfoPtr->ctxGeneric->genericSecretLength > 0 ) || \
791 ( contextType == CONTEXT_HASH ) );
792
793 /* Remember the reference to the associated crypto functionality
794 in the device */
795 contextInfoPtr->deviceObject = value;
796 contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
797 #endif /* USE_DEVICES */
798 return( CRYPT_OK );
799 }
800
801 retIntError();
802 }
803
804 /* Set a string attribute */
805
806 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
setContextAttributeS(INOUT CONTEXT_INFO * contextInfoPtr,IN_BUFFER (dataLength)const void * data,IN_LENGTH const int dataLength,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute)807 int setContextAttributeS( INOUT CONTEXT_INFO *contextInfoPtr,
808 IN_BUFFER( dataLength ) const void *data,
809 IN_LENGTH const int dataLength,
810 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
811 {
812 const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
813 const CONTEXT_TYPE contextType = contextInfoPtr->type;
814 int status;
815
816 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
817 assert( isReadPtr( data, dataLength ) );
818
819 REQUIRES( dataLength > 0 && dataLength < MAX_INTLENGTH );
820 REQUIRES( isAttribute( attribute ) || \
821 isInternalAttribute( attribute ) );
822
823 switch( attribute )
824 {
825 case CRYPT_CTXINFO_KEYING_SALT:
826 REQUIRES( contextType == CONTEXT_CONV || \
827 contextType == CONTEXT_MAC );
828 REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_HASHSIZE );
829
830 if( contextType == CONTEXT_CONV )
831 {
832 if( contextInfoPtr->ctxConv->saltLength > 0 )
833 return( exitErrorInited( contextInfoPtr,
834 CRYPT_CTXINFO_KEYING_SALT ) );
835 memcpy( contextInfoPtr->ctxConv->salt, data, dataLength );
836 contextInfoPtr->ctxConv->saltLength = dataLength;
837 return( CRYPT_OK );
838 }
839 if( contextInfoPtr->ctxMAC->saltLength > 0 )
840 return( exitErrorInited( contextInfoPtr,
841 CRYPT_CTXINFO_KEYING_SALT ) );
842 memcpy( contextInfoPtr->ctxMAC->salt, data, dataLength );
843 contextInfoPtr->ctxMAC->saltLength = dataLength;
844 return( CRYPT_OK );
845
846 case CRYPT_CTXINFO_KEYING_VALUE:
847 return( deriveKey( contextInfoPtr, data, dataLength ) );
848
849 case CRYPT_CTXINFO_KEY:
850 {
851 const CTX_LOADKEY_FUNCTION loadKeyFunction = \
852 FNPTR_GET( contextInfoPtr->loadKeyFunction );
853
854 REQUIRES( contextType == CONTEXT_CONV || \
855 contextType == CONTEXT_MAC || \
856 contextType == CONTEXT_GENERIC );
857 REQUIRES( needsKey( contextInfoPtr ) );
858 REQUIRES( loadKeyFunction != NULL );
859
860 /* If it's a persistent context we need to have a key label set
861 before we can continue */
862 if( ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) && \
863 contextInfoPtr->labelSize <= 0 )
864 return( exitErrorNotInited( contextInfoPtr,
865 CRYPT_CTXINFO_LABEL ) );
866
867 /* The kernel performs a general check on the size of this
868 attribute but doesn't know about context subtype-specific
869 limits so we perform a context-specific check here */
870 if( dataLength < capabilityInfoPtr->minKeySize || \
871 dataLength > capabilityInfoPtr->maxKeySize )
872 return( CRYPT_ARGERROR_NUM1 );
873
874 /* Load the key into the context */
875 status = loadKeyFunction( contextInfoPtr, data, dataLength );
876 if( cryptStatusOK( status ) )
877 contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
878 return( status );
879 }
880
881 #ifndef USE_FIPS140
882 case CRYPT_CTXINFO_KEY_COMPONENTS:
883 return( setKeyComponents( contextInfoPtr, data, dataLength ) );
884 #endif /* !USE_FIPS140 */
885
886 case CRYPT_CTXINFO_IV:
887 REQUIRES( contextType == CONTEXT_CONV );
888
889 /* If it's a mode that doesn't use an IV then the load IV
890 operation is meaningless */
891 if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
892 isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
893 return( CRYPT_ERROR_NOTAVAIL );
894
895 /* Make sure that the data size is valid. GCM is handled
896 specially because the default IV size is somewhat smaller
897 than the cipher block size */
898 if( contextInfoPtr->ctxConv->mode == CRYPT_MODE_GCM )
899 {
900 if( dataLength < 8 || \
901 dataLength > capabilityInfoPtr->blockSize )
902 return( CRYPT_ARGERROR_NUM1 );
903 }
904 else
905 {
906 if( dataLength != capabilityInfoPtr->blockSize )
907 return( CRYPT_ARGERROR_NUM1 );
908 }
909
910 /* Load the IV */
911 return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
912 KEYPARAM_IV, data, dataLength ) );
913
914 case CRYPT_CTXINFO_LABEL:
915 {
916 CRYPT_HANDLE iCryptHandle;
917
918 if( contextInfoPtr->labelSize > 0 )
919 return( exitErrorInited( contextInfoPtr,
920 CRYPT_CTXINFO_LABEL ) );
921
922 /* Check any device object that the context is associated with
923 to ensure that nothing with that label already exists in the
924 device. For keysets the check for duplicates is performed
925 when the context is explicitly added to the keyset but with
926 devices the context will be implicitly created within the
927 device at some future point (at context creation, on key
928 load/generation, or at some other point) that depends on the
929 device. Because of this we perform a preemptive check for
930 duplicates to avoid a potentially confusing error condition
931 at some indeterminate point in the future.
932
933 Since objects are typed, we have to check for the three
934 possible { label, type } combinations. In theory we could
935 require that labels are only unique per object type but this
936 can lead to problems with underlying devices or keysets that
937 only support a check by label and not by { label, type }
938 combination. In addition we can't send the message to the
939 context because the kernel won't forward this message type
940 (sending a get-key message to a context doesn't make sense)
941 so we have to explicitly get the dependent device and then
942 send the get-key directly to it */
943 status = krnlSendMessage( contextInfoPtr->objectHandle,
944 IMESSAGE_GETDEPENDENT, &iCryptHandle,
945 OBJECT_TYPE_DEVICE );
946 if( cryptStatusOK( status ) && \
947 ( iCryptHandle != SYSTEM_OBJECT_HANDLE ) )
948 {
949 MESSAGE_KEYMGMT_INFO getkeyInfo;
950
951 setMessageKeymgmtInfo( &getkeyInfo, CRYPT_KEYID_NAME,
952 data, dataLength, NULL, 0,
953 KEYMGMT_FLAG_CHECK_ONLY );
954 status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
955 &getkeyInfo, KEYMGMT_ITEM_SECRETKEY );
956 if( cryptStatusError( status ) )
957 status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
958 &getkeyInfo,
959 KEYMGMT_ITEM_PUBLICKEY );
960 if( cryptStatusError( status ) )
961 status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
962 &getkeyInfo,
963 KEYMGMT_ITEM_PRIVATEKEY );
964 if( cryptStatusOK( status ) )
965 {
966 /* We've found something with this label already
967 present, we can't use it again */
968 return( CRYPT_ERROR_DUPLICATE );
969 }
970 assert( !cryptArgError( status ) );
971 }
972
973 /* Fall through */
974 }
975
976 case CRYPT_IATTRIBUTE_EXISTINGLABEL:
977 REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
978
979 /* The difference between CRYPT_CTXINFO_LABEL and
980 CRYPT_IATTRIBUTE_EXISTINGLABEL is that the latter is used to
981 set a label for a context that's being instantiated from a
982 persistent object in a device. We can't perform the
983 duplicate-label check in this case because we'll always get a
984 match for the device object's label */
985 if( contextInfoPtr->labelSize > 0 )
986 return( exitErrorInited( contextInfoPtr,
987 CRYPT_CTXINFO_LABEL ) );
988
989 /* Set the label */
990 memcpy( contextInfoPtr->label, data, dataLength );
991 contextInfoPtr->labelSize = dataLength;
992 return( CRYPT_OK );
993
994 case CRYPT_IATTRIBUTE_KEYID_OPENPGP:
995 REQUIRES( contextType == CONTEXT_PKC );
996 REQUIRES( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA || \
997 contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
998 contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL || \
999 contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );
1000 REQUIRES( dataLength == PGP_KEYID_SIZE );
1001
1002 memcpy( contextInfoPtr->ctxPKC->openPgpKeyID, data, dataLength );
1003 contextInfoPtr->flags |= CONTEXT_FLAG_OPENPGPKEYID_SET;
1004
1005 /* If it's a non-PGP 2.x key type, set the PGP 2.x keyID to the
1006 OpenPGP keyID. This is necessary because non-PGP 2.x keys can
1007 be used with PGP 2.x message formats which would imply the use
1008 of a PGP 2.x keyID except that it's not defined for this key
1009 type */
1010 if( contextInfoPtr->capabilityInfo->cryptAlgo != CRYPT_ALGO_RSA )
1011 {
1012 memcpy( contextInfoPtr->ctxPKC->pgp2KeyID,
1013 contextInfoPtr->ctxPKC->openPgpKeyID, PGP_KEYID_SIZE );
1014 contextInfoPtr->flags |= CONTEXT_FLAG_PGPKEYID_SET;
1015 }
1016 return( CRYPT_OK );
1017
1018 case CRYPT_IATTRIBUTE_KEY_SPKI:
1019 case CRYPT_IATTRIBUTE_KEY_PGP:
1020 case CRYPT_IATTRIBUTE_KEY_SSH:
1021 case CRYPT_IATTRIBUTE_KEY_SSL:
1022 case CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL:
1023 case CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL:
1024 REQUIRES( contextType == CONTEXT_PKC );
1025
1026 return( setEncodedKey( contextInfoPtr, attribute, data,
1027 dataLength ) );
1028
1029 case CRYPT_IATTRIBUTE_PGPVALIDITY:
1030 REQUIRES( contextType == CONTEXT_PKC );
1031
1032 contextInfoPtr->ctxPKC->pgpCreationTime = *( ( time_t * ) data );
1033 return( CRYPT_OK );
1034
1035 case CRYPT_IATTRIBUTE_DEVICESTORAGEID:
1036 #ifdef USE_HARDWARE
1037 REQUIRES( dataLength > 0 && dataLength <= KEYID_SIZE );
1038 memset( contextInfoPtr->deviceStorageID, 0, KEYID_SIZE );
1039 memcpy( contextInfoPtr->deviceStorageID, data, dataLength );
1040 contextInfoPtr->deviceStorageIDset = TRUE;
1041 #endif /* USE_HARDWARE */
1042 return( CRYPT_OK );
1043
1044 case CRYPT_IATTRIBUTE_KDFPARAMS:
1045 REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
1046
1047 memcpy( contextInfoPtr->ctxGeneric->kdfParams, data,
1048 dataLength );
1049 contextInfoPtr->ctxGeneric->kdfParamSize = dataLength;
1050
1051 return( CRYPT_OK );
1052
1053 case CRYPT_IATTRIBUTE_ENCPARAMS:
1054 REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
1055
1056 memcpy( contextInfoPtr->ctxGeneric->encAlgoParams, data,
1057 dataLength );
1058 contextInfoPtr->ctxGeneric->encAlgoParamSize = dataLength;
1059
1060 return( CRYPT_OK );
1061
1062 case CRYPT_IATTRIBUTE_MACPARAMS:
1063 REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
1064
1065 memcpy( contextInfoPtr->ctxGeneric->macAlgoParams, data,
1066 dataLength );
1067 contextInfoPtr->ctxGeneric->macAlgoParamSize = dataLength;
1068
1069 return( CRYPT_OK );
1070
1071 case CRYPT_IATTRIBUTE_AAD:
1072 REQUIRES( contextType == CONTEXT_CONV );
1073
1074 if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_GCM )
1075 return( CRYPT_ERROR_NOTAVAIL );
1076
1077 /* Process the AAD */
1078 return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
1079 KEYPARAM_AAD , data, dataLength ) );
1080 }
1081
1082 retIntError();
1083 }
1084
1085 /****************************************************************************
1086 * *
1087 * Delete Attributes *
1088 * *
1089 ****************************************************************************/
1090
1091 /* Delete an attribute */
1092
1093 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
deleteContextAttribute(INOUT CONTEXT_INFO * contextInfoPtr,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute)1094 int deleteContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
1095 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
1096 {
1097 const CONTEXT_TYPE contextType = contextInfoPtr->type;
1098
1099 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1100
1101 REQUIRES( isAttribute( attribute ) || \
1102 isInternalAttribute( attribute ) );
1103
1104 switch( attribute )
1105 {
1106 case CRYPT_CTXINFO_KEYING_ALGO:
1107 REQUIRES( contextType == CONTEXT_CONV || \
1108 contextType == CONTEXT_MAC );
1109
1110 if( contextType == CONTEXT_CONV )
1111 {
1112 if( contextInfoPtr->ctxConv->keySetupAlgorithm == CRYPT_ALGO_NONE )
1113 return( exitErrorNotFound( contextInfoPtr,
1114 CRYPT_CTXINFO_KEYING_ALGO ) );
1115 contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_NONE;
1116 return( CRYPT_OK );
1117 }
1118 if( contextInfoPtr->ctxMAC->keySetupAlgorithm == CRYPT_ALGO_NONE )
1119 return( exitErrorNotFound( contextInfoPtr,
1120 CRYPT_CTXINFO_KEYING_ALGO ) );
1121 contextInfoPtr->ctxMAC->keySetupAlgorithm = CRYPT_ALGO_NONE;
1122 return( CRYPT_OK );
1123
1124 case CRYPT_CTXINFO_KEYING_ITERATIONS:
1125 REQUIRES( contextType == CONTEXT_CONV || \
1126 contextType == CONTEXT_MAC );
1127
1128 if( contextType == CONTEXT_CONV )
1129 {
1130 if( contextInfoPtr->ctxConv->keySetupIterations == 0 )
1131 return( exitErrorNotFound( contextInfoPtr,
1132 CRYPT_CTXINFO_KEYING_ITERATIONS ) );
1133 contextInfoPtr->ctxConv->keySetupIterations = 0;
1134 return( CRYPT_OK );
1135 }
1136 if( contextInfoPtr->ctxMAC->keySetupIterations == 0 )
1137 return( exitErrorNotFound( contextInfoPtr,
1138 CRYPT_CTXINFO_KEYING_ITERATIONS ) );
1139 contextInfoPtr->ctxMAC->keySetupIterations = 0;
1140 return( CRYPT_OK );
1141
1142 case CRYPT_CTXINFO_KEYING_SALT:
1143 REQUIRES( contextType == CONTEXT_CONV || \
1144 contextType == CONTEXT_MAC );
1145
1146 if( contextType == CONTEXT_CONV )
1147 {
1148 if( contextInfoPtr->ctxConv->saltLength == 0 )
1149 return( exitErrorNotFound( contextInfoPtr,
1150 CRYPT_CTXINFO_KEYING_SALT ) );
1151 zeroise( contextInfoPtr->ctxConv->salt, CRYPT_MAX_HASHSIZE );
1152 contextInfoPtr->ctxConv->saltLength = 0;
1153 return( CRYPT_OK );
1154 }
1155 if( contextInfoPtr->ctxMAC->saltLength == 0 )
1156 return( exitErrorNotFound( contextInfoPtr,
1157 CRYPT_CTXINFO_KEYING_SALT ) );
1158 zeroise( contextInfoPtr->ctxMAC->salt, CRYPT_MAX_HASHSIZE );
1159 contextInfoPtr->ctxMAC->saltLength = 0;
1160 return( CRYPT_OK );
1161
1162 case CRYPT_CTXINFO_IV:
1163 REQUIRES( contextType == CONTEXT_CONV );
1164
1165 if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
1166 isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
1167 return( exitErrorNotFound( contextInfoPtr,
1168 CRYPT_CTXINFO_IV ) );
1169 contextInfoPtr->ctxConv->ivLength = \
1170 contextInfoPtr->ctxConv->ivCount = 0;
1171 contextInfoPtr->flags &= ~CONTEXT_FLAG_IV_SET;
1172 return( CRYPT_OK );
1173
1174 case CRYPT_CTXINFO_LABEL:
1175 if( contextInfoPtr->labelSize <= 0 )
1176 return( exitErrorNotFound( contextInfoPtr,
1177 CRYPT_CTXINFO_LABEL ) );
1178 zeroise( contextInfoPtr->label, contextInfoPtr->labelSize );
1179 contextInfoPtr->labelSize = 0;
1180 return( CRYPT_OK );
1181
1182 case CRYPT_CTXINFO_HASHVALUE:
1183 switch( contextType )
1184 {
1185 case CONTEXT_HASH:
1186 zeroise( contextInfoPtr->ctxHash->hash, CRYPT_MAX_HASHSIZE );
1187 break;
1188
1189 case CONTEXT_MAC:
1190 zeroise( contextInfoPtr->ctxMAC->mac, CRYPT_MAX_HASHSIZE );
1191 break;
1192
1193 default:
1194 retIntError();
1195 }
1196 contextInfoPtr->flags &= ~( CONTEXT_FLAG_HASH_INITED | \
1197 CONTEXT_FLAG_HASH_DONE );
1198 return( CRYPT_OK );
1199 }
1200
1201 retIntError();
1202 }
1203