diff options
author | Krzysztof Jackiewicz <k.jackiewicz@samsung.com> | 2015-07-07 12:10:50 +0200 |
---|---|---|
committer | Krzysztof Jackiewicz <k.jackiewicz@samsung.com> | 2015-07-28 02:04:59 -0700 |
commit | 8cfd51cfa09e81f89e0f35505e980206e76b06a1 (patch) | |
tree | 699b79a9861eea6ae9bfe81edb31d7f2340dcb94 | |
parent | 75b51d07a869d1dfcf02c2806f9950782fd258d7 (diff) | |
download | key-manager-8cfd51cfa09e81f89e0f35505e980206e76b06a1.tar.gz key-manager-8cfd51cfa09e81f89e0f35505e980206e76b06a1.tar.bz2 key-manager-8cfd51cfa09e81f89e0f35505e980206e76b06a1.zip |
Add RSA OAEP support
[Feature] Encryption service development
[Solution] Add support for RSA OAEP encryption/decryption
[Verification] Run ckm-tests --group=CKM_ENCRYPTION_DECRYPTION
Change-Id: Ieb78fcb65fbd6e2042c2b7effe1ef7b66429fcbd
-rw-r--r-- | src/manager/crypto/generic-backend/algo-validation.h | 25 | ||||
-rw-r--r-- | src/manager/crypto/sw-backend/internals.cpp | 80 | ||||
-rw-r--r-- | src/manager/crypto/sw-backend/internals.h | 7 | ||||
-rw-r--r-- | src/manager/crypto/sw-backend/key.cpp | 10 | ||||
-rw-r--r-- | src/manager/crypto/sw-backend/key.h | 2 |
5 files changed, 111 insertions, 13 deletions
diff --git a/src/manager/crypto/generic-backend/algo-validation.h b/src/manager/crypto/generic-backend/algo-validation.h index c8abc724..69dd95d9 100644 --- a/src/manager/crypto/generic-backend/algo-validation.h +++ b/src/manager/crypto/generic-backend/algo-validation.h @@ -85,6 +85,12 @@ struct Type { }; }; +template <typename T> +struct Unsupported { + static bool Check(const T&) { return false; } + static void Why(std::ostringstream& os) { os << "is not supported"; } +}; + ////////// Getters ////////////// @@ -93,12 +99,19 @@ template <typename T> struct DefaultGetter { static T Get(const T& value) { return value; } static void What(std::ostringstream& os) { os << "value"; } + static void Print(std::ostringstream& os, const T& value) { os << static_cast<int>(value); } }; +template <> +void DefaultGetter<RawBuffer>::Print(std::ostringstream& os, const RawBuffer& buffer) { + os << "[" << buffer.size() << "B buffer]"; +} + // returns buffer param size struct BufferSizeGetter { static size_t Get(const RawBuffer& buffer) { return buffer.size(); } static void What(std::ostringstream& os) { os << "buffer size"; } + static void Print(std::ostringstream& os, const RawBuffer& buffer) { os << buffer.size(); } }; @@ -126,6 +139,13 @@ typedef std::vector<ParamCheckBasePtr> ValidatorVector; template <typename ...Args> struct VBuilder; +template <> +struct VBuilder<> { +static ValidatorVector Build() { + return ValidatorVector(); + } +}; + template <typename First> struct VBuilder<First> { static ValidatorVector Build() { @@ -187,8 +207,9 @@ struct ParamCheck : public ParamCheckBase { if(!Validator::Check(Getter::Get(value))) { os << "The "; Getter::What(os); - os << " of param '" << static_cast<int>(Name) << "'=" << - static_cast<int>(Getter::Get(value)) << " "; + os << " of param '" << static_cast<int>(Name) << "'="; + Getter::Print(os, value); + os << " "; Validator::Why(os); ErrorHandler::Handle(os.str()); } diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index df9fbb7b..3875c2b0 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -96,8 +96,12 @@ typedef ParamCheck<ParamName::ALGO_TYPE, Type<AlgoType>::Equals<AlgoType::AES_CTR, AlgoType::AES_CBC, AlgoType::AES_GCM, - AlgoType::AES_CFB, - AlgoType::RSA_OAEP>> IsEncryption; + AlgoType::AES_CFB>> IsSymEncryption; + +typedef ParamCheck<ParamName::ALGO_TYPE, + AlgoType, + true, + Type<AlgoType>::Equals<AlgoType::RSA_OAEP>> IsAsymEncryption; typedef ParamCheck<ParamName::ED_IV, RawBuffer, @@ -113,14 +117,18 @@ typedef ParamCheck<ParamName::ED_CTR_LEN, typedef ParamCheck<ParamName::ED_IV, RawBuffer, true, - DefaultValidator<size_t>, - BufferSizeGetter> GcmIvCheck; + DefaultValidator<RawBuffer>> GcmIvCheck; typedef ParamCheck<ParamName::ED_TAG_LEN, int, false, Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck; +typedef ParamCheck<ParamName::ED_LABEL, + RawBuffer, + false, + Unsupported<RawBuffer>> RsaLabelCheck; + // sign / verify typedef ParamCheck<ParamName::ALGO_TYPE, AlgoType, @@ -195,6 +203,7 @@ ValidatorMap initValidators() { validators.emplace(AlgoType::AES_CBC, VBuilder<IvSizeCheck>::Build()); validators.emplace(AlgoType::AES_CFB, VBuilder<IvSizeCheck>::Build()); validators.emplace(AlgoType::AES_GCM, VBuilder<GcmIvCheck, GcmTagCheck>::Build()); + validators.emplace(AlgoType::RSA_OAEP, VBuilder<RsaLabelCheck>::Build()); return validators; }; ValidatorMap g_validators = initValidators(); @@ -207,8 +216,11 @@ void validateParams(const CryptoAlgorithm& ca) tc.Check(ca); AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE); - for(const auto& validator : g_validators.at(at)) { - validator->Check(ca); + try { + for(const auto& validator : g_validators.at(at)) + validator->Check(ca); + } catch(const std::out_of_range&) { + ThrowErr(Exc::Crypto::InputParam, "Unsupported algorithm ", static_cast<int>(at)); } } @@ -279,6 +291,39 @@ InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = } } + +RawBuffer asymmetricHelper(int (*cryptoFn)(int, const unsigned char*, unsigned char*, RSA*, int), + const std::string logPrefix, + const EvpShPtr &pkey, + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + validateParams<IsAsymEncryption>(alg); + + RSA* rsa = EVP_PKEY_get1_RSA(pkey.get()); + if (!rsa) + ThrowErr(Exc::Crypto::InputParam, logPrefix, "invalid key"); + + /* + * RSA_padding_add_PKCS1_OAEP supports custom label but RSA_public_encrypt calls it with NULL + * value so for now label is not supported. Alternative is to rewrite the openssl implementation + * to support it: openssl-fips/crypto/rsa/rsa_eay.c + */ + RawBuffer output; + output.resize(RSA_size(rsa)); + int ret = cryptoFn(data.size(), + data.data(), + output.data(), + rsa, + RSA_PKCS1_OAEP_PADDING); + RSA_free(rsa); + if (ret < 0) + ThrowErr(Exc::Crypto::InternalError, logPrefix, "failed"); + + output.resize(ret); + return output; +} + } // anonymous namespace const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) { @@ -625,7 +670,7 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, const CryptoAlgorithm &alg, const RawBuffer &data) { - validateParams<IsEncryption>(alg); + validateParams<IsSymEncryption>(alg); AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE); switch(keyType) @@ -649,15 +694,14 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, default: break; } - ThrowErr(Exc::Crypto::OperationNotSupported, - "symmetric enc error: algorithm not recognized"); + ThrowErr(Exc::Crypto::OperationNotSupported, "symmetric enc: algorithm not recognized"); } RawBuffer symmetricDecrypt(const RawBuffer &key, const CryptoAlgorithm &alg, const RawBuffer &data) { - validateParams<IsEncryption>(alg); + validateParams<IsSymEncryption>(alg); AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE); switch(keyType) @@ -681,7 +725,21 @@ RawBuffer symmetricDecrypt(const RawBuffer &key, default: break; } - ThrowErr(Exc::Crypto::InputParam, "symmetric dec error: algorithm not recognized"); + ThrowErr(Exc::Crypto::InputParam, "symmetric dec: algorithm not recognized"); +} + +RawBuffer asymmetricEncrypt(const EvpShPtr &pkey, + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + return asymmetricHelper(RSA_public_encrypt, "Asymmetric encryption: ", pkey, alg, data); +} + +RawBuffer asymmetricDecrypt(const EvpShPtr &pkey, + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + return asymmetricHelper(RSA_private_decrypt, "Asymmetric decryption: ", pkey, alg, data); } RawBuffer sign(EVP_PKEY *pkey, diff --git a/src/manager/crypto/sw-backend/internals.h b/src/manager/crypto/sw-backend/internals.h index 4d810d53..c71d106b 100644 --- a/src/manager/crypto/sw-backend/internals.h +++ b/src/manager/crypto/sw-backend/internals.h @@ -25,6 +25,7 @@ #include <ckm/ckm-type.h> #include <openssl/evp.h> #include <token.h> +#include <sw-backend/key.h> #define EVP_SUCCESS 1 // DO NOTCHANGE THIS VALUE #define EVP_FAIL 0 // DO NOTCHANGE THIS VALUE @@ -53,6 +54,12 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, RawBuffer symmetricDecrypt(const RawBuffer &key, const CryptoAlgorithm &alg, const RawBuffer &cipher); +RawBuffer asymmetricEncrypt(const EvpShPtr &key, + const CryptoAlgorithm &alg, + const RawBuffer &data); +RawBuffer asymmetricDecrypt(const EvpShPtr &key, + const CryptoAlgorithm &alg, + const RawBuffer &data); std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(const RawBuffer &key, const RawBuffer &data, diff --git a/src/manager/crypto/sw-backend/key.cpp b/src/manager/crypto/sw-backend/key.cpp index 7ff0ebbc..b1e57ff0 100644 --- a/src/manager/crypto/sw-backend/key.cpp +++ b/src/manager/crypto/sw-backend/key.cpp @@ -108,6 +108,16 @@ int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, const Raw return Internals::verify(evp, algWithType, message, sign); } +RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data) +{ + return Internals::asymmetricEncrypt(getEvpShPtr(), alg, data); +} + +RawBuffer AKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &data) +{ + return Internals::asymmetricDecrypt(getEvpShPtr(), alg, data); +} + EvpShPtr AKey::getEvpShPtr() { if (m_evp) return m_evp; diff --git a/src/manager/crypto/sw-backend/key.h b/src/manager/crypto/sw-backend/key.h index df331ec5..d5b7bfe0 100644 --- a/src/manager/crypto/sw-backend/key.h +++ b/src/manager/crypto/sw-backend/key.h @@ -56,6 +56,8 @@ public: {} virtual RawBuffer sign(const CryptoAlgorithm &alg, const RawBuffer &message); virtual int verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign); + virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &); + virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &); virtual RawBuffer getBinary() const; virtual ~AKey(){} protected: |