Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6207282

Browse files
AearsisOndřej Hlavatý
authored and
Ondřej Hlavatý
committedNov 29, 2024·
Add tests for ECDH with KDFs
Signed-off-by: Ondřej Hlavatý <aearsis@eideo.cz>
1 parent 5c8d939 commit 6207282

File tree

2 files changed

+103
-20
lines changed

2 files changed

+103
-20
lines changed
 

‎src/lib/test/DeriveTests.cpp

+102-19
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ void DeriveTests::dhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicK
328328
}
329329

330330
#if defined(WITH_ECC) || defined(WITH_EDDSA)
331-
void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw)
331+
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)
332332
{
333333
CK_ATTRIBUTE valAttrib = { CKA_EC_POINT, NULL_PTR, 0 };
334334
CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
@@ -337,7 +337,7 @@ void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPubli
337337
rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
338338
CPPUNIT_ASSERT(rv == CKR_OK);
339339

340-
CK_ECDH1_DERIVE_PARAMS parms = { CKD_NULL, 0, NULL_PTR, 0, NULL_PTR };
340+
CK_ECDH1_DERIVE_PARAMS parms = { kdf, 0, NULL_PTR, 0, NULL_PTR };
341341
// Use RAW or DER format
342342
if (useRaw)
343343
{
@@ -366,14 +366,19 @@ void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPubli
366366
parms.ulPublicDataLen = valAttrib.ulValueLen;
367367
}
368368

369+
if (useSharedData)
370+
{
371+
parms.pSharedData = (unsigned char *) "TEST";
372+
parms.ulSharedDataLen = 4;
373+
}
374+
369375
CK_MECHANISM mechanism = { CKM_ECDH1_DERIVE, NULL, 0 };
370376
mechanism.pParameter = &parms;
371377
mechanism.ulParameterLen = sizeof(parms);
372378
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
373379
CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
374380
CK_BBOOL bFalse = CK_FALSE;
375381
CK_BBOOL bTrue = CK_TRUE;
376-
CK_ULONG secLen = 32;
377382
CK_ATTRIBUTE keyAttribs[] = {
378383
{ CKA_CLASS, &keyClass, sizeof(keyClass) },
379384
{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
@@ -536,37 +541,76 @@ void DeriveTests::testEcdsaDerive()
536541
rv = generateEcKeyPair("P-256",hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
537542
CPPUNIT_ASSERT(rv == CKR_OK);
538543
CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
539-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
544+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
540545
CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
541-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
546+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
542547
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
543548

544549
// Private Session Keys
545550
rv = generateEcKeyPair("P-384",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
546551
CPPUNIT_ASSERT(rv == CKR_OK);
547552
rv = generateEcKeyPair("P-384",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
548553
CPPUNIT_ASSERT(rv == CKR_OK);
549-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
550-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
554+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
555+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
551556
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
552557

553558
// Public Token Keys
554559
rv = generateEcKeyPair("P-521",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
555560
CPPUNIT_ASSERT(rv == CKR_OK);
556561
rv = generateEcKeyPair("P-521",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
557562
CPPUNIT_ASSERT(rv == CKR_OK);
558-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
559-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
563+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
564+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
560565
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
561566

562567
// Private Token Keys
563568
rv = generateEcKeyPair("P-256",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
564569
CPPUNIT_ASSERT(rv == CKR_OK);
565570
rv = generateEcKeyPair("P-256",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
566571
CPPUNIT_ASSERT(rv == CKR_OK);
567-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
568-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
572+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
573+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
569574
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
575+
576+
CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
577+
CK_OBJECT_HANDLE hKey4 = CK_INVALID_HANDLE;
578+
579+
CK_ATTRIBUTE keyAttribs[] = {
580+
{ CKA_VALUE, NULL_PTR, 0 },
581+
};
582+
CK_BYTE val1[48];
583+
CK_BYTE val2[48];
584+
585+
// KDF's
586+
for (ck_ec_kdf_t kdf : { CKD_SHA1_KDF, CKD_SHA224_KDF, CKD_SHA256_KDF, CKD_SHA384_KDF, CKD_SHA512_KDF })
587+
{
588+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false);
589+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false);
590+
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
591+
592+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey3,true,kdf,true);
593+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey4,false,kdf,true);
594+
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey3,hKey4));
595+
596+
CPPUNIT_ASSERT(!compareSecret(hSessionRW,hKey1,hKey3));
597+
598+
// ANSI X9.63 KDF's derive arbitrarily long sequences of bytes, short are prefixes of longer
599+
600+
keyAttribs[0].pValue = val1;
601+
keyAttribs[0].ulValueLen = sizeof(val1);
602+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false,24);
603+
CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey1, keyAttribs, 1) );
604+
CPPUNIT_ASSERT(rv == CKR_OK);
605+
606+
keyAttribs[0].pValue = val2;
607+
keyAttribs[0].ulValueLen = sizeof(val2);
608+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false,48);
609+
rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey2, keyAttribs, 1) );
610+
CPPUNIT_ASSERT(rv == CKR_OK);
611+
612+
CPPUNIT_ASSERT(memcmp(val1, val2, 24) == 0);
613+
}
570614
}
571615
#endif
572616

@@ -616,37 +660,76 @@ void DeriveTests::testEddsaDerive(const char* alg)
616660
rv = generateEdKeyPair(alg,hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
617661
CPPUNIT_ASSERT(rv == CKR_OK);
618662
CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
619-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
663+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
620664
CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
621-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
665+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
622666
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
623667

624668
// Private Session Keys
625669
rv = generateEdKeyPair(alg,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
626670
CPPUNIT_ASSERT(rv == CKR_OK);
627671
rv = generateEdKeyPair(alg,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
628672
CPPUNIT_ASSERT(rv == CKR_OK);
629-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
630-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
673+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
674+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
631675
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
632676

633677
// Public Token Keys
634678
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
635679
CPPUNIT_ASSERT(rv == CKR_OK);
636680
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
637681
CPPUNIT_ASSERT(rv == CKR_OK);
638-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
639-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
682+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
683+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
640684
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
641685

642686
// Private Token Keys
643687
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
644688
CPPUNIT_ASSERT(rv == CKR_OK);
645689
rv = generateEdKeyPair(alg,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
646690
CPPUNIT_ASSERT(rv == CKR_OK);
647-
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
648-
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
691+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,CKD_NULL,false);
692+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,CKD_NULL,false);
649693
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
694+
695+
CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
696+
CK_OBJECT_HANDLE hKey4 = CK_INVALID_HANDLE;
697+
698+
CK_ATTRIBUTE keyAttribs[] = {
699+
{ CKA_VALUE, NULL_PTR, 0 },
700+
};
701+
CK_BYTE val1[48];
702+
CK_BYTE val2[48];
703+
704+
// KDF's
705+
for (ck_ec_kdf_t kdf : { CKD_SHA1_KDF, CKD_SHA224_KDF, CKD_SHA256_KDF, CKD_SHA384_KDF, CKD_SHA512_KDF })
706+
{
707+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false);
708+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false);
709+
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
710+
711+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey3,true,kdf,true);
712+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey4,false,kdf,true);
713+
CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey3,hKey4));
714+
715+
CPPUNIT_ASSERT(!compareSecret(hSessionRW,hKey1,hKey3));
716+
717+
// ANSI X9.63 KDF's derive arbitrarily long sequences of bytes, short are prefixes of longer
718+
719+
keyAttribs[0].pValue = val1;
720+
keyAttribs[0].ulValueLen = sizeof(val1);
721+
ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true,kdf,false,24);
722+
CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey1, keyAttribs, 1) );
723+
CPPUNIT_ASSERT(rv == CKR_OK);
724+
725+
keyAttribs[0].pValue = val2;
726+
keyAttribs[0].ulValueLen = sizeof(val2);
727+
ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false,kdf,false,48);
728+
rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSessionRW, hKey2, keyAttribs, 1) );
729+
CPPUNIT_ASSERT(rv == CKR_OK);
730+
731+
CPPUNIT_ASSERT(memcmp(val1, val2, 24) == 0);
732+
}
650733
}
651734
#endif
652735

‎src/lib/test/DeriveTests.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class DeriveTests : public TestsBase
7575
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);
7676
#endif
7777
#if defined(WITH_ECC) || defined(WITH_EDDSA)
78-
void ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw);
78+
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);
7979
#endif
8080
#ifdef WITH_EDDSA
8181
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);

0 commit comments

Comments
 (0)