@@ -304,7 +304,7 @@ void DeriveTests::dhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicK
304304}
305305
306306#if defined(WITH_ECC) || defined(WITH_EDDSA)
307- void DeriveTests::ecdhDerive (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw)
307+ 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 )
308308{
309309 CK_ATTRIBUTE valAttrib = { CKA_EC_POINT, NULL_PTR, 0 };
310310 CK_RV rv = CRYPTOKI_F_PTR ( C_GetAttributeValue (hSession, hPublicKey, &valAttrib, 1 ) );
@@ -313,7 +313,7 @@ void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPubli
313313 rv = CRYPTOKI_F_PTR ( C_GetAttributeValue (hSession, hPublicKey, &valAttrib, 1 ) );
314314 CPPUNIT_ASSERT (rv == CKR_OK);
315315
316- CK_ECDH1_DERIVE_PARAMS parms = { CKD_NULL , 0 , NULL_PTR, 0 , NULL_PTR };
316+ CK_ECDH1_DERIVE_PARAMS parms = { kdf , 0 , NULL_PTR, 0 , NULL_PTR };
317317 // Use RAW or DER format
318318 if (useRaw)
319319 {
@@ -342,14 +342,19 @@ void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPubli
342342 parms.ulPublicDataLen = valAttrib.ulValueLen ;
343343 }
344344
345+ if (useSharedData)
346+ {
347+ parms.pSharedData = (unsigned char *) " TEST" ;
348+ parms.ulSharedDataLen = 4 ;
349+ }
350+
345351 CK_MECHANISM mechanism = { CKM_ECDH1_DERIVE, NULL , 0 };
346352 mechanism.pParameter = &parms;
347353 mechanism.ulParameterLen = sizeof (parms);
348354 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
349355 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
350356 CK_BBOOL bFalse = CK_FALSE;
351357 CK_BBOOL bTrue = CK_TRUE;
352- CK_ULONG secLen = 32 ;
353358 CK_ATTRIBUTE keyAttribs[] = {
354359 { CKA_CLASS, &keyClass, sizeof (keyClass) },
355360 { CKA_KEY_TYPE, &keyType, sizeof (keyType) },
@@ -512,37 +517,76 @@ void DeriveTests::testEcdsaDerive()
512517 rv = generateEcKeyPair (" P-256" ,hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
513518 CPPUNIT_ASSERT (rv == CKR_OK);
514519 CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
515- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
520+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
516521 CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
517- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
522+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
518523 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
519524
520525 // Private Session Keys
521526 rv = generateEcKeyPair (" P-384" ,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
522527 CPPUNIT_ASSERT (rv == CKR_OK);
523528 rv = generateEcKeyPair (" P-384" ,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
524529 CPPUNIT_ASSERT (rv == CKR_OK);
525- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
526- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
530+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
531+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
527532 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
528533
529534 // Public Token Keys
530535 rv = generateEcKeyPair (" P-521" ,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
531536 CPPUNIT_ASSERT (rv == CKR_OK);
532537 rv = generateEcKeyPair (" P-521" ,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
533538 CPPUNIT_ASSERT (rv == CKR_OK);
534- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
535- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
539+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
540+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
536541 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
537542
538543 // Private Token Keys
539544 rv = generateEcKeyPair (" P-256" ,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
540545 CPPUNIT_ASSERT (rv == CKR_OK);
541546 rv = generateEcKeyPair (" P-256" ,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
542547 CPPUNIT_ASSERT (rv == CKR_OK);
543- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
544- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
548+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
549+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
545550 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
551+
552+ CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
553+ CK_OBJECT_HANDLE hKey4 = CK_INVALID_HANDLE;
554+
555+ CK_ATTRIBUTE keyAttribs[] = {
556+ { CKA_VALUE, NULL_PTR, 0 },
557+ };
558+ CK_BYTE val1[48 ];
559+ CK_BYTE val2[48 ];
560+
561+ // KDF's
562+ for (ck_ec_kdf_t kdf : { CKD_SHA1_KDF, CKD_SHA224_KDF, CKD_SHA256_KDF, CKD_SHA384_KDF, CKD_SHA512_KDF })
563+ {
564+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,kdf,false );
565+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,kdf,false );
566+ CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
567+
568+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey3,true ,kdf,true );
569+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey4,false ,kdf,true );
570+ CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey3,hKey4));
571+
572+ CPPUNIT_ASSERT (!compareSecret (hSessionRW,hKey1,hKey3));
573+
574+ // ANSI X9.63 KDF's derive arbitrarily long sequences of bytes, short are prefixes of longer
575+
576+ keyAttribs[0 ].pValue = val1;
577+ keyAttribs[0 ].ulValueLen = sizeof (val1);
578+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,kdf,false ,24 );
579+ CK_RV rv = CRYPTOKI_F_PTR ( C_GetAttributeValue (hSessionRW, hKey1, keyAttribs, 1 ) );
580+ CPPUNIT_ASSERT (rv == CKR_OK);
581+
582+ keyAttribs[0 ].pValue = val2;
583+ keyAttribs[0 ].ulValueLen = sizeof (val2);
584+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,kdf,false ,48 );
585+ rv = CRYPTOKI_F_PTR ( C_GetAttributeValue (hSessionRW, hKey2, keyAttribs, 1 ) );
586+ CPPUNIT_ASSERT (rv == CKR_OK);
587+
588+ CPPUNIT_ASSERT (memcmp (val1, val2, 24 ) == 0 );
589+ }
546590}
547591#endif
548592
@@ -592,37 +636,76 @@ void DeriveTests::testEddsaDerive(const char* alg)
592636 rv = generateEdKeyPair (alg,hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
593637 CPPUNIT_ASSERT (rv == CKR_OK);
594638 CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
595- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
639+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
596640 CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
597- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
641+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
598642 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
599643
600644 // Private Session Keys
601645 rv = generateEdKeyPair (alg,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
602646 CPPUNIT_ASSERT (rv == CKR_OK);
603647 rv = generateEdKeyPair (alg,hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
604648 CPPUNIT_ASSERT (rv == CKR_OK);
605- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
606- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
649+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
650+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
607651 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
608652
609653 // Public Token Keys
610654 rv = generateEdKeyPair (alg,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
611655 CPPUNIT_ASSERT (rv == CKR_OK);
612656 rv = generateEdKeyPair (alg,hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
613657 CPPUNIT_ASSERT (rv == CKR_OK);
614- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
615- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
658+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
659+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
616660 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
617661
618662 // Private Token Keys
619663 rv = generateEdKeyPair (alg,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
620664 CPPUNIT_ASSERT (rv == CKR_OK);
621665 rv = generateEdKeyPair (alg,hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
622666 CPPUNIT_ASSERT (rv == CKR_OK);
623- ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true );
624- ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false );
667+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,CKD_NULL, false );
668+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,CKD_NULL, false );
625669 CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
670+
671+ CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
672+ CK_OBJECT_HANDLE hKey4 = CK_INVALID_HANDLE;
673+
674+ CK_ATTRIBUTE keyAttribs[] = {
675+ { CKA_VALUE, NULL_PTR, 0 },
676+ };
677+ CK_BYTE val1[48 ];
678+ CK_BYTE val2[48 ];
679+
680+ // KDF's
681+ for (ck_ec_kdf_t kdf : { CKD_SHA1_KDF, CKD_SHA224_KDF, CKD_SHA256_KDF, CKD_SHA384_KDF, CKD_SHA512_KDF })
682+ {
683+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,kdf,false );
684+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,kdf,false );
685+ CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey1,hKey2));
686+
687+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey3,true ,kdf,true );
688+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey4,false ,kdf,true );
689+ CPPUNIT_ASSERT (compareSecret (hSessionRW,hKey3,hKey4));
690+
691+ CPPUNIT_ASSERT (!compareSecret (hSessionRW,hKey1,hKey3));
692+
693+ // ANSI X9.63 KDF's derive arbitrarily long sequences of bytes, short are prefixes of longer
694+
695+ keyAttribs[0 ].pValue = val1;
696+ keyAttribs[0 ].ulValueLen = sizeof (val1);
697+ ecdhDerive (hSessionRW,hPuk1,hPrk2,hKey1,true ,kdf,false ,24 );
698+ CK_RV rv = CRYPTOKI_F_PTR ( C_GetAttributeValue (hSessionRW, hKey1, keyAttribs, 1 ) );
699+ CPPUNIT_ASSERT (rv == CKR_OK);
700+
701+ keyAttribs[0 ].pValue = val2;
702+ keyAttribs[0 ].ulValueLen = sizeof (val2);
703+ ecdhDerive (hSessionRW,hPuk2,hPrk1,hKey2,false ,kdf,false ,48 );
704+ rv = CRYPTOKI_F_PTR ( C_GetAttributeValue (hSessionRW, hKey2, keyAttribs, 1 ) );
705+ CPPUNIT_ASSERT (rv == CKR_OK);
706+
707+ CPPUNIT_ASSERT (memcmp (val1, val2, 24 ) == 0 );
708+ }
626709}
627710#endif
628711
0 commit comments