diff --git a/src/lib/SoftHSM.cpp b/src/lib/SoftHSM.cpp index 234fbfa1..3a462160 100644 --- a/src/lib/SoftHSM.cpp +++ b/src/lib/SoftHSM.cpp @@ -2471,16 +2471,20 @@ CK_RV SoftHSM::AsymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec mechanism = AsymMech::RSA; isRSA = true; break; - case CKM_RSA_PKCS_OAEP: - if (keyType != CKK_RSA) - return CKR_KEY_TYPE_INCONSISTENT; - rv = MechParamCheckRSAPKCSOAEP(pMechanism); - if (rv != CKR_OK) - return rv; - - mechanism = AsymMech::RSA_PKCS_OAEP; - isRSA = true; - break; + case CKM_RSA_PKCS_OAEP: + if (keyType != CKK_RSA) + return CKR_KEY_TYPE_INCONSISTENT; + { + RSA_PKCS_OAEP_PARAMS oaepParams; + rv = MechParamCheckRSAPKCSOAEP(pMechanism, &oaepParams); + if (rv != CKR_OK) + return rv; + + mechanism = AsymMech::RSA_PKCS_OAEP; + isRSA = true; + session->setParameters(&oaepParams, sizeof(oaepParams)); + } + break; default: return CKR_MECHANISM_INVALID; } @@ -2647,8 +2651,10 @@ static CK_RV AsymEncrypt(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen data += ByteString(pData, ulDataLen); - // Encrypt the data - if (!asymCrypto->encrypt(publicKey,data,encryptedData,mechanism)) + // Encrypt the data + size_t paramLen = 0; + void* param = session->getParameters(paramLen); + if (!asymCrypto->encrypt(publicKey,data,encryptedData,mechanism,param,paramLen)) { session->resetOp(); return CKR_GENERAL_ERROR; @@ -3205,29 +3211,20 @@ CK_RV SoftHSM::AsymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec mechanism = AsymMech::RSA; isRSA = true; break; - case CKM_RSA_PKCS_OAEP: - if (keyType != CKK_RSA) - return CKR_KEY_TYPE_INCONSISTENT; - if (pMechanism->pParameter == NULL_PTR || - pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS)) - { - DEBUG_MSG("pParameter must be of type CK_RSA_PKCS_OAEP_PARAMS"); - return CKR_ARGUMENTS_BAD; - } - if (CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1) - { - DEBUG_MSG("hashAlg must be CKM_SHA_1"); - return CKR_ARGUMENTS_BAD; - } - if (CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1) - { - DEBUG_MSG("mgf must be CKG_MGF1_SHA1"); - return CKR_ARGUMENTS_BAD; - } - - mechanism = AsymMech::RSA_PKCS_OAEP; - isRSA = true; - break; + case CKM_RSA_PKCS_OAEP: + if (keyType != CKK_RSA) + return CKR_KEY_TYPE_INCONSISTENT; + { + RSA_PKCS_OAEP_PARAMS oaepParams; + rv = MechParamCheckRSAPKCSOAEP(pMechanism, &oaepParams); + if (rv != CKR_OK) + return rv; + + mechanism = AsymMech::RSA_PKCS_OAEP; + isRSA = true; + session->setParameters(&oaepParams, sizeof(oaepParams)); + } + break; default: return CKR_MECHANISM_INVALID; } @@ -3391,8 +3388,10 @@ static CK_RV AsymDecrypt(Session* session, CK_BYTE_PTR pEncryptedData, CK_ULONG ByteString encryptedData(pEncryptedData, ulEncryptedDataLen); ByteString data; - // Decrypt the data - if (!asymCrypto->decrypt(privateKey,encryptedData,data,mechanism)) + // Decrypt the data + size_t paramLen = 0; + void* param = session->getParameters(paramLen); + if (!asymCrypto->decrypt(privateKey,encryptedData,data,mechanism,param,paramLen)) { session->resetOp(); return CKR_ENCRYPTED_DATA_INVALID; @@ -6445,11 +6444,14 @@ CK_RV SoftHSM::WrapKeyAsym ByteString& wrapped ) { - const size_t bb = 8; - AsymAlgo::Type algo = AsymAlgo::Unknown; - AsymMech::Type mech = AsymMech::Unknown; + const size_t bb = 8; + CK_RV rv = CKR_OK; + AsymAlgo::Type algo = AsymAlgo::Unknown; + AsymMech::Type mech = AsymMech::Unknown; + RSA_PKCS_OAEP_PARAMS oaepParams; + bool hasOaepParams = false; - CK_ULONG modulus_length; + CK_ULONG modulus_length; switch(pMechanism->mechanism) { case CKM_RSA_PKCS: case CKM_RSA_PKCS_OAEP: @@ -6466,24 +6468,27 @@ CK_RV SoftHSM::WrapKeyAsym } switch(pMechanism->mechanism) { - case CKM_RSA_PKCS: - mech = AsymMech::RSA_PKCS; - // RFC 3447 section 7.2.1 - if (keydata.size() > modulus_length - 11) - return CKR_KEY_SIZE_RANGE; - break; + case CKM_RSA_PKCS: + mech = AsymMech::RSA_PKCS; + // RFC 3447 section 7.2.1 + if (keydata.size() > modulus_length - 11) + return CKR_KEY_SIZE_RANGE; + break; - case CKM_RSA_PKCS_OAEP: - mech = AsymMech::RSA_PKCS_OAEP; - // SHA-1 is the only supported option - // PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen - if (keydata.size() > modulus_length - 2 - 2 * 160 / 8) - return CKR_KEY_SIZE_RANGE; - break; + case CKM_RSA_PKCS_OAEP: + rv = MechParamCheckRSAPKCSOAEP(pMechanism, &oaepParams); + if (rv != CKR_OK) + return rv; + mech = AsymMech::RSA_PKCS_OAEP; + // PKCS#11 2.40 section 2.1.8: input length <= k-2-2*hashLen + if (keydata.size() > modulus_length - 2 - 2 * oaepParams.hashLen) + return CKR_KEY_SIZE_RANGE; + hasOaepParams = true; + break; - default: - return CKR_MECHANISM_INVALID; - } + default: + return CKR_MECHANISM_INVALID; + } AsymmetricAlgorithm* cipher = CryptoFactory::i()->getAsymmetricAlgorithm(algo); if (cipher == NULL) return CKR_MECHANISM_INVALID; @@ -6508,14 +6513,16 @@ CK_RV SoftHSM::WrapKeyAsym default: return CKR_MECHANISM_INVALID; - } - // Wrap the key - if (!cipher->wrapKey(publicKey, keydata, wrapped, mech)) - { - cipher->recyclePublicKey(publicKey); - CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher); - return CKR_GENERAL_ERROR; - } + } + // Wrap the key + const void* param = hasOaepParams ? &oaepParams : NULL; + const size_t paramLen = hasOaepParams ? sizeof(oaepParams) : 0; + if (!cipher->wrapKey(publicKey, keydata, wrapped, mech, param, paramLen)) + { + cipher->recyclePublicKey(publicKey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher); + return CKR_GENERAL_ERROR; + } cipher->recyclePublicKey(publicKey); CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher); @@ -7034,22 +7041,28 @@ CK_RV SoftHSM::UnwrapKeyAsym { CK_RV rv = CKR_OK; // Get the symmetric algorithm matching the mechanism - AsymAlgo::Type algo = AsymAlgo::Unknown; - AsymMech::Type mode = AsymMech::Unknown; - switch(pMechanism->mechanism) { - case CKM_RSA_PKCS: - algo = AsymAlgo::RSA; - mode = AsymMech::RSA_PKCS; - break; + AsymAlgo::Type algo = AsymAlgo::Unknown; + AsymMech::Type mode = AsymMech::Unknown; + RSA_PKCS_OAEP_PARAMS oaepParams; + bool hasOaepParams = false; + switch(pMechanism->mechanism) { + case CKM_RSA_PKCS: + algo = AsymAlgo::RSA; + mode = AsymMech::RSA_PKCS; + break; - case CKM_RSA_PKCS_OAEP: - algo = AsymAlgo::RSA; - mode = AsymMech::RSA_PKCS_OAEP; - break; + case CKM_RSA_PKCS_OAEP: + algo = AsymAlgo::RSA; + mode = AsymMech::RSA_PKCS_OAEP; + rv = MechParamCheckRSAPKCSOAEP(pMechanism, &oaepParams); + if (rv != CKR_OK) + return rv; + hasOaepParams = true; + break; - default: - return CKR_MECHANISM_INVALID; - } + default: + return CKR_MECHANISM_INVALID; + } AsymmetricAlgorithm* cipher = CryptoFactory::i()->getAsymmetricAlgorithm(algo); if (cipher == NULL) return CKR_MECHANISM_INVALID; @@ -7075,12 +7088,14 @@ CK_RV SoftHSM::UnwrapKeyAsym return CKR_MECHANISM_INVALID; } - // Unwrap the key - if (!cipher->unwrapKey(unwrappingkey, wrapped, keydata, mode)) - rv = CKR_GENERAL_ERROR; - cipher->recyclePrivateKey(unwrappingkey); - CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher); - return rv; + // Unwrap the key + const void* param = hasOaepParams ? &oaepParams : NULL; + const size_t paramLen = hasOaepParams ? sizeof(oaepParams) : 0; + if (!cipher->unwrapKey(unwrappingkey, wrapped, keydata, mode, param, paramLen)) + rv = CKR_GENERAL_ERROR; + cipher->recyclePrivateKey(unwrappingkey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher); + return rv; } // Internal: Unwrap with mechanism RSA_AES_KEY_WRAP @@ -13159,48 +13174,144 @@ bool SoftHSM::setGOSTPrivateKey(OSObject* key, const ByteString &ber, Token* tok return bOK; } -CK_RV SoftHSM::MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism) +static bool getHashProperties(CK_MECHANISM_TYPE mech, HashAlgo::Type& hashType, size_t& hashLen) { - // This is a programming error - if (pMechanism->mechanism != CKM_RSA_PKCS_OAEP) { - ERROR_MSG("MechParamCheckRSAPKCSOAEP called on wrong mechanism"); - return CKR_GENERAL_ERROR; - } + switch (mech) + { + case CKM_SHA_1: + hashType = HashAlgo::SHA1; + hashLen = 20; + return true; + case CKM_SHA224: + hashType = HashAlgo::SHA224; + hashLen = 28; + return true; + case CKM_SHA256: + hashType = HashAlgo::SHA256; + hashLen = 32; + return true; + case CKM_SHA384: + hashType = HashAlgo::SHA384; + hashLen = 48; + return true; + case CKM_SHA512: + hashType = HashAlgo::SHA512; + hashLen = 64; + return true; + default: + return false; + } +} - if (pMechanism->pParameter == NULL_PTR || - pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS)) - { - ERROR_MSG("pParameter must be of type CK_RSA_PKCS_OAEP_PARAMS"); - return CKR_ARGUMENTS_BAD; - } +static bool getMGFType(CK_RSA_PKCS_MGF_TYPE mgf, AsymRSAMGF::Type& mgfType) +{ + switch (mgf) + { + case CKG_MGF1_SHA1: + mgfType = AsymRSAMGF::MGF1_SHA1; + return true; + case CKG_MGF1_SHA224: + mgfType = AsymRSAMGF::MGF1_SHA224; + return true; + case CKG_MGF1_SHA256: + mgfType = AsymRSAMGF::MGF1_SHA256; + return true; + case CKG_MGF1_SHA384: + mgfType = AsymRSAMGF::MGF1_SHA384; + return true; + case CKG_MGF1_SHA512: + mgfType = AsymRSAMGF::MGF1_SHA512; + return true; + default: + return false; + } +} - CK_RSA_PKCS_OAEP_PARAMS_PTR params = (CK_RSA_PKCS_OAEP_PARAMS_PTR)pMechanism->pParameter; - if (params->hashAlg != CKM_SHA_1) - { - ERROR_MSG("hashAlg must be CKM_SHA_1"); - return CKR_ARGUMENTS_BAD; - } - if (params->mgf != CKG_MGF1_SHA1) - { - ERROR_MSG("mgf must be CKG_MGF1_SHA1"); - return CKR_ARGUMENTS_BAD; - } - if (params->source != CKZ_DATA_SPECIFIED) - { - ERROR_MSG("source must be CKZ_DATA_SPECIFIED"); - return CKR_ARGUMENTS_BAD; - } +CK_RV SoftHSM::MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism, RSA_PKCS_OAEP_PARAMS* outParams) +{ + // This is a programming error + if (pMechanism->mechanism != CKM_RSA_PKCS_OAEP) { + ERROR_MSG("MechParamCheckRSAPKCSOAEP called on wrong mechanism"); + return CKR_GENERAL_ERROR; + } + + if (pMechanism->pParameter == NULL_PTR || + pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS)) + { + ERROR_MSG("pParameter must be of type CK_RSA_PKCS_OAEP_PARAMS"); + return CKR_ARGUMENTS_BAD; + } + + CK_RSA_PKCS_OAEP_PARAMS_PTR params = (CK_RSA_PKCS_OAEP_PARAMS_PTR)pMechanism->pParameter; + CK_MECHANISM_TYPE hashMech = params->hashAlg; + if (hashMech == 0) + hashMech = CKM_SHA_1; + + HashAlgo::Type hashType = HashAlgo::Unknown; + size_t hashLen = 0; + if (!getHashProperties(hashMech, hashType, hashLen)) + { + ERROR_MSG("Unsupported OAEP hash mechanism"); + return CKR_ARGUMENTS_BAD; + } + + CK_RSA_PKCS_MGF_TYPE mgfMech = params->mgf; + if (mgfMech == 0) + { + switch (hashMech) + { + case CKM_SHA_1: mgfMech = CKG_MGF1_SHA1; break; + case CKM_SHA224: mgfMech = CKG_MGF1_SHA224; break; + case CKM_SHA256: mgfMech = CKG_MGF1_SHA256; break; + case CKM_SHA384: mgfMech = CKG_MGF1_SHA384; break; + case CKM_SHA512: mgfMech = CKG_MGF1_SHA512; break; + default: mgfMech = CKG_MGF1_SHA1; break; + } + } + + AsymRSAMGF::Type mgfType = AsymRSAMGF::Unknown; + if (!getMGFType(mgfMech, mgfType)) + { + ERROR_MSG("Unsupported OAEP MGF"); + return CKR_ARGUMENTS_BAD; + } + + bool mgfMatchesHash = + (hashType == HashAlgo::SHA1 && mgfType == AsymRSAMGF::MGF1_SHA1) || + (hashType == HashAlgo::SHA224 && mgfType == AsymRSAMGF::MGF1_SHA224) || + (hashType == HashAlgo::SHA256 && mgfType == AsymRSAMGF::MGF1_SHA256) || + (hashType == HashAlgo::SHA384 && mgfType == AsymRSAMGF::MGF1_SHA384) || + (hashType == HashAlgo::SHA512 && mgfType == AsymRSAMGF::MGF1_SHA512); + + if (!mgfMatchesHash) + { + ERROR_MSG("mgf must match hash algorithm"); + return CKR_ARGUMENTS_BAD; + } + if (params->source != CKZ_DATA_SPECIFIED) + { + ERROR_MSG("source must be CKZ_DATA_SPECIFIED"); + return CKR_ARGUMENTS_BAD; + } if (params->pSourceData != NULL) { ERROR_MSG("pSourceData must be NULL"); return CKR_ARGUMENTS_BAD; } - if (params->ulSourceDataLen != 0) - { - ERROR_MSG("ulSourceDataLen must be 0"); - return CKR_ARGUMENTS_BAD; - } - return CKR_OK; + if (params->ulSourceDataLen != 0) + { + ERROR_MSG("ulSourceDataLen must be 0"); + return CKR_ARGUMENTS_BAD; + } + + if (outParams != NULL) + { + outParams->hashAlg = hashType; + outParams->mgf = mgfType; + outParams->hashLen = hashLen; + } + + return CKR_OK; } @@ -13229,26 +13340,27 @@ CK_RV SoftHSM::MechParamCheckRSAAESKEYWRAP(CK_MECHANISM_PTR pMechanism) ERROR_MSG("oaep_params must be of type CK_RSA_PKCS_OAEP_PARAMS"); return CKR_ARGUMENTS_BAD; } - if (params->oaep_params->mgf < 1UL || params->oaep_params->mgf > 5UL) - { - ERROR_MSG("mgf not supported"); - return CKR_ARGUMENTS_BAD; - } - if (params->oaep_params->source != CKZ_DATA_SPECIFIED) - { - ERROR_MSG("source must be CKZ_DATA_SPECIFIED"); - return CKR_ARGUMENTS_BAD; - } - if (params->oaep_params->pSourceData != NULL) - { - ERROR_MSG("pSourceData must be NULL"); - return CKR_ARGUMENTS_BAD; - } - if (params->oaep_params->ulSourceDataLen != 0) - { - ERROR_MSG("ulSourceDataLen must be 0"); - return CKR_ARGUMENTS_BAD; - } + if (params->oaep_params->source != CKZ_DATA_SPECIFIED) + { + ERROR_MSG("source must be CKZ_DATA_SPECIFIED"); + return CKR_ARGUMENTS_BAD; + } + if (params->oaep_params->pSourceData != NULL) + { + ERROR_MSG("pSourceData must be NULL"); + return CKR_ARGUMENTS_BAD; + } + if (params->oaep_params->ulSourceDataLen != 0) + { + ERROR_MSG("ulSourceDataLen must be 0"); + return CKR_ARGUMENTS_BAD; + } + CK_MECHANISM oaepMech = { CKM_RSA_PKCS_OAEP, params->oaep_params, sizeof(CK_RSA_PKCS_OAEP_PARAMS) }; + CK_RV rv = MechParamCheckRSAPKCSOAEP(&oaepMech); + if (rv != CKR_OK) + { + return rv; + } return CKR_OK; } diff --git a/src/lib/SoftHSM.h b/src/lib/SoftHSM.h index 644686b2..0b4f5513 100644 --- a/src/lib/SoftHSM.h +++ b/src/lib/SoftHSM.h @@ -507,7 +507,7 @@ class SoftHSM ByteString &keydata ); - CK_RV MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism); + CK_RV MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism, RSA_PKCS_OAEP_PARAMS* outParams = NULL); CK_RV MechParamCheckRSAAESKEYWRAP(CK_MECHANISM_PTR pMechanism); bool isMechanismPermitted(OSObject* key, CK_MECHANISM_PTR pMechanism); diff --git a/src/lib/crypto/AsymmetricAlgorithm.cpp b/src/lib/crypto/AsymmetricAlgorithm.cpp index 20a50a5f..45ef0bf9 100644 --- a/src/lib/crypto/AsymmetricAlgorithm.cpp +++ b/src/lib/crypto/AsymmetricAlgorithm.cpp @@ -156,20 +156,20 @@ bool AsymmetricAlgorithm::isWrappingMech(AsymMech::Type padding) } // Wrap/Unwrap keys -bool AsymmetricAlgorithm::wrapKey(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding) +bool AsymmetricAlgorithm::wrapKey(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { - if (!isWrappingMech(padding)) - return false; + if (!isWrappingMech(padding)) + return false; - return encrypt(publicKey, data, encryptedData, padding); + return encrypt(publicKey, data, encryptedData, padding, param, paramLen); } -bool AsymmetricAlgorithm::unwrapKey(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding) +bool AsymmetricAlgorithm::unwrapKey(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { - if (!isWrappingMech(padding)) - return false; + if (!isWrappingMech(padding)) + return false; - return decrypt(privateKey, encryptedData, data, padding); + return decrypt(privateKey, encryptedData, data, padding, param, paramLen); } diff --git a/src/lib/crypto/AsymmetricAlgorithm.h b/src/lib/crypto/AsymmetricAlgorithm.h index 52519db6..8bad0519 100644 --- a/src/lib/crypto/AsymmetricAlgorithm.h +++ b/src/lib/crypto/AsymmetricAlgorithm.h @@ -111,9 +111,16 @@ struct AsymRSAMGF struct RSA_PKCS_PSS_PARAMS { - HashAlgo::Type hashAlg; - AsymRSAMGF::Type mgf; - size_t sLen; + HashAlgo::Type hashAlg; + AsymRSAMGF::Type mgf; + size_t sLen; +}; + +struct RSA_PKCS_OAEP_PARAMS +{ + HashAlgo::Type hashAlg; + AsymRSAMGF::Type mgf; + size_t hashLen; }; class AsymmetricAlgorithm @@ -138,14 +145,14 @@ class AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding) = 0; + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0) = 0; - // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding) = 0; + // Decryption functions + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0) = 0; - // Wrap/Unwrap keys - bool wrapKey(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); - bool unwrapKey(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + // Wrap/Unwrap keys + bool wrapKey(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); + bool unwrapKey(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL) = 0; diff --git a/src/lib/crypto/BotanDH.cpp b/src/lib/crypto/BotanDH.cpp index 82b7aec0..51adb5e0 100644 --- a/src/lib/crypto/BotanDH.cpp +++ b/src/lib/crypto/BotanDH.cpp @@ -93,7 +93,7 @@ bool BotanDH::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool BotanDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DH does not support encryption"); @@ -102,7 +102,7 @@ bool BotanDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool BotanDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DH does not support decryption"); diff --git a/src/lib/crypto/BotanDH.h b/src/lib/crypto/BotanDH.h index af2ac598..b54fd859 100644 --- a/src/lib/crypto/BotanDH.h +++ b/src/lib/crypto/BotanDH.h @@ -54,10 +54,10 @@ class BotanDH : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/BotanDSA.cpp b/src/lib/crypto/BotanDSA.cpp index a26001b4..2356bd65 100644 --- a/src/lib/crypto/BotanDSA.cpp +++ b/src/lib/crypto/BotanDSA.cpp @@ -485,7 +485,7 @@ bool BotanDSA::verifyFinal(const ByteString& signature) // Encryption functions bool BotanDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DSA does not support encryption"); @@ -494,7 +494,7 @@ bool BotanDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool BotanDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DSA does not support decryption"); diff --git a/src/lib/crypto/BotanDSA.h b/src/lib/crypto/BotanDSA.h index dd100165..dc559300 100644 --- a/src/lib/crypto/BotanDSA.h +++ b/src/lib/crypto/BotanDSA.h @@ -59,10 +59,10 @@ class BotanDSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/BotanECDH.cpp b/src/lib/crypto/BotanECDH.cpp index 8f45f43a..0b93a704 100644 --- a/src/lib/crypto/BotanECDH.cpp +++ b/src/lib/crypto/BotanECDH.cpp @@ -94,7 +94,7 @@ bool BotanECDH::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool BotanECDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDH does not support encryption"); @@ -103,7 +103,7 @@ bool BotanECDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool BotanECDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDH does not support decryption"); diff --git a/src/lib/crypto/BotanECDH.h b/src/lib/crypto/BotanECDH.h index 3fac507e..e182717a 100644 --- a/src/lib/crypto/BotanECDH.h +++ b/src/lib/crypto/BotanECDH.h @@ -54,10 +54,10 @@ class BotanECDH : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/BotanECDSA.cpp b/src/lib/crypto/BotanECDSA.cpp index 4fffa4ec..0358e84b 100644 --- a/src/lib/crypto/BotanECDSA.cpp +++ b/src/lib/crypto/BotanECDSA.cpp @@ -321,7 +321,7 @@ bool BotanECDSA::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool BotanECDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDSA does not support encryption"); @@ -330,7 +330,7 @@ bool BotanECDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool BotanECDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDSA does not support decryption"); diff --git a/src/lib/crypto/BotanECDSA.h b/src/lib/crypto/BotanECDSA.h index 826d318d..e1e6f0e7 100644 --- a/src/lib/crypto/BotanECDSA.h +++ b/src/lib/crypto/BotanECDSA.h @@ -59,10 +59,10 @@ class BotanECDSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/BotanEDDSA.cpp b/src/lib/crypto/BotanEDDSA.cpp index f2b1b232..512c5dcc 100644 --- a/src/lib/crypto/BotanEDDSA.cpp +++ b/src/lib/crypto/BotanEDDSA.cpp @@ -256,7 +256,7 @@ bool BotanEDDSA::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool BotanEDDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("EDDSA does not support encryption"); @@ -265,7 +265,7 @@ bool BotanEDDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool BotanEDDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("EDDSA does not support decryption"); diff --git a/src/lib/crypto/BotanEDDSA.h b/src/lib/crypto/BotanEDDSA.h index 552bca46..b5603cd1 100644 --- a/src/lib/crypto/BotanEDDSA.h +++ b/src/lib/crypto/BotanEDDSA.h @@ -59,10 +59,10 @@ class BotanEDDSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/BotanGOST.cpp b/src/lib/crypto/BotanGOST.cpp index 4ae0d13b..28243c3b 100644 --- a/src/lib/crypto/BotanGOST.cpp +++ b/src/lib/crypto/BotanGOST.cpp @@ -326,7 +326,7 @@ bool BotanGOST::verifyFinal(const ByteString& signature) // Encryption functions bool BotanGOST::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("GOST does not support encryption"); @@ -335,7 +335,7 @@ bool BotanGOST::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool BotanGOST::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("GOST does not support decryption"); diff --git a/src/lib/crypto/BotanGOST.h b/src/lib/crypto/BotanGOST.h index a8085ab1..e7c25dce 100644 --- a/src/lib/crypto/BotanGOST.h +++ b/src/lib/crypto/BotanGOST.h @@ -57,10 +57,10 @@ class BotanGOST : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/BotanRSA.cpp b/src/lib/crypto/BotanRSA.cpp index 3ed450ef..9e071fea 100644 --- a/src/lib/crypto/BotanRSA.cpp +++ b/src/lib/crypto/BotanRSA.cpp @@ -742,33 +742,110 @@ bool BotanRSA::verifyFinal(const ByteString& signature) return verResult; } +namespace +{ +static bool getBotanOAEPParameters(const void* param, const size_t paramLen, std::string& eme) +{ + const RSA_PKCS_OAEP_PARAMS* oaep = NULL; + + if (param != NULL) + { + if (paramLen != sizeof(RSA_PKCS_OAEP_PARAMS)) + { + ERROR_MSG("Invalid OAEP parameter size"); + return false; + } + + oaep = static_cast(param); + } + + HashAlgo::Type hash = HashAlgo::SHA1; + AsymRSAMGF::Type mgf = AsymRSAMGF::MGF1_SHA1; + + if (oaep != NULL) + { + hash = oaep->hashAlg; + mgf = oaep->mgf; + } + + switch (hash) + { + case HashAlgo::SHA1: + if (mgf != AsymRSAMGF::MGF1_SHA1) + { + ERROR_MSG("Unsupported OAEP MGF for Botan backend"); + return false; + } + eme = "EME1(SHA-160)"; + return true; + case HashAlgo::SHA224: + if (mgf != AsymRSAMGF::MGF1_SHA224) + { + ERROR_MSG("Unsupported OAEP MGF for Botan backend"); + return false; + } + eme = "EME1(SHA-224)"; + return true; + case HashAlgo::SHA256: + if (mgf != AsymRSAMGF::MGF1_SHA256) + { + ERROR_MSG("Unsupported OAEP MGF for Botan backend"); + return false; + } + eme = "EME1(SHA-256)"; + return true; + case HashAlgo::SHA384: + if (mgf != AsymRSAMGF::MGF1_SHA384) + { + ERROR_MSG("Unsupported OAEP MGF for Botan backend"); + return false; + } + eme = "EME1(SHA-384)"; + return true; + case HashAlgo::SHA512: + if (mgf != AsymRSAMGF::MGF1_SHA512) + { + ERROR_MSG("Unsupported OAEP MGF for Botan backend"); + return false; + } + eme = "EME1(SHA-512)"; + return true; + default: + ERROR_MSG("Unsupported OAEP hash for Botan backend (%d)", hash); + return false; + } +} +} + // Encryption functions bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data, - ByteString& encryptedData, const AsymMech::Type padding) + ByteString& encryptedData, const AsymMech::Type padding, + const void* param /* = NULL */, const size_t paramLen /* = 0 */) { - // Check if the public key is the right type - if (!publicKey->isOfType(BotanRSAPublicKey::type)) - { - ERROR_MSG("Invalid key type supplied"); + // Check if the public key is the right type + if (!publicKey->isOfType(BotanRSAPublicKey::type)) + { + ERROR_MSG("Invalid key type supplied"); return false; } std::string eme; - switch (padding) - { - case AsymMech::RSA_PKCS: - eme = "PKCS1v15"; - break; - case AsymMech::RSA_PKCS_OAEP: - eme = "EME1(SHA-160)"; - break; - case AsymMech::RSA: - eme = "Raw"; - break; - default: - ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); + switch (padding) + { + case AsymMech::RSA_PKCS: + eme = "PKCS1v15"; + break; + case AsymMech::RSA_PKCS_OAEP: + if (!getBotanOAEPParameters(param, paramLen, eme)) + return false; + break; + case AsymMech::RSA: + eme = "Raw"; + break; + default: + ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); return false; } @@ -823,31 +900,33 @@ bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data, // Decryption functions bool BotanRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData, - ByteString& data, const AsymMech::Type padding) + ByteString& data, const AsymMech::Type padding, + const void* param /* = NULL */, const size_t paramLen /* = 0 */) { - // Check if the private key is the right type - if (!privateKey->isOfType(BotanRSAPrivateKey::type)) - { - ERROR_MSG("Invalid key type supplied"); + // Check if the private key is the right type + if (!privateKey->isOfType(BotanRSAPrivateKey::type)) + { + ERROR_MSG("Invalid key type supplied"); return false; } std::string eme; - switch (padding) - { - case AsymMech::RSA_PKCS: - eme = "PKCS1v15"; - break; - case AsymMech::RSA_PKCS_OAEP: - eme = "EME1(SHA-160)"; - break; - case AsymMech::RSA: - eme = "Raw"; - break; - default: - ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); + switch (padding) + { + case AsymMech::RSA_PKCS: + eme = "PKCS1v15"; + break; + case AsymMech::RSA_PKCS_OAEP: + if (!getBotanOAEPParameters(param, paramLen, eme)) + return false; + break; + case AsymMech::RSA: + eme = "Raw"; + break; + default: + ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); return false; } diff --git a/src/lib/crypto/BotanRSA.h b/src/lib/crypto/BotanRSA.h index f9b65541..264a8f61 100644 --- a/src/lib/crypto/BotanRSA.h +++ b/src/lib/crypto/BotanRSA.h @@ -60,10 +60,10 @@ class BotanRSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); - // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + // Decryption functions + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/OSSLDH.cpp b/src/lib/crypto/OSSLDH.cpp index ee61733c..444fa787 100644 --- a/src/lib/crypto/OSSLDH.cpp +++ b/src/lib/crypto/OSSLDH.cpp @@ -91,7 +91,7 @@ bool OSSLDH::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool OSSLDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DH does not support encryption"); @@ -100,7 +100,7 @@ bool OSSLDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool OSSLDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DH does not support decryption"); diff --git a/src/lib/crypto/OSSLDH.h b/src/lib/crypto/OSSLDH.h index d611aee1..b7d1d627 100644 --- a/src/lib/crypto/OSSLDH.h +++ b/src/lib/crypto/OSSLDH.h @@ -54,10 +54,10 @@ class OSSLDH : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/OSSLDSA.cpp b/src/lib/crypto/OSSLDSA.cpp index 06b5d501..2da35e95 100644 --- a/src/lib/crypto/OSSLDSA.cpp +++ b/src/lib/crypto/OSSLDSA.cpp @@ -437,7 +437,7 @@ bool OSSLDSA::verifyFinal(const ByteString& signature) // Encryption functions bool OSSLDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DSA does not support encryption"); @@ -446,7 +446,7 @@ bool OSSLDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool OSSLDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("DSA does not support decryption"); diff --git a/src/lib/crypto/OSSLDSA.h b/src/lib/crypto/OSSLDSA.h index 1fb2b1e5..a37335a7 100644 --- a/src/lib/crypto/OSSLDSA.h +++ b/src/lib/crypto/OSSLDSA.h @@ -60,10 +60,10 @@ class OSSLDSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/OSSLECDH.cpp b/src/lib/crypto/OSSLECDH.cpp index e2abaeb2..89c50cd8 100644 --- a/src/lib/crypto/OSSLECDH.cpp +++ b/src/lib/crypto/OSSLECDH.cpp @@ -94,7 +94,7 @@ bool OSSLECDH::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool OSSLECDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDH does not support encryption"); @@ -103,7 +103,7 @@ bool OSSLECDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool OSSLECDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDH does not support decryption"); diff --git a/src/lib/crypto/OSSLECDH.h b/src/lib/crypto/OSSLECDH.h index 2cafa6fd..1db74798 100644 --- a/src/lib/crypto/OSSLECDH.h +++ b/src/lib/crypto/OSSLECDH.h @@ -54,10 +54,10 @@ class OSSLECDH : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/OSSLECDSA.cpp b/src/lib/crypto/OSSLECDSA.cpp index 23139c1b..00660153 100644 --- a/src/lib/crypto/OSSLECDSA.cpp +++ b/src/lib/crypto/OSSLECDSA.cpp @@ -331,7 +331,7 @@ bool OSSLECDSA::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool OSSLECDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDSA does not support encryption"); @@ -340,7 +340,7 @@ bool OSSLECDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool OSSLECDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("ECDSA does not support decryption"); diff --git a/src/lib/crypto/OSSLECDSA.h b/src/lib/crypto/OSSLECDSA.h index 992fa40b..e728d2ae 100644 --- a/src/lib/crypto/OSSLECDSA.h +++ b/src/lib/crypto/OSSLECDSA.h @@ -56,10 +56,10 @@ class OSSLECDSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/OSSLEDDSA.cpp b/src/lib/crypto/OSSLEDDSA.cpp index dc2f4cc3..ea3f88a0 100644 --- a/src/lib/crypto/OSSLEDDSA.cpp +++ b/src/lib/crypto/OSSLEDDSA.cpp @@ -208,7 +208,7 @@ bool OSSLEDDSA::verifyFinal(const ByteString& /*signature*/) // Encryption functions bool OSSLEDDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("EDDSA does not support encryption"); @@ -217,7 +217,7 @@ bool OSSLEDDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool OSSLEDDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("EDDSA does not support decryption"); diff --git a/src/lib/crypto/OSSLEDDSA.h b/src/lib/crypto/OSSLEDDSA.h index 02b8a115..83cf0390 100644 --- a/src/lib/crypto/OSSLEDDSA.h +++ b/src/lib/crypto/OSSLEDDSA.h @@ -56,10 +56,10 @@ class OSSLEDDSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/OSSLGOST.cpp b/src/lib/crypto/OSSLGOST.cpp index 4f34d45d..f8bd6764 100644 --- a/src/lib/crypto/OSSLGOST.cpp +++ b/src/lib/crypto/OSSLGOST.cpp @@ -428,7 +428,7 @@ bool OSSLGOST::verifyFinal(const ByteString& signature) // Encryption functions bool OSSLGOST::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, - ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("GOST does not support encryption"); @@ -437,7 +437,7 @@ bool OSSLGOST::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, // Decryption functions bool OSSLGOST::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, - ByteString& /*data*/, const AsymMech::Type /*padding*/) + ByteString& /*data*/, const AsymMech::Type /*padding*/, const void* /*param*/ /* = NULL */, const size_t /*paramLen*/ /* = 0 */) { ERROR_MSG("GOST does not support decryption"); diff --git a/src/lib/crypto/OSSLGOST.h b/src/lib/crypto/OSSLGOST.h index ad399f18..d9f4082c 100644 --- a/src/lib/crypto/OSSLGOST.h +++ b/src/lib/crypto/OSSLGOST.h @@ -61,10 +61,10 @@ class OSSLGOST : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/crypto/OSSLRSA.cpp b/src/lib/crypto/OSSLRSA.cpp index d36a1e68..683db6b9 100644 --- a/src/lib/crypto/OSSLRSA.cpp +++ b/src/lib/crypto/OSSLRSA.cpp @@ -38,6 +38,66 @@ #include "RSAParameters.h" #include "OSSLRSAKeyPair.h" #include +#include +#include +#include + +namespace +{ +const EVP_MD* getHashMD(HashAlgo::Type hash) +{ + int nid = 0; + switch (hash) + { + case HashAlgo::SHA1: + nid = NID_sha1; + break; + case HashAlgo::SHA224: + nid = NID_sha224; + break; + case HashAlgo::SHA256: + nid = NID_sha256; + break; + case HashAlgo::SHA384: + nid = NID_sha384; + break; + case HashAlgo::SHA512: + nid = NID_sha512; + break; + default: + return NULL; + } + + return EVP_get_digestbynid(nid); +} + +const EVP_MD* getMGFMD(AsymRSAMGF::Type mgf) +{ + int nid = 0; + switch (mgf) + { + case AsymRSAMGF::MGF1_SHA1: + nid = NID_sha1; + break; + case AsymRSAMGF::MGF1_SHA224: + nid = NID_sha224; + break; + case AsymRSAMGF::MGF1_SHA256: + nid = NID_sha256; + break; + case AsymRSAMGF::MGF1_SHA384: + nid = NID_sha384; + break; + case AsymRSAMGF::MGF1_SHA512: + nid = NID_sha512; + break; + default: + return NULL; + } + + return EVP_get_digestbynid(nid); +} +} #include #include #include @@ -1206,139 +1266,235 @@ bool OSSLRSA::verifyFinal(const ByteString& signature) // Encryption functions bool OSSLRSA::encrypt(PublicKey* publicKey, const ByteString& data, - ByteString& encryptedData, const AsymMech::Type padding) + ByteString& encryptedData, const AsymMech::Type padding, + const void* param /* = NULL */, const size_t paramLen /* = 0 */) { - // Check if the public key is the right type - if (!publicKey->isOfType(OSSLRSAPublicKey::type)) - { - ERROR_MSG("Invalid key type supplied"); - - return false; - } - - // Retrieve the OpenSSL key object - RSA* rsa = ((OSSLRSAPublicKey*) publicKey)->getOSSLKey(); - - // Check the data and padding algorithm - int osslPadding = 0; - - if (padding == AsymMech::RSA_PKCS) - { - // The size of the input data cannot be more than the modulus - // length of the key - 11 - if (data.size() > (size_t) (RSA_size(rsa) - 11)) - { - ERROR_MSG("Too much data supplied for RSA PKCS #1 encryption"); - - return false; - } - - osslPadding = RSA_PKCS1_PADDING; - } - else if (padding == AsymMech::RSA_PKCS_OAEP) - { - // The size of the input data cannot be more than the modulus - // length of the key - 41 - if (data.size() > (size_t) (RSA_size(rsa) - 41)) - { - ERROR_MSG("Too much data supplied for RSA OAEP encryption"); - - return false; - } - - osslPadding = RSA_PKCS1_OAEP_PADDING; - } - else if (padding == AsymMech::RSA) - { - // The size of the input data should be exactly equal to the modulus length - if (data.size() != (size_t) RSA_size(rsa)) - { - ERROR_MSG("Incorrect amount of input data supplied for raw RSA encryption"); - - return false; - } - - osslPadding = RSA_NO_PADDING; - } - else - { - ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); - - return false; - } - - // Perform the RSA operation - encryptedData.resize(RSA_size(rsa)); - - if (RSA_public_encrypt(data.size(), (unsigned char*) data.const_byte_str(), &encryptedData[0], rsa, osslPadding) == -1) - { - ERROR_MSG("RSA public key encryption failed (0x%08X)", ERR_get_error()); - - return false; - } - - return true; + // Check if the public key is the right type + if (!publicKey->isOfType(OSSLRSAPublicKey::type)) + { + ERROR_MSG("Invalid key type supplied"); + + return false; + } + + // Retrieve the OpenSSL key object + RSA* rsa = ((OSSLRSAPublicKey*) publicKey)->getOSSLKey(); + + if (padding == AsymMech::RSA_PKCS_OAEP) + { + const RSA_PKCS_OAEP_PARAMS* oaep = NULL; + + if (param != NULL) + { + if (paramLen != sizeof(RSA_PKCS_OAEP_PARAMS)) + { + ERROR_MSG("Invalid OAEP parameter size"); + return false; + } + + oaep = static_cast(param); + } + + HashAlgo::Type hashType = oaep ? oaep->hashAlg : HashAlgo::SHA1; + AsymRSAMGF::Type mgfType = oaep ? oaep->mgf : AsymRSAMGF::MGF1_SHA1; + + const EVP_MD* hash = getHashMD(hashType); + const EVP_MD* mgfHash = getMGFMD(mgfType); + + if (hash == NULL || mgfHash == NULL) + { + ERROR_MSG("Unsupported OAEP parameters for OpenSSL backend"); + return false; + } + + size_t hashLen = oaep ? oaep->hashLen : static_cast(EVP_MD_size(hash)); + + if (data.size() > (size_t) (RSA_size(rsa) - 2 - 2 * hashLen)) + { + ERROR_MSG("Too much data supplied for RSA OAEP encryption"); + return false; + } + + std::vector padded(RSA_size(rsa)); + + if (!RSA_padding_add_PKCS1_OAEP_mgf1(padded.data(), padded.size(), + data.const_byte_str(), data.size(), + NULL, 0, hash, mgfHash)) + { + ERROR_MSG("RSA OAEP padding failed (0x%08X)", ERR_get_error()); + return false; + } + + encryptedData.resize(RSA_size(rsa)); + + if (RSA_public_encrypt(padded.size(), padded.data(), &encryptedData[0], rsa, RSA_NO_PADDING) == -1) + { + ERROR_MSG("RSA public key encryption failed (0x%08X)", ERR_get_error()); + return false; + } + + return true; + } + + // Check the data and padding algorithm + int osslPadding = 0; + + if (padding == AsymMech::RSA_PKCS) + { + // The size of the input data cannot be more than the modulus + // length of the key - 11 + if (data.size() > (size_t) (RSA_size(rsa) - 11)) + { + ERROR_MSG("Too much data supplied for RSA PKCS #1 encryption"); + + return false; + } + + osslPadding = RSA_PKCS1_PADDING; + } + else if (padding == AsymMech::RSA) + { + // The size of the input data should be exactly equal to the modulus length + if (data.size() != (size_t) RSA_size(rsa)) + { + ERROR_MSG("Incorrect amount of input data supplied for raw RSA encryption"); + + return false; + } + + osslPadding = RSA_NO_PADDING; + } + else + { + ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); + + return false; + } + + // Perform the RSA operation + encryptedData.resize(RSA_size(rsa)); + + if (RSA_public_encrypt(data.size(), (unsigned char*) data.const_byte_str(), &encryptedData[0], rsa, osslPadding) == -1) + { + ERROR_MSG("RSA public key encryption failed (0x%08X)", ERR_get_error()); + + return false; + } + + return true; } // Decryption functions bool OSSLRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData, - ByteString& data, const AsymMech::Type padding) + ByteString& data, const AsymMech::Type padding, + const void* param /* = NULL */, const size_t paramLen /* = 0 */) { - // Check if the private key is the right type - if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) - { - ERROR_MSG("Invalid key type supplied"); - - return false; - } - - // Retrieve the OpenSSL key object - RSA* rsa = ((OSSLRSAPrivateKey*) privateKey)->getOSSLKey(); - - // Check the input size - if (encryptedData.size() != (size_t) RSA_size(rsa)) - { - ERROR_MSG("Invalid amount of input data supplied for RSA decryption"); - - return false; - } - - // Determine the OpenSSL padding algorithm - int osslPadding = 0; - - switch (padding) - { - case AsymMech::RSA_PKCS: - osslPadding = RSA_PKCS1_PADDING; - break; - case AsymMech::RSA_PKCS_OAEP: - osslPadding = RSA_PKCS1_OAEP_PADDING; - break; - case AsymMech::RSA: - osslPadding = RSA_NO_PADDING; - break; - default: - ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); - return false; - } - - // Perform the RSA operation - data.resize(RSA_size(rsa)); - - int decSize = RSA_private_decrypt(encryptedData.size(), (unsigned char*) encryptedData.const_byte_str(), &data[0], rsa, osslPadding); - - if (decSize == -1) - { - ERROR_MSG("RSA private key decryption failed (0x%08X)", ERR_get_error()); - - return false; - } - - data.resize(decSize); - - return true; + // Check if the private key is the right type + if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) + { + ERROR_MSG("Invalid key type supplied"); + + return false; + } + + // Retrieve the OpenSSL key object + RSA* rsa = ((OSSLRSAPrivateKey*) privateKey)->getOSSLKey(); + + // Check the input size + if (encryptedData.size() != (size_t) RSA_size(rsa)) + { + ERROR_MSG("Invalid amount of input data supplied for RSA decryption"); + + return false; + } + + if (padding == AsymMech::RSA_PKCS_OAEP) + { + const RSA_PKCS_OAEP_PARAMS* oaep = NULL; + + if (param != NULL) + { + if (paramLen != sizeof(RSA_PKCS_OAEP_PARAMS)) + { + ERROR_MSG("Invalid OAEP parameter size"); + return false; + } + + oaep = static_cast(param); + } + + HashAlgo::Type hashType = oaep ? oaep->hashAlg : HashAlgo::SHA1; + AsymRSAMGF::Type mgfType = oaep ? oaep->mgf : AsymRSAMGF::MGF1_SHA1; + + const EVP_MD* hash = getHashMD(hashType); + const EVP_MD* mgfHash = getMGFMD(mgfType); + + if (hash == NULL || mgfHash == NULL) + { + ERROR_MSG("Unsupported OAEP parameters for OpenSSL backend"); + return false; + } + + std::vector padded(RSA_size(rsa)); + int decSize = RSA_private_decrypt(encryptedData.size(), + (unsigned char*) encryptedData.const_byte_str(), + padded.data(), rsa, RSA_NO_PADDING); + + if (decSize == -1) + { + ERROR_MSG("RSA private key decryption failed (0x%08X)", ERR_get_error()); + return false; + } + + std::vector recovered(RSA_size(rsa)); + int outLen = RSA_padding_check_PKCS1_OAEP_mgf1(recovered.data(), recovered.size(), + padded.data(), decSize, RSA_size(rsa), + NULL, 0, hash, mgfHash); + + if (outLen == -1) + { + ERROR_MSG("RSA OAEP unpadding failed (0x%08X)", ERR_get_error()); + return false; + } + + data.resize(outLen); + memcpy(&data[0], recovered.data(), outLen); + + return true; + } + + // Determine the OpenSSL padding algorithm + int osslPadding = 0; + + switch (padding) + { + case AsymMech::RSA_PKCS: + osslPadding = RSA_PKCS1_PADDING; + break; + case AsymMech::RSA: + osslPadding = RSA_NO_PADDING; + break; + default: + ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); + return false; + } + + // Perform the RSA operation + data.resize(RSA_size(rsa)); + + int decSize = RSA_private_decrypt(encryptedData.size(), (unsigned char*) encryptedData.const_byte_str(), &data[0], rsa, osslPadding); + + if (decSize == -1) + { + ERROR_MSG("RSA private key decryption failed (0x%08X)", ERR_get_error()); + + return false; + } + + data.resize(decSize); + + return true; } - // Key factory bool OSSLRSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */) { diff --git a/src/lib/crypto/OSSLRSA.h b/src/lib/crypto/OSSLRSA.h index 5b7db6d6..b65af3a7 100644 --- a/src/lib/crypto/OSSLRSA.h +++ b/src/lib/crypto/OSSLRSA.h @@ -60,10 +60,10 @@ class OSSLRSA : public AsymmetricAlgorithm virtual bool verifyFinal(const ByteString& signature); // Encryption functions - virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Decryption functions - virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding, const void* param = NULL, const size_t paramLen = 0); // Key factory virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); diff --git a/src/lib/test/AsymEncryptDecryptTests.cpp b/src/lib/test/AsymEncryptDecryptTests.cpp index 2a537d00..442333ca 100644 --- a/src/lib/test/AsymEncryptDecryptTests.cpp +++ b/src/lib/test/AsymEncryptDecryptTests.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "AsymEncryptDecryptTests.h" // CKA_TOKEN @@ -84,43 +85,59 @@ CK_RV AsymEncryptDecryptTests::generateRsaKeyPair(CK_SESSION_HANDLE hSession, CK void AsymEncryptDecryptTests::rsaEncryptDecrypt(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey) { - CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 }; - CK_RSA_PKCS_OAEP_PARAMS oaepParams = { CKM_SHA_1, CKG_MGF1_SHA1, 1, NULL_PTR, 0 }; - CK_BYTE plainText[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,0x0C, 0x0D, 0x0F }; - CK_BYTE cipherText[256]; - CK_ULONG ulCipherTextLen; - CK_BYTE recoveredText[256]; - CK_ULONG ulRecoveredTextLen; - CK_RV rv; - - if (mechanismType == CKM_RSA_PKCS_OAEP) - { - mechanism.pParameter = &oaepParams; - mechanism.ulParameterLen = sizeof(oaepParams); - } - - rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hPublicKey) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - ulCipherTextLen = sizeof(cipherText); - rv =CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText),cipherText,&ulCipherTextLen) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hPrivateKey) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - ulRecoveredTextLen = sizeof(recoveredText); - rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,cipherText,ulCipherTextLen,recoveredText,&ulRecoveredTextLen) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - CPPUNIT_ASSERT(memcmp(plainText, &recoveredText[ulRecoveredTextLen-sizeof(plainText)], sizeof(plainText)) == 0); + CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 }; + CK_BYTE plainText[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,0x0C, 0x0D, 0x0F }; + CK_BYTE cipherText[256]; + CK_ULONG ulCipherTextLen; + CK_BYTE recoveredText[256]; + CK_ULONG ulRecoveredTextLen; + + auto runCase = [&](void) { + CK_RV rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hPublicKey) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + ulCipherTextLen = sizeof(cipherText); + rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText),cipherText,&ulCipherTextLen) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hPrivateKey) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + ulRecoveredTextLen = sizeof(recoveredText); + rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,cipherText,ulCipherTextLen,recoveredText,&ulRecoveredTextLen) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + CPPUNIT_ASSERT(memcmp(plainText, &recoveredText[ulRecoveredTextLen-sizeof(plainText)], sizeof(plainText)) == 0); + }; + + if (mechanismType == CKM_RSA_PKCS_OAEP) + { + std::vector paramsList = { + { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA224, CKG_MGF1_SHA224, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA256, CKG_MGF1_SHA256, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA384, CKG_MGF1_SHA384, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA512, CKG_MGF1_SHA512, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA256, 0, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { 0, 0, CKZ_DATA_SPECIFIED, NULL_PTR, 0 } + }; + for (std::vector::iterator it = paramsList.begin(); it != paramsList.end(); ++it) + { + mechanism.pParameter = &(*it); + mechanism.ulParameterLen = sizeof(*it); + runCase(); + } + return; + } + + runCase(); } // Check that RSA OAEP mechanism properly validates all input parameters void AsymEncryptDecryptTests::rsaOAEPParams(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey) { - // This is only supported combination of parameters - CK_RSA_PKCS_OAEP_PARAMS oaepParams = { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }; + // Start with a valid combination of parameters + CK_RSA_PKCS_OAEP_PARAMS oaepParams = { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }; CK_MECHANISM mechanism = { CKM_RSA_PKCS_OAEP, NULL, 0 }; CK_RV rv; diff --git a/src/lib/test/AsymWrapUnwrapTests.cpp b/src/lib/test/AsymWrapUnwrapTests.cpp index 917747bf..4b977596 100644 --- a/src/lib/test/AsymWrapUnwrapTests.cpp +++ b/src/lib/test/AsymWrapUnwrapTests.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "AsymWrapUnwrapTests.h" // CKA_TOKEN @@ -115,10 +116,9 @@ void AsymWrapUnwrapTests::rsaWrapUnwrapPvt(CK_SESSION_HANDLE hSession, CK_OBJECT { CK_RV rv = CKR_OK; CK_MECHANISM_INFO mechInfo; - CK_RSA_PKCS_OAEP_PARAMS oaepParams = { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }; - CK_RSA_AES_KEY_WRAP_PARAMS rsa_aes_params = { 256, &oaepParams }; - CK_MECHANISM mechanism = {CKM_RSA_AES_KEY_WRAP, &rsa_aes_params, sizeof(rsa_aes_params)}; - CK_MECHANISM sv_mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 }; + CK_RSA_AES_KEY_WRAP_PARAMS rsa_aes_params = { 256, NULL }; + CK_MECHANISM mechanism = {CKM_RSA_AES_KEY_WRAP, &rsa_aes_params, sizeof(rsa_aes_params)}; + CK_MECHANISM sv_mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 }; 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; @@ -150,60 +150,68 @@ void AsymWrapUnwrapTests::rsaWrapUnwrapPvt(CK_SESSION_HANDLE hSession, CK_OBJECT CPPUNIT_ASSERT(mechInfo.flags&CKF_WRAP); CPPUNIT_ASSERT(mechInfo.flags&CKF_UNWRAP); - // Estimate wrapped length - rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, targetPvtKey, NULL_PTR, &wrappedLenEstimation) ); - CPPUNIT_ASSERT(rv==CKR_OK); - CPPUNIT_ASSERT(wrappedLenEstimation>0); - - // This should always fail because wrapped data have to be longer than 0 bytes - ulCipherTextLen = 0; - rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, targetPvtKey, cipherText, &ulCipherTextLen) ); - CPPUNIT_ASSERT(rv==CKR_BUFFER_TOO_SMALL); - - // Do real wrapping - ulCipherTextLen = sizeof(cipherText); - rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, targetPvtKey, cipherText, &ulCipherTextLen) ); - CPPUNIT_ASSERT(rv==CKR_OK); - CPPUNIT_ASSERT(wrappedLenEstimation==ulCipherTextLen); - - rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hPrivateKey, cipherText, ulCipherTextLen, unwrapTemplate, sizeof(unwrapTemplate)/sizeof(CK_ATTRIBUTE), &unwrappedKey) ); - CPPUNIT_ASSERT(rv==CKR_OK); - CPPUNIT_ASSERT(unwrappedKey != CK_INVALID_HANDLE); - - // Verify the private key is unwrapped properly - rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &sv_mechanism, unwrappedKey) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - ulSignatureLen = sizeof(signature); - rv = CRYPTOKI_F_PTR( C_Sign(hSession, data, sizeof(data), signature, &ulSignatureLen) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - rv = CRYPTOKI_F_PTR( C_VerifyInit(hSession, &sv_mechanism, targetPubKey) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - rv = CRYPTOKI_F_PTR( C_Verify(hSession, data, sizeof(data), signature, ulSignatureLen) ); - CPPUNIT_ASSERT(rv==CKR_OK); + std::vector paramsList = { + { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA224, CKG_MGF1_SHA224, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA256, CKG_MGF1_SHA256, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA384, CKG_MGF1_SHA384, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA512, CKG_MGF1_SHA512, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA256, 0, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { 0, 0, CKZ_DATA_SPECIFIED, NULL_PTR, 0 } + }; + + for (std::vector::iterator it = paramsList.begin(); it != paramsList.end(); ++it) + { + rsa_aes_params.oaep_params = &(*it); + + // Estimate wrapped length + rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, targetPvtKey, NULL_PTR, &wrappedLenEstimation) ); + CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT(wrappedLenEstimation>0); + + // This should always fail because wrapped data have to be longer than 0 bytes + ulCipherTextLen = 0; + rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, targetPvtKey, cipherText, &ulCipherTextLen) ); + CPPUNIT_ASSERT(rv==CKR_BUFFER_TOO_SMALL); + + // Do real wrapping + ulCipherTextLen = sizeof(cipherText); + rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, targetPvtKey, cipherText, &ulCipherTextLen) ); + CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT(wrappedLenEstimation==ulCipherTextLen); + + rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hPrivateKey, cipherText, ulCipherTextLen, unwrapTemplate, sizeof(unwrapTemplate)/sizeof(CK_ATTRIBUTE), &unwrappedKey) ); + CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT(unwrappedKey != CK_INVALID_HANDLE); + + // Verify the private key is unwrapped properly + rv = CRYPTOKI_F_PTR( C_SignInit(hSession, &sv_mechanism, unwrappedKey) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + ulSignatureLen = sizeof(signature); + rv = CRYPTOKI_F_PTR( C_Sign(hSession, data, sizeof(data), signature, &ulSignatureLen) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + rv = CRYPTOKI_F_PTR( C_VerifyInit(hSession, &sv_mechanism, targetPubKey) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + rv = CRYPTOKI_F_PTR( C_Verify(hSession, data, sizeof(data), signature, ulSignatureLen) ); + CPPUNIT_ASSERT(rv==CKR_OK); + } } void AsymWrapUnwrapTests::rsaWrapUnwrap(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey) { - CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 }; - CK_RSA_PKCS_OAEP_PARAMS oaepParams = { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }; - CK_BYTE cipherText[2048]; - CK_ULONG ulCipherTextLen; - CK_BYTE symValue[64]; - CK_ULONG ulSymValueLen = sizeof(symValue); - CK_BYTE unwrappedValue[64]; - CK_ULONG ulUnwrappedValueLen = sizeof(unwrappedValue); - CK_OBJECT_HANDLE symKey = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE unwrappedKey = CK_INVALID_HANDLE; - CK_RV rv; - CK_ULONG wrappedLenEstimation; - - CK_BBOOL bFalse = CK_FALSE; - CK_BBOOL bTrue = CK_TRUE; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_AES; + CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 }; + CK_BYTE cipherText[2048]; + CK_BYTE symValue[64]; + CK_BYTE unwrappedValue[64]; + CK_RV rv; + + CK_BBOOL bFalse = CK_FALSE; + CK_BBOOL bTrue = CK_TRUE; + CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; + CK_KEY_TYPE keyType = CKK_AES; CK_ATTRIBUTE unwrapTemplate[] = { { CKA_CLASS, &keyClass, sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, @@ -212,65 +220,95 @@ void AsymWrapUnwrapTests::rsaWrapUnwrap(CK_MECHANISM_TYPE mechanismType, CK_SESS { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) } }; - CK_ATTRIBUTE valueTemplate[] = { - { CKA_VALUE, &symValue, ulSymValueLen } - }; + CK_ATTRIBUTE valueTemplate[] = { + { CKA_VALUE, symValue, sizeof(symValue) } + }; CK_MECHANISM_INFO mechInfo; - if (mechanismType == CKM_RSA_PKCS_OAEP) - { - mechanism.pParameter = &oaepParams; - mechanism.ulParameterLen = sizeof(oaepParams); - } - - if (mechanismType == CKM_RSA_AES_KEY_WRAP) - { - rsaWrapUnwrapPvt(hSession, hPublicKey, hPrivateKey); - return; - } - - // Generate temporary symmetric key and remember it's value - rv = generateAesKey(hSession, symKey); - CPPUNIT_ASSERT(rv==CKR_OK); - - rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, symKey, valueTemplate, sizeof(valueTemplate)/sizeof(CK_ATTRIBUTE)) ); - CPPUNIT_ASSERT(rv==CKR_OK); - ulSymValueLen = valueTemplate[0].ulValueLen; - - // Check if the specified mechanism supports Wrap/Unwrap - rv = CRYPTOKI_F_PTR( C_GetMechanismInfo(m_initializedTokenSlotID, mechanismType, &mechInfo) ); - CPPUNIT_ASSERT(rv==CKR_OK); - CPPUNIT_ASSERT(mechInfo.flags&CKF_WRAP); - CPPUNIT_ASSERT(mechInfo.flags&CKF_UNWRAP); - - // Estimate wrapped length - rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, symKey, NULL_PTR, &wrappedLenEstimation) ); - CPPUNIT_ASSERT(rv==CKR_OK); - CPPUNIT_ASSERT(wrappedLenEstimation>0); - - // This should always fail because wrapped data have to be longer than 0 bytes - ulCipherTextLen = 0; - rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, symKey, cipherText, &ulCipherTextLen) ); - CPPUNIT_ASSERT(rv==CKR_BUFFER_TOO_SMALL); - - // Do real wrapping - ulCipherTextLen = sizeof(cipherText); - rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, symKey, cipherText, &ulCipherTextLen) ); - CPPUNIT_ASSERT(rv==CKR_OK); - // Check length 'estimation' - CPPUNIT_ASSERT(wrappedLenEstimation>=ulCipherTextLen); - - rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hPrivateKey, cipherText, ulCipherTextLen, unwrapTemplate, sizeof(unwrapTemplate)/sizeof(CK_ATTRIBUTE), &unwrappedKey) ); - CPPUNIT_ASSERT(rv==CKR_OK); - - valueTemplate[0].pValue = &unwrappedValue; - rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, unwrappedKey, valueTemplate, sizeof(valueTemplate)/sizeof(CK_ATTRIBUTE)) ); - CPPUNIT_ASSERT(rv==CKR_OK); - ulUnwrappedValueLen = valueTemplate[0].ulValueLen; - - CPPUNIT_ASSERT(ulSymValueLen == ulUnwrappedValueLen); - CPPUNIT_ASSERT(memcmp(symValue, unwrappedValue, ulSymValueLen) == 0); + if (mechanismType == CKM_RSA_AES_KEY_WRAP) + { + rsaWrapUnwrapPvt(hSession, hPublicKey, hPrivateKey); + return; + } + + auto runWrap = [&](void) { + CK_OBJECT_HANDLE symKey = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE unwrappedKey = CK_INVALID_HANDLE; + CK_ULONG wrappedLenEstimation = 0; + CK_ULONG ulCipherTextLen = 0; + CK_ULONG ulSymValueLen = sizeof(symValue); + CK_ULONG ulUnwrappedValueLen = sizeof(unwrappedValue); + + valueTemplate[0].pValue = symValue; + valueTemplate[0].ulValueLen = ulSymValueLen; + + // Generate temporary symmetric key and remember it's value + rv = generateAesKey(hSession, symKey); + CPPUNIT_ASSERT(rv==CKR_OK); + + rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, symKey, valueTemplate, sizeof(valueTemplate)/sizeof(CK_ATTRIBUTE)) ); + CPPUNIT_ASSERT(rv==CKR_OK); + ulSymValueLen = valueTemplate[0].ulValueLen; + + // Check if the specified mechanism supports Wrap/Unwrap + rv = CRYPTOKI_F_PTR( C_GetMechanismInfo(m_initializedTokenSlotID, mechanismType, &mechInfo) ); + CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT(mechInfo.flags&CKF_WRAP); + CPPUNIT_ASSERT(mechInfo.flags&CKF_UNWRAP); + + // Estimate wrapped length + rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, symKey, NULL_PTR, &wrappedLenEstimation) ); + CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT(wrappedLenEstimation>0); + + // This should always fail because wrapped data have to be longer than 0 bytes + ulCipherTextLen = 0; + rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, symKey, cipherText, &ulCipherTextLen) ); + CPPUNIT_ASSERT(rv==CKR_BUFFER_TOO_SMALL); + + // Do real wrapping + ulCipherTextLen = sizeof(cipherText); + rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hPublicKey, symKey, cipherText, &ulCipherTextLen) ); + CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT(wrappedLenEstimation>=ulCipherTextLen); + + rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hPrivateKey, cipherText, ulCipherTextLen, unwrapTemplate, sizeof(unwrapTemplate)/sizeof(CK_ATTRIBUTE), &unwrappedKey) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + valueTemplate[0].pValue = unwrappedValue; + rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, unwrappedKey, valueTemplate, sizeof(valueTemplate)/sizeof(CK_ATTRIBUTE)) ); + CPPUNIT_ASSERT(rv==CKR_OK); + ulUnwrappedValueLen = valueTemplate[0].ulValueLen; + + CPPUNIT_ASSERT(ulSymValueLen == ulUnwrappedValueLen); + CPPUNIT_ASSERT(memcmp(symValue, unwrappedValue, ulSymValueLen) == 0); + }; + + if (mechanismType == CKM_RSA_PKCS_OAEP) + { + std::vector paramsList = { + { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA224, CKG_MGF1_SHA224, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA256, CKG_MGF1_SHA256, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA384, CKG_MGF1_SHA384, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA512, CKG_MGF1_SHA512, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { CKM_SHA256, 0, CKZ_DATA_SPECIFIED, NULL_PTR, 0 }, + { 0, 0, CKZ_DATA_SPECIFIED, NULL_PTR, 0 } + }; + for (std::vector::iterator it = paramsList.begin(); it != paramsList.end(); ++it) + { + mechanism.pParameter = &(*it); + mechanism.ulParameterLen = sizeof(*it); + runWrap(); + } + } + else + { + mechanism.pParameter = NULL_PTR; + mechanism.ulParameterLen = 0; + runWrap(); + } } void AsymWrapUnwrapTests::testRsaWrapUnwrap()