Skip to content

Commit

Permalink
Add tests for ECDH with KDFs
Browse files Browse the repository at this point in the history
Signed-off-by: Ondřej Hlavatý <[email protected]>
  • Loading branch information
Aearsis committed Jan 27, 2021
1 parent b8895b5 commit 296ec66
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 20 deletions.
121 changes: 102 additions & 19 deletions src/lib/test/DeriveTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ void DeriveTests::dhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicK
}

#if defined(WITH_ECC) || defined(WITH_EDDSA)
void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw)
void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw, ck_ec_kdf_t kdf, bool useSharedData, CK_ULONG secLen = 32)
{
CK_ATTRIBUTE valAttrib = { CKA_EC_POINT, NULL_PTR, 0 };
CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
Expand All @@ -313,7 +313,7 @@ void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPubli
rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
CPPUNIT_ASSERT(rv == CKR_OK);

CK_ECDH1_DERIVE_PARAMS parms = { CKD_NULL, 0, NULL_PTR, 0, NULL_PTR };
CK_ECDH1_DERIVE_PARAMS parms = { kdf, 0, NULL_PTR, 0, NULL_PTR };
// Use RAW or DER format
if (useRaw)
{
Expand Down Expand Up @@ -342,14 +342,19 @@ void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPubli
parms.ulPublicDataLen = valAttrib.ulValueLen;
}

if (useSharedData)
{
parms.pSharedData = (unsigned char *) "TEST";
parms.ulSharedDataLen = 4;
}

CK_MECHANISM mechanism = { CKM_ECDH1_DERIVE, NULL, 0 };
mechanism.pParameter = &parms;
mechanism.ulParameterLen = sizeof(parms);
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
CK_BBOOL bFalse = CK_FALSE;
CK_BBOOL bTrue = CK_TRUE;
CK_ULONG secLen = 32;
CK_ATTRIBUTE keyAttribs[] = {
{ CKA_CLASS, &keyClass, sizeof(keyClass) },
{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
Expand Down Expand Up @@ -512,37 +517,76 @@ void DeriveTests::testEcdsaDerive()
rv = generateEcKeyPair("P-256",hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

// Private Session Keys
rv = generateEcKeyPair("P-384",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
CPPUNIT_ASSERT(rv == CKR_OK);
rv = generateEcKeyPair("P-384",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

// Public Token Keys
rv = generateEcKeyPair("P-521",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
CPPUNIT_ASSERT(rv == CKR_OK);
rv = generateEcKeyPair("P-521",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

// Private Token Keys
rv = generateEcKeyPair("P-256",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
CPPUNIT_ASSERT(rv == CKR_OK);
rv = generateEcKeyPair("P-256",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE hKey4 = CK_INVALID_HANDLE;

CK_ATTRIBUTE keyAttribs[] = {
{ CKA_VALUE, NULL_PTR, 0 },
};
CK_BYTE val1[48];
CK_BYTE val2[48];

// KDF's
for (ck_ec_kdf_t kdf : { CKD_SHA1_KDF, CKD_SHA224_KDF, CKD_SHA256_KDF, CKD_SHA384_KDF, CKD_SHA512_KDF })
{
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey3,true,kdf,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey4,false,kdf,true);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey3,hKey4));

CPPUNIT_ASSERT(!compareSecret(hSessionRW,hKey1,hKey3));

// ANSI X9.63 KDF's derive arbitrarily long sequences of bytes, short are prefixes of longer

keyAttribs[0].pValue = val1;
keyAttribs[0].ulValueLen = sizeof(val1);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false,24);
CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey1, keyAttribs, 1) );
CPPUNIT_ASSERT(rv == CKR_OK);

keyAttribs[0].pValue = val2;
keyAttribs[0].ulValueLen = sizeof(val2);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false,48);
rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey2, keyAttribs, 1) );
CPPUNIT_ASSERT(rv == CKR_OK);

CPPUNIT_ASSERT(memcmp(val1, val2, 24) == 0);
}
}
#endif

Expand Down Expand Up @@ -592,37 +636,76 @@ void DeriveTests::testEddsaDerive(const char* alg)
rv = generateEdKeyPair(alg,hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

// Private Session Keys
rv = generateEdKeyPair(alg,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
CPPUNIT_ASSERT(rv == CKR_OK);
rv = generateEdKeyPair(alg,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

// Public Token Keys
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
CPPUNIT_ASSERT(rv == CKR_OK);
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

// Private Token Keys
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
CPPUNIT_ASSERT(rv == CKR_OK);
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
CPPUNIT_ASSERT(rv == CKR_OK);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE hKey4 = CK_INVALID_HANDLE;

CK_ATTRIBUTE keyAttribs[] = {
{ CKA_VALUE, NULL_PTR, 0 },
};
CK_BYTE val1[48];
CK_BYTE val2[48];

// KDF's
for (ck_ec_kdf_t kdf : { CKD_SHA1_KDF, CKD_SHA224_KDF, CKD_SHA256_KDF, CKD_SHA384_KDF, CKD_SHA512_KDF })
{
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));

ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey3,true,kdf,true);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey4,false,kdf,true);
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey3,hKey4));

CPPUNIT_ASSERT(!compareSecret(hSessionRW,hKey1,hKey3));

// ANSI X9.63 KDF's derive arbitrarily long sequences of bytes, short are prefixes of longer

keyAttribs[0].pValue = val1;
keyAttribs[0].ulValueLen = sizeof(val1);
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false,24);
CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey1, keyAttribs, 1) );
CPPUNIT_ASSERT(rv == CKR_OK);

keyAttribs[0].pValue = val2;
keyAttribs[0].ulValueLen = sizeof(val2);
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false,48);
rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey2, keyAttribs, 1) );
CPPUNIT_ASSERT(rv == CKR_OK);

CPPUNIT_ASSERT(memcmp(val1, val2, 24) == 0);
}
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/lib/test/DeriveTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class DeriveTests : public TestsBase
CK_RV generateEcKeyPair(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk);
#endif
#if defined(WITH_ECC) || defined(WITH_EDDSA)
void ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw);
void ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw, ck_ec_kdf_t kdf, bool useSharedData, CK_ULONG secLen);
#endif
#ifdef WITH_EDDSA
CK_RV generateEdKeyPair(const char* alg, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk);
Expand Down

0 comments on commit 296ec66

Please sign in to comment.