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