From 7d842c598963bc6cfe35658e443f998f73cd6a03 Mon Sep 17 00:00:00 2001 From: Rickard Bellgrim Date: Fri, 2 Sep 2016 23:04:24 +0200 Subject: [PATCH] Issue #205: ECDSA P-521 support for OpenSSL and better test coverage. --- NEWS | 3 + src/lib/crypto/OSSLUtil.cpp | 87 ++++++--- src/lib/crypto/test/ECDSATests.cpp | 5 +- src/lib/test/SignVerifyTests.cpp | 297 ++++++++++++++++++++++------- src/lib/test/SignVerifyTests.h | 16 +- 5 files changed, 313 insertions(+), 95 deletions(-) diff --git a/NEWS b/NEWS index 56f851eda..b37393e5b 100644 --- a/NEWS +++ b/NEWS @@ -19,10 +19,13 @@ SoftHSM develop * Issue #209: Possibility to test other PKCS#11 implementations with the CppUnit test. (Patch from Lars SilvĂ©n) +* Issue #223: Mark public key as non private by default. + (Patch from Nikos Mavrogiannopoulos) Bugfixes: * Issue #201: Missing new source file and test configuration in the Windows build project. +* Issue #205: ECDSA P-521 support for OpenSSL and better test coverage. * Issue #207: Fix segmentation faults in loadLibrary function. (Patch from Jaroslav Imrich) * Issue #218: Fix build warnings. diff --git a/src/lib/crypto/OSSLUtil.cpp b/src/lib/crypto/OSSLUtil.cpp index 17c94f0a5..61472ffbc 100644 --- a/src/lib/crypto/OSSLUtil.cpp +++ b/src/lib/crypto/OSSLUtil.cpp @@ -88,16 +88,29 @@ ByteString OSSL::pt2ByteString(const EC_POINT* pt, const EC_GROUP* grp) if (pt != NULL && grp != NULL) { size_t len = EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - if (len > 0x7f) + // Definite, short + if (len <= 0x7f) { - ERROR_MSG("Oversized EC point"); - - return rv; + rv.resize(2 + len); + rv[0] = V_ASN1_OCTET_STRING; + rv[1] = len & 0x7f; + EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &rv[2], len, NULL); + } + // Definite, long + else + { + // Get the number of length octets + ByteString length(len); + unsigned int counter = 0; + while (length[counter] == 0 && counter < (length.size()-1)) counter++; + ByteString lengthOctets(&length[counter], length.size() - counter); + + rv.resize(len + 2 + lengthOctets.size()); + rv[0] = V_ASN1_OCTET_STRING; + rv[1] = 0x80 | lengthOctets.size(); + memcpy(&rv[2], &lengthOctets[0], lengthOctets.size()); + EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &rv[2 + lengthOctets.size()], len, NULL); } - rv.resize(len + 2); - rv[0] = V_ASN1_OCTET_STRING; - rv[1] = len & 0x7f; - EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &rv[2], len, NULL); } return rv; @@ -107,42 +120,72 @@ ByteString OSSL::pt2ByteString(const EC_POINT* pt, const EC_GROUP* grp) EC_POINT* OSSL::byteString2pt(const ByteString& byteString, const EC_GROUP* grp) { size_t len = byteString.size(); - if (len < 2) + size_t controlOctets = 2; + if (len < controlOctets) { ERROR_MSG("Undersized EC point"); return NULL; } - len -= 2; - if (len > 0x7f) - { - ERROR_MSG("Oversized EC point"); - return NULL; - } ByteString repr = byteString; + if (repr[0] != V_ASN1_OCTET_STRING) { ERROR_MSG("EC point tag is not OCTET STRING"); return NULL; } - if (repr[1] != len) + + // Definite, short + if (repr[1] < 0x80) { - if (repr[1] < len) + if (repr[1] != (len - controlOctets)) { - ERROR_MSG("Underrun EC point"); + if (repr[1] < (len - controlOctets)) + { + ERROR_MSG("Underrun EC point"); + } + else + { + ERROR_MSG("Overrun EC point"); + } + + return NULL; } - else + } + // Definite, long + else + { + size_t lengthOctets = repr[1] & 0x7f; + controlOctets += lengthOctets; + + if (controlOctets >= repr.size()) { - ERROR_MSG("Overrun EC point"); + ERROR_MSG("Undersized EC point"); + + return NULL; } - return NULL; + ByteString length(&repr[2], lengthOctets); + + if (length.long_val() != (len - controlOctets)) + { + if (length.long_val() < (len - controlOctets)) + { + ERROR_MSG("Underrun EC point"); + } + else + { + ERROR_MSG("Overrun EC point"); + } + + return NULL; + } } EC_POINT* pt = EC_POINT_new(grp); - if (!EC_POINT_oct2point(grp, pt, &repr[2], len, NULL)) + if (!EC_POINT_oct2point(grp, pt, &repr[controlOctets], len - controlOctets, NULL)) { EC_POINT_free(pt); return NULL; diff --git a/src/lib/crypto/test/ECDSATests.cpp b/src/lib/crypto/test/ECDSATests.cpp index 20e2e8e79..3c29d0613 100644 --- a/src/lib/crypto/test/ECDSATests.cpp +++ b/src/lib/crypto/test/ECDSATests.cpp @@ -76,6 +76,8 @@ void ECDSATests::testKeyGeneration() curves.push_back(ByteString("06082a8648ce3d030107")); // Add secp384r1 curves.push_back(ByteString("06052b81040022")); + // Add secp521r1 + curves.push_back(ByteString("06052b81040023")); for (std::vector::iterator c = curves.begin(); c != curves.end(); c++) { @@ -192,7 +194,8 @@ void ECDSATests::testSigningVerifying() totest.push_back(std::make_pair(ByteString("06082a8648ce3d030107"), HashAlgo::SHA256)); // Add secp384r1 totest.push_back(std::make_pair(ByteString("06052b81040022"), HashAlgo::SHA384)); - + // Add secp521r1 + totest.push_back(std::make_pair(ByteString("06052b81040023"), HashAlgo::SHA384)); for (std::vector >::iterator k = totest.begin(); k != totest.end(); k++) { diff --git a/src/lib/test/SignVerifyTests.cpp b/src/lib/test/SignVerifyTests.cpp index 7decf9c92..a3ffbd35c 100644 --- a/src/lib/test/SignVerifyTests.cpp +++ b/src/lib/test/SignVerifyTests.cpp @@ -55,35 +55,107 @@ const CK_BBOOL IS_PUBLIC = CK_FALSE; CPPUNIT_TEST_SUITE_REGISTRATION(SignVerifyTests); -CK_RV SignVerifyTests::generateRsaKeyPair(CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk) +CK_RV SignVerifyTests::generateRSA(CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk) { CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; + CK_KEY_TYPE keyType = CKK_RSA; CK_ULONG bits = 1536; CK_BYTE pubExp[] = {0x01, 0x00, 0x01}; - CK_BYTE subject[] = { 0x12, 0x34 }; // dummy + CK_BYTE label[] = { 0x12, 0x34 }; // dummy CK_BYTE id[] = { 123 } ; // dummy CK_BBOOL bFalse = CK_FALSE; CK_BBOOL bTrue = CK_TRUE; CK_ATTRIBUTE pukAttribs[] = { - { CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) }, - { CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) }, - { CKA_ENCRYPT, &bFalse, sizeof(bFalse) }, + { CKA_LABEL, &label[0], sizeof(label) }, + { CKA_ID, &id[0], sizeof(id) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, { CKA_VERIFY, &bTrue, sizeof(bTrue) }, + { CKA_ENCRYPT, &bFalse, sizeof(bFalse) }, { CKA_WRAP, &bFalse, sizeof(bFalse) }, + { CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) }, + { CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) }, { CKA_MODULUS_BITS, &bits, sizeof(bits) }, { CKA_PUBLIC_EXPONENT, &pubExp[0], sizeof(pubExp) } }; CK_ATTRIBUTE prkAttribs[] = { + { CKA_LABEL, &label[0], sizeof(label) }, + { CKA_ID, &id[0], sizeof(id) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_SIGN, &bTrue, sizeof(bTrue) }, + { CKA_DECRYPT, &bFalse, sizeof(bFalse) }, + { CKA_UNWRAP, &bFalse, sizeof(bFalse) }, + { CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, { CKA_TOKEN, &bTokenPrk, sizeof(bTokenPrk) }, { CKA_PRIVATE, &bPrivatePrk, sizeof(bPrivatePrk) }, - { CKA_SUBJECT, &subject[0], sizeof(subject) }, + { CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) } + }; + + hPuk = CK_INVALID_HANDLE; + hPrk = CK_INVALID_HANDLE; + return CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, + pukAttribs, sizeof(pukAttribs)/sizeof(CK_ATTRIBUTE), + prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE), + &hPuk, &hPrk) ); +} + +#ifdef WITH_ECC +CK_RV SignVerifyTests::generateEC(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) +{ + CK_MECHANISM mechanism = { CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0 }; + CK_KEY_TYPE keyType = CKK_EC; + CK_BYTE oidP256[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }; + CK_BYTE oidP384[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22 }; + CK_BYTE oidP521[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23 }; + CK_BYTE label[] = { 0x12, 0x34 }; // dummy + CK_BYTE id[] = { 123 } ; // dummy + CK_BBOOL bFalse = CK_FALSE; + CK_BBOOL bTrue = CK_TRUE; + + CK_ATTRIBUTE pukAttribs[] = { + { CKA_EC_PARAMS, NULL, 0 }, + { CKA_LABEL, &label[0], sizeof(label) }, { CKA_ID, &id[0], sizeof(id) }, - { CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, - { CKA_DECRYPT, &bFalse, sizeof(bFalse) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_VERIFY, &bTrue, sizeof(bTrue) }, + { CKA_ENCRYPT, &bFalse, sizeof(bFalse) }, + { CKA_WRAP, &bFalse, sizeof(bFalse) }, + { CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) }, + { CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) } + }; + CK_ATTRIBUTE prkAttribs[] = { + { CKA_LABEL, &label[0], sizeof(label) }, + { CKA_ID, &id[0], sizeof(id) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, { CKA_SIGN, &bTrue, sizeof(bTrue) }, - { CKA_UNWRAP, &bFalse, sizeof(bFalse) } + { CKA_DECRYPT, &bFalse, sizeof(bFalse) }, + { CKA_UNWRAP, &bFalse, sizeof(bFalse) }, + { CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, + { CKA_TOKEN, &bTokenPrk, sizeof(bTokenPrk) }, + { CKA_PRIVATE, &bPrivatePrk, sizeof(bPrivatePrk) }, + { CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) } }; + /* Select the curve */ + if (strcmp(curve, "P-256") == 0) + { + pukAttribs[0].pValue = oidP256; + pukAttribs[0].ulValueLen = sizeof(oidP256); + } + else if (strcmp(curve, "P-384") == 0) + { + pukAttribs[0].pValue = oidP384; + pukAttribs[0].ulValueLen = sizeof(oidP384); + } + else if (strcmp(curve, "P-521") == 0) + { + pukAttribs[0].pValue = oidP521; + pukAttribs[0].ulValueLen = sizeof(oidP521); + } + else + { + return CKR_GENERAL_ERROR; + } + hPuk = CK_INVALID_HANDLE; hPrk = CK_INVALID_HANDLE; return CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, @@ -91,11 +163,12 @@ CK_RV SignVerifyTests::generateRsaKeyPair(CK_SESSION_HANDLE hSession, CK_BBOOL b prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE), &hPuk, &hPrk) ); } +#endif -void SignVerifyTests::rsaPkcsSignVerify(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey) +void SignVerifyTests::signVerifySingle(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param /* = NULL_PTR */, CK_ULONG paramLen /* = 0 */) { CK_RV rv; - CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 }; + CK_MECHANISM mechanism = { mechanismType, param, paramLen }; CK_BYTE data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,0x0C, 0x0D, 0x0F }; CK_BYTE signature[256]; CK_ULONG ulSignatureLen = 0; @@ -112,9 +185,17 @@ void SignVerifyTests::rsaPkcsSignVerify(CK_MECHANISM_TYPE mechanismType, CK_SESS rv = CRYPTOKI_F_PTR( C_Verify(hSession,data,sizeof(data),signature,ulSignatureLen) ); CPPUNIT_ASSERT(rv==CKR_OK); + + // verify again, but now change the input that is being signed. + rv = CRYPTOKI_F_PTR( C_VerifyInit(hSession,&mechanism,hPublicKey) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + data[0] = 0xff; + rv = CRYPTOKI_F_PTR( C_Verify(hSession,data,sizeof(data),signature,ulSignatureLen) ); + CPPUNIT_ASSERT(rv==CKR_SIGNATURE_INVALID); } -void SignVerifyTests::digestRsaPkcsSignVerify(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param /* = NULL_PTR */, CK_ULONG paramLen /* = 0 */) +void SignVerifyTests::signVerifyMulti(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param /* = NULL_PTR */, CK_ULONG paramLen /* = 0 */) { CK_RV rv; CK_MECHANISM mechanism = { mechanismType, param, paramLen }; @@ -153,7 +234,6 @@ void SignVerifyTests::digestRsaPkcsSignVerify(CK_MECHANISM_TYPE mechanismType, C CPPUNIT_ASSERT(rv==CKR_SIGNATURE_INVALID); } - void SignVerifyTests::testRsaSignVerify() { CK_RV rv; @@ -194,86 +274,165 @@ void SignVerifyTests::testRsaSignVerify() CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE; // Public Session keys - rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk); + rv = generateRSA(hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk); CPPUNIT_ASSERT(rv == CKR_OK); - rsaPkcsSignVerify(CKM_RSA_PKCS, hSessionRO, hPuk,hPrk); - rsaPkcsSignVerify(CKM_RSA_X_509, hSessionRO, hPuk,hPrk); + signVerifySingle(CKM_RSA_PKCS, hSessionRO, hPuk,hPrk); + signVerifySingle(CKM_RSA_X_509, hSessionRO, hPuk,hPrk); #ifndef WITH_FIPS - digestRsaPkcsSignVerify(CKM_MD5_RSA_PKCS, hSessionRO, hPuk,hPrk); + signVerifyMulti(CKM_MD5_RSA_PKCS, hSessionRO, hPuk,hPrk); #endif - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS, hSessionRO, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS, hSessionRO, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS, hSessionRO, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS, hSessionRO, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS, hSessionRO, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[0], sizeof(params[0])); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[1], sizeof(params[1])); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[2], sizeof(params[2])); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[3], sizeof(params[3])); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[4], sizeof(params[4])); + signVerifyMulti(CKM_SHA1_RSA_PKCS, hSessionRO, hPuk,hPrk); + signVerifyMulti(CKM_SHA224_RSA_PKCS, hSessionRO, hPuk,hPrk); + signVerifyMulti(CKM_SHA256_RSA_PKCS, hSessionRO, hPuk,hPrk); + signVerifyMulti(CKM_SHA384_RSA_PKCS, hSessionRO, hPuk,hPrk); + signVerifyMulti(CKM_SHA512_RSA_PKCS, hSessionRO, hPuk,hPrk); + signVerifyMulti(CKM_SHA1_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[0], sizeof(params[0])); + signVerifyMulti(CKM_SHA224_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[1], sizeof(params[1])); + signVerifyMulti(CKM_SHA256_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[2], sizeof(params[2])); + signVerifyMulti(CKM_SHA384_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[3], sizeof(params[3])); + signVerifyMulti(CKM_SHA512_RSA_PKCS_PSS, hSessionRO, hPuk,hPrk, ¶ms[4], sizeof(params[4])); // Private Session Keys - rv = generateRsaKeyPair(hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk); + rv = generateRSA(hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk); CPPUNIT_ASSERT(rv == CKR_OK); - rsaPkcsSignVerify(CKM_RSA_PKCS, hSessionRW, hPuk,hPrk); - rsaPkcsSignVerify(CKM_RSA_X_509, hSessionRW, hPuk,hPrk); + signVerifySingle(CKM_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifySingle(CKM_RSA_X_509, hSessionRW, hPuk,hPrk); #ifndef WITH_FIPS - digestRsaPkcsSignVerify(CKM_MD5_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_MD5_RSA_PKCS, hSessionRW, hPuk,hPrk); #endif - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[0], sizeof(params[0])); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[1], sizeof(params[1])); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[2], sizeof(params[2])); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[3], sizeof(params[3])); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[4], sizeof(params[4])); + signVerifyMulti(CKM_SHA1_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA224_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA256_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA384_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA512_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA1_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[0], sizeof(params[0])); + signVerifyMulti(CKM_SHA224_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[1], sizeof(params[1])); + signVerifyMulti(CKM_SHA256_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[2], sizeof(params[2])); + signVerifyMulti(CKM_SHA384_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[3], sizeof(params[3])); + signVerifyMulti(CKM_SHA512_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[4], sizeof(params[4])); // Public Token Keys - rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk); + rv = generateRSA(hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk); CPPUNIT_ASSERT(rv == CKR_OK); - rsaPkcsSignVerify(CKM_RSA_PKCS, hSessionRW, hPuk,hPrk); - rsaPkcsSignVerify(CKM_RSA_X_509, hSessionRW, hPuk,hPrk); + signVerifySingle(CKM_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifySingle(CKM_RSA_X_509, hSessionRW, hPuk,hPrk); #ifndef WITH_FIPS - digestRsaPkcsSignVerify(CKM_MD5_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_MD5_RSA_PKCS, hSessionRW, hPuk,hPrk); #endif - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[0], sizeof(params[0])); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[1], sizeof(params[1])); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[2], sizeof(params[2])); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[3], sizeof(params[3])); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[4], sizeof(params[4])); + signVerifyMulti(CKM_SHA1_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA224_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA256_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA384_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA512_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA1_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[0], sizeof(params[0])); + signVerifyMulti(CKM_SHA224_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[1], sizeof(params[1])); + signVerifyMulti(CKM_SHA256_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[2], sizeof(params[2])); + signVerifyMulti(CKM_SHA384_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[3], sizeof(params[3])); + signVerifyMulti(CKM_SHA512_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[4], sizeof(params[4])); // Private Token Keys - rv = generateRsaKeyPair(hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk); + rv = generateRSA(hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk); CPPUNIT_ASSERT(rv == CKR_OK); - rsaPkcsSignVerify(CKM_RSA_PKCS, hSessionRW, hPuk,hPrk); - rsaPkcsSignVerify(CKM_RSA_X_509, hSessionRW, hPuk,hPrk); + signVerifySingle(CKM_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifySingle(CKM_RSA_X_509, hSessionRW, hPuk,hPrk); #ifndef WITH_FIPS - digestRsaPkcsSignVerify(CKM_MD5_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_MD5_RSA_PKCS, hSessionRW, hPuk,hPrk); #endif - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS, hSessionRW, hPuk,hPrk); - digestRsaPkcsSignVerify(CKM_SHA1_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[0], sizeof(params[0])); - digestRsaPkcsSignVerify(CKM_SHA224_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[1], sizeof(params[1])); - digestRsaPkcsSignVerify(CKM_SHA256_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[2], sizeof(params[2])); - digestRsaPkcsSignVerify(CKM_SHA384_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[3], sizeof(params[3])); - digestRsaPkcsSignVerify(CKM_SHA512_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[4], sizeof(params[4])); + signVerifyMulti(CKM_SHA1_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA224_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA256_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA384_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA512_RSA_PKCS, hSessionRW, hPuk,hPrk); + signVerifyMulti(CKM_SHA1_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[0], sizeof(params[0])); + signVerifyMulti(CKM_SHA224_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[1], sizeof(params[1])); + signVerifyMulti(CKM_SHA256_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[2], sizeof(params[2])); + signVerifyMulti(CKM_SHA384_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[3], sizeof(params[3])); + signVerifyMulti(CKM_SHA512_RSA_PKCS_PSS, hSessionRW, hPuk,hPrk, ¶ms[4], sizeof(params[4])); } +#ifdef WITH_ECC +void SignVerifyTests::testEcSignVerify() +{ + CK_RV rv; + CK_SESSION_HANDLE hSessionRO; + CK_SESSION_HANDLE hSessionRW; + + // Just make sure that we finalize any previous tests + CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) ); + + // Open read-only session on when the token is not initialized should fail + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) ); + CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED); + + // Initialize the library and start the test. + rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Open read-only session + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Open read-write session + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Login USER into the sessions so we can create a private objects + rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + CK_OBJECT_HANDLE hPuk = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE; + + // Public Session keys + rv = generateEC("P-256", hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-384", hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-521", hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + + // Private Session Keys + rv = generateEC("P-256", hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-384", hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-521", hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + + // Public Token Keys + rv = generateEC("P-256", hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-384", hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-521", hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + + // Private Token Keys + rv = generateEC("P-256", hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-384", hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); + rv = generateEC("P-521", hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_ECDSA, hSessionRO, hPuk,hPrk); +} +#endif + CK_RV SignVerifyTests::generateKey(CK_SESSION_HANDLE hSession, CK_KEY_TYPE keyType, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey) { #ifndef WITH_BOTAN diff --git a/src/lib/test/SignVerifyTests.h b/src/lib/test/SignVerifyTests.h index 9605eea15..dc645ef64 100644 --- a/src/lib/test/SignVerifyTests.h +++ b/src/lib/test/SignVerifyTests.h @@ -34,6 +34,7 @@ #ifndef _SOFTHSM_V2_SIGNVERIFYTESTS_H #define _SOFTHSM_V2_SIGNVERIFYTESTS_H +#include "config.h" #include "TestsBase.h" #include @@ -41,17 +42,26 @@ class SignVerifyTests : public TestsBase { CPPUNIT_TEST_SUITE(SignVerifyTests); CPPUNIT_TEST(testRsaSignVerify); +#ifdef WITH_ECC + CPPUNIT_TEST(testEcSignVerify); +#endif CPPUNIT_TEST(testHmacSignVerify); CPPUNIT_TEST_SUITE_END(); public: void testRsaSignVerify(); +#ifdef WITH_ECC + void testEcSignVerify(); +#endif void testHmacSignVerify(); protected: - CK_RV generateRsaKeyPair(CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk); - void rsaPkcsSignVerify(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey); - void digestRsaPkcsSignVerify(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param = NULL_PTR, CK_ULONG paramLen = 0); + CK_RV generateRSA(CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk); +#ifdef WITH_ECC + CK_RV generateEC(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 + void signVerifySingle(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param = NULL_PTR, CK_ULONG paramLen = 0); + void signVerifyMulti(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param = NULL_PTR, CK_ULONG paramLen = 0); CK_RV generateKey(CK_SESSION_HANDLE hSession, CK_KEY_TYPE keyType, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey); void hmacSignVerify(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey); };