summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2015-07-07 12:10:50 +0200
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2015-07-28 02:04:59 -0700
commit8cfd51cfa09e81f89e0f35505e980206e76b06a1 (patch)
tree699b79a9861eea6ae9bfe81edb31d7f2340dcb94
parent75b51d07a869d1dfcf02c2806f9950782fd258d7 (diff)
downloadkey-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.h25
-rw-r--r--src/manager/crypto/sw-backend/internals.cpp80
-rw-r--r--src/manager/crypto/sw-backend/internals.h7
-rw-r--r--src/manager/crypto/sw-backend/key.cpp10
-rw-r--r--src/manager/crypto/sw-backend/key.h2
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: