The PKCS#11 spec explicitly forbids CKA_VALUE_LEN in AES Key templates for C_UnwrapKey(), but without it we can't correctly unwrap AES Keys (which have variable size) using unwrapping mechanisms that don't get the decrypted size right (such as X.509 RSA).
Fix AES Unwrapping by creating/updating a CKA_VALUE_LEN attribute that is calculated from the size of the key data buffer. If it does not match with a "known" size, try checking for an existing CKA_VALUE_LEN attribute in the template. Signed-off-by: Klaus Heinrich Kiwi <[email protected]> --- usr/lib/pkcs11/common/key.c | 75 ++++++++++++++++++++++++------------------ 1 files changed, 43 insertions(+), 32 deletions(-) diff --git a/usr/lib/pkcs11/common/key.c b/usr/lib/pkcs11/common/key.c index 6da170c..366a04a 100755 --- a/usr/lib/pkcs11/common/key.c +++ b/usr/lib/pkcs11/common/key.c @@ -5207,50 +5207,45 @@ aes_unwrap( TEMPLATE *tmpl, CK_ULONG key_size; CK_BBOOL found = FALSE; - - /* - * CKA_VALUE_LEN attribute is optional in the key template. Default - * is to use AES_BLOCK_SIZE and truncate if no value is specified. --KlausK - */ + found = template_attribute_find( tmpl, CKA_VALUE_LEN, &val_len_attr ); - if (found){ - key_size = *(CK_ULONG *)val_len_attr->pValue; + + + /* For AES, we should inspect data_len and set * + * CKA_VALUE_LEN accordingly * + * data_len should be one of AES's possible key * + * sizes */ + if (data_len == AES_KEY_SIZE_128 || + data_len == AES_KEY_SIZE_192 || + data_len == AES_KEY_SIZE_256){ + key_size = data_len; } else { - key_size = AES_BLOCK_SIZE; /* same as AES_KEY_SIZE_128 */ - } - - /* key_size should be one of AES's possible sizes */ - if (key_size != AES_KEY_SIZE_128 && - key_size != AES_KEY_SIZE_192 && - key_size != AES_KEY_SIZE_256){ - st_err_log(62, __FILE__, __LINE__); - return CKR_ATTRIBUTE_VALUE_INVALID; + /* TODO: log me */ + /* Ops! We may be dealing with an Unwrapping * + * mechamism that doesn't do padding and/or * + * doesn't get the decrypted size right. * + * Let's try looking for CKA_VALUE_LEN (which btw * + * the specs forbids for C_UnwrapKey()) as a way * + * to recover from that (this is where we get out * + * of spec, thus, FIXME:) */ + if (found){ + key_size = *(CK_ULONG *)val_len_attr->pValue; + } + else { + st_err_log(62, __FILE__, __LINE__); + return CKR_ATTRIBUTE_VALUE_INVALID; + } } if (fromend == TRUE) ptr = data + data_len - key_size; else ptr = data; - -#if 0 - CK_ULONG i; - if (nv_token_data->tweak_vector.check_des_parity == TRUE) { - for (i=0; i < 3*DES_KEY_SIZE; i++) { - if (parity_is_odd(ptr[i]) == FALSE){ - st_err_log(9, __FILE__, __LINE__); - return CKR_ATTRIBUTE_VALUE_INVALID; - } - } - } -#endif - + value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + key_size ); if (!value_attr) { - if (value_attr) - free( value_attr ); st_err_log(0, __FILE__, __LINE__); - return CKR_HOST_MEMORY; } @@ -5261,6 +5256,22 @@ aes_unwrap( TEMPLATE *tmpl, template_update_attribute( tmpl, value_attr ); + if (!found) { + val_len_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG)); + if (!val_len_attr) { + st_err_log(0, __FILE__, __LINE__); + return CKR_HOST_MEMORY; + } + } + /* If the templace has CKA_VALUE_LEN, let's just * + * hope it also has pValue allocated */ + val_len_attr->type = CKA_VALUE_LEN; + val_len_attr->ulValueLen = sizeof(CK_ULONG); + val_len_attr->pValue = (CK_BYTE *) val_len_attr + sizeof(CK_ATTRIBUTE); + *((CK_ULONG *)val_len_attr->pValue) = key_size; + + template_update_attribute(tmpl, val_len_attr); + return CKR_OK; } -- 1.7.2.3 ------------------------------------------------------------------------------ Increase Visibility of Your 3D Game App & Earn a Chance To Win $500! Tap into the largest installed PC base & get more eyes on your game by optimizing for Intel(R) Graphics Technology. Get started today with the Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs. http://p.sf.net/sfu/intelisp-dev2dev _______________________________________________ Opencryptoki-tech mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opencryptoki-tech
