@@ -1186,6 +1186,119 @@ void SymmetricAlgorithmTests::aesWrapUnwrapGeneric(CK_MECHANISM_TYPE mechanismTy
11861186 CPPUNIT_ASSERT (rv == CKR_OK);
11871187}
11881188
1189+ void SymmetricAlgorithmTests::aesWrapUnwrapNonModifiableGeneric (CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
1190+ {
1191+ CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
1192+ CK_BBOOL bFalse = CK_FALSE;
1193+ CK_BBOOL bTrue = CK_TRUE;
1194+ CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
1195+ CK_KEY_TYPE genKeyType = CKK_GENERIC_SECRET;
1196+ CK_BYTE keyPtr[128 ];
1197+ CK_ULONG keyLen =
1198+ mechanismType == CKM_AES_KEY_WRAP_PAD ? 125UL : 128UL ;
1199+
1200+ CK_RV rv;
1201+ CK_BYTE ivPtr[16 ];
1202+ if ( mechanismType == CKM_AES_CBC_PAD ) {
1203+ rv = CRYPTOKI_F_PTR ( C_GenerateRandom (hSession, ivPtr, sizeof ivPtr) );
1204+ CPPUNIT_ASSERT (rv == CKR_OK);
1205+ mechanism.pParameter = ivPtr;
1206+ mechanism.ulParameterLen = sizeof ivPtr;
1207+ }
1208+
1209+ CK_ATTRIBUTE attribs[] = {
1210+ { CKA_EXTRACTABLE, &bFalse, sizeof (bFalse) },
1211+ { CKA_CLASS, &secretClass, sizeof (secretClass) },
1212+ { CKA_KEY_TYPE, &genKeyType, sizeof (genKeyType) },
1213+ { CKA_TOKEN, &bFalse, sizeof (bFalse) },
1214+ { CKA_PRIVATE, &bTrue, sizeof (bTrue) },
1215+ { CKA_SENSITIVE, &bTrue, sizeof (bTrue) }, // Wrapping is allowed even on sensitive objects
1216+ { CKA_VALUE, keyPtr, keyLen }
1217+ };
1218+ CK_OBJECT_HANDLE hSecret;
1219+
1220+ rv = CRYPTOKI_F_PTR ( C_GenerateRandom (hSession, keyPtr, keyLen) );
1221+ CPPUNIT_ASSERT (rv == CKR_OK);
1222+
1223+ hSecret = CK_INVALID_HANDLE;
1224+ rv = CRYPTOKI_F_PTR ( C_CreateObject (hSession, attribs, sizeof (attribs)/sizeof (CK_ATTRIBUTE), &hSecret) );
1225+ CPPUNIT_ASSERT (rv == CKR_OK);
1226+ CPPUNIT_ASSERT (hSecret != CK_INVALID_HANDLE);
1227+
1228+ CK_BYTE_PTR wrappedPtr = NULL_PTR;
1229+ CK_ULONG wrappedLen = 0UL ;
1230+ CK_ULONG zero = 0UL ;
1231+ CK_ULONG rndKeyLen = keyLen;
1232+ if (mechanismType == CKM_AES_KEY_WRAP_PAD)
1233+ rndKeyLen = (keyLen + 7 ) & ~7 ;
1234+ rv = CRYPTOKI_F_PTR ( C_WrapKey (hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
1235+ CPPUNIT_ASSERT (rv == CKR_KEY_UNEXTRACTABLE);
1236+ rv = CRYPTOKI_F_PTR ( C_DestroyObject (hSession, hSecret) );
1237+ CPPUNIT_ASSERT (rv == CKR_OK);
1238+
1239+ attribs[0 ].pValue = &bTrue;
1240+
1241+ hSecret = CK_INVALID_HANDLE;
1242+ rv = CRYPTOKI_F_PTR ( C_CreateObject (hSession, attribs, sizeof (attribs)/sizeof (CK_ATTRIBUTE), &hSecret) );
1243+ CPPUNIT_ASSERT (rv == CKR_OK);
1244+ CPPUNIT_ASSERT (hSecret != CK_INVALID_HANDLE);
1245+
1246+ // Estimate wrapped length
1247+ rv = CRYPTOKI_F_PTR ( C_WrapKey (hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
1248+ CPPUNIT_ASSERT (rv == CKR_OK);
1249+
1250+ auto wrapOverhead = [mechanismType]() {
1251+ return (mechanismType == CKM_AES_KEY_WRAP || mechanismType == CKM_AES_KEY_WRAP_PAD) ? 8 : 16 ;
1252+ };
1253+ CPPUNIT_ASSERT (wrappedLen == rndKeyLen + wrapOverhead () );
1254+
1255+ wrappedPtr = (CK_BYTE_PTR) malloc (wrappedLen);
1256+ CPPUNIT_ASSERT (wrappedPtr != NULL_PTR);
1257+ rv = CRYPTOKI_F_PTR ( C_WrapKey (hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
1258+ CPPUNIT_ASSERT (rv == CKR_OK);
1259+ CPPUNIT_ASSERT (wrappedLen == rndKeyLen + wrapOverhead () );
1260+
1261+ // This should always fail because wrapped data have to be longer than 0 bytes
1262+ zero = 0 ;
1263+ rv = CRYPTOKI_F_PTR ( C_WrapKey (hSession, &mechanism, hKey, hSecret, wrappedPtr, &zero) );
1264+ CPPUNIT_ASSERT (rv == CKR_BUFFER_TOO_SMALL);
1265+
1266+ CK_ATTRIBUTE nattribs[] = {
1267+ { CKA_CLASS, &secretClass, sizeof (secretClass) },
1268+ { CKA_KEY_TYPE, &genKeyType, sizeof (genKeyType) },
1269+ { CKA_TOKEN, &bFalse, sizeof (bFalse) },
1270+ { CKA_PRIVATE, &bTrue, sizeof (bTrue) },
1271+ { CKA_ENCRYPT, &bFalse, sizeof (bFalse) },
1272+ { CKA_DECRYPT, &bTrue, sizeof (bTrue) },
1273+ { CKA_MODIFIABLE, &bFalse, sizeof (bFalse) },
1274+ { CKA_SIGN, &bFalse,sizeof (bFalse) },
1275+ { CKA_VERIFY, &bTrue, sizeof (bTrue) }
1276+ };
1277+ CK_OBJECT_HANDLE hNew;
1278+
1279+ hNew = CK_INVALID_HANDLE;
1280+ rv = CRYPTOKI_F_PTR ( C_UnwrapKey (hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nattribs, sizeof (nattribs)/sizeof (CK_ATTRIBUTE), &hNew) );
1281+ CPPUNIT_ASSERT (rv == CKR_OK);
1282+ CPPUNIT_ASSERT (hNew != CK_INVALID_HANDLE);
1283+
1284+ CK_ATTRIBUTE modifiableAttribs[] = {
1285+ { CKA_MODIFIABLE, &bFalse, sizeof (bFalse) }
1286+ };
1287+
1288+ rv = CRYPTOKI_F_PTR ( C_GetAttributeValue (hSession, hNew, modifiableAttribs, sizeof (modifiableAttribs)/sizeof (CK_ATTRIBUTE)) );
1289+ CPPUNIT_ASSERT (rv == CKR_OK);
1290+
1291+ CPPUNIT_ASSERT (modifiableAttribs[0 ].ulValueLen == sizeof (bFalse));
1292+ CPPUNIT_ASSERT (*(CK_BBOOL*)modifiableAttribs[0 ].pValue == bFalse);
1293+
1294+ free (wrappedPtr);
1295+ wrappedPtr = NULL_PTR;
1296+ rv = CRYPTOKI_F_PTR ( C_DestroyObject (hSession, hSecret) );
1297+ CPPUNIT_ASSERT (rv == CKR_OK);
1298+ rv = CRYPTOKI_F_PTR ( C_DestroyObject (hSession, hNew) );
1299+ CPPUNIT_ASSERT (rv == CKR_OK);
1300+ }
1301+
11891302inline void SymmetricAlgorithmTests::aesWrapUnwrapRsa (CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
11901303{
11911304 wrapUnwrapRsa (mechanismType, hSession, hKey);
@@ -1643,6 +1756,8 @@ void SymmetricAlgorithmTests::testAesWrapUnwrap()
16431756
16441757 aesWrapUnwrapGeneric (CKM_AES_KEY_WRAP, hSession, hKey);
16451758 aesWrapUnwrapGeneric (CKM_AES_CBC_PAD, hSession, hKey);
1759+ aesWrapUnwrapNonModifiableGeneric (CKM_AES_KEY_WRAP, hSession, hKey);
1760+ aesWrapUnwrapNonModifiableGeneric (CKM_AES_CBC_PAD, hSession, hKey);
16461761 aesWrapUnwrapRsa (CKM_AES_KEY_WRAP, hSession, hKey);
16471762 aesWrapUnwrapRsa (CKM_AES_CBC_PAD, hSession, hKey);
16481763
0 commit comments