RSA_GEN,
DSA_GEN,
ECDSA_GEN,
+ AES_GEN,
};
// cryptographic algorithm description
// encryption & decryption
CKMC_PARAM_ED_IV = 101, /**< 16B buffer (up to 2^64-1 bytes long in case of AES GCM) */
- CKMC_PARAM_ED_CTR_LEN, /**< integer */
+ CKMC_PARAM_ED_CTR_LEN, /**< integer - ctr length in bits*/
CKMC_PARAM_ED_AAD, /**< buffer */
- CKMC_PARAM_ED_TAG_LEN, /**< integer */
+ CKMC_PARAM_ED_TAG_LEN, /**< integer - tag length in bits */
CKMC_PARAM_ED_LABEL, /**< buffer */
// key generation
- CKMC_PARAM_GEN_KEY_LEN = 201, /**< integer */
+ CKMC_PARAM_GEN_KEY_LEN = 201, /**< integer - key length in bits */
CKMC_PARAM_GEN_EC, /**< integer - elliptic curve (ckmc_ec_type_e) */
// sign & verify
- CKMC_PARAM_ALGO_TYPE,
- CKMC_PARAM_GEN_KEY_LEN */
- CKMC_ALGO_ECDSA_GEN, /**< ECDA algorithm used for key generation
+ CKMC_ALGO_ECDSA_GEN, /**< ECDSA algorithm used for key generation
Supported parameters:
- CKMC_PARAM_ALGO_TYPE,
- CKMC_PARAM_GEN_EC */
+
+ CKMC_ALGO_AES_GEN, /**< AES key generation
+ Supported parameters:
+ - CKMC_PARAM_ALGO_TYPE,
+ - CKMC_PARAM_GEN_KEY_LEN */
} ckmc_algo_type_e;
/**
: m_dataType(data)
{
if (!isInRange(data))
- ThrowMsg(Exception::OutOfRange, "Invalid conversion from DataType to DBDataType");
+ ThrowMsg(Exception::OutOfRange,
+ "Invalid conversion from DataType=" << static_cast<int>(data) << " to DBDataType");
}
DataType::DataType(KeyType key) {
case KeyType::KEY_ECDSA_PRIVATE: m_dataType = DataType::KEY_ECDSA_PRIVATE; break;
case KeyType::KEY_AES: m_dataType = DataType::KEY_AES; break;
default:
- ThrowMsg(Exception::OutOfRange, "Invalid conversion from KeyType to DBDataType");
+ ThrowMsg(Exception::OutOfRange,
+ "Invalid conversion from KeyType=" << static_cast<int>(key) << " to DBDataType");
}
}
case AlgoType::AES_CTR:
case AlgoType::AES_CBC:
case AlgoType::AES_GCM:
- case AlgoType::AES_CFB: m_dataType = DataType::KEY_AES; break;
+ case AlgoType::AES_CFB:
+ case AlgoType::AES_GEN: m_dataType = DataType::KEY_AES; break;
+ case AlgoType::RSA_SV:
+ case AlgoType::RSA_OAEP:
case AlgoType::RSA_GEN: m_dataType = DataType::KEY_RSA_PUBLIC; break;
+ case AlgoType::DSA_SV:
case AlgoType::DSA_GEN: m_dataType = DataType::KEY_DSA_PUBLIC; break;
+ case AlgoType::ECDSA_SV:
case AlgoType::ECDSA_GEN: m_dataType = DataType::KEY_ECDSA_PUBLIC; break;
default:
- ThrowMsg(Exception::OutOfRange, "Invalid conversion from AlgoType to DBDataType");
+ ThrowMsg(Exception::OutOfRange,
+ "Invalid conversion from AlgoType=" << static_cast<int>(algorithmType) <<
+ " to DBDataType");
}
}
: m_dataType(static_cast<Type>(data))
{
if (!isInRange(data))
- ThrowMsg(Exception::OutOfRange, "Invalid conversion from int to DBDataType");
+ ThrowMsg(Exception::OutOfRange, "Invalid conversion from int=" << data << " to DBDataType");
}
DataType::operator int () const {
case DataType::KEY_ECDSA_PUBLIC: return KeyType::KEY_ECDSA_PUBLIC;
case DataType::KEY_AES: return KeyType::KEY_AES;
default:
- ThrowMsg(Exception::OutOfRange, "Invalid conversion from DBDataType to KeyType");
+ ThrowMsg(Exception::OutOfRange,
+ "Invalid conversion from DBDataType=" << static_cast<int>(m_dataType) <<
+ " to KeyType" );
}
}
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file algo-validation.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ */
+
+#pragma once
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include <ckm/ckm-type.h>
+
+#include <exception.h>
+
+namespace CKM {
+namespace Crypto {
+
+template<typename T>
+T unpack(
+ const CryptoAlgorithm &alg,
+ ParamName paramName)
+{
+ T result;
+ if (!alg.getParam(paramName, result)) {
+ ThrowErr(Exc::Crypto::InputParam, "Wrong input param");
+ }
+ return result;
+}
+
+
+////////// Validators //////////////
+
+// Always validates as true. Useful for checking parameter existence only
+template <typename T>
+struct DefaultValidator {
+ static bool Check(const T&) { return true; }
+ static void Why(std::ostringstream& os) { os << "is ok"; }
+};
+
+// Validates as true if parameter value is equal to one of Args
+template <typename T>
+struct Type {
+ template <T ...Args>
+ struct Equals;
+
+ template <T First>
+ struct Equals<First> {
+ public:
+ static bool Check(const T& value) {
+ return First == value;
+ }
+ static void Why(std::ostringstream& os) {
+ os << "doesn't match " << static_cast<int>(First);
+ }
+ };
+
+ template <T First, T ...Args>
+ struct Equals<First, Args...> : public Equals<First>, public Equals<Args...> {
+ public:
+ static bool Check(const T& value) {
+ return Equals<First>::Check(value) || Equals<Args...>::Check(value);
+ }
+ static void Why(std::ostringstream& os) {
+ Equals<First>::Why(os);
+ os << ", ";
+ Equals<Args...>::Why(os);
+ }
+ };
+};
+
+
+////////// Getters //////////////
+
+// simply returns parameter value
+template <typename T>
+struct DefaultGetter {
+ static T Get(const T& value) { return value; }
+ static void What(std::ostringstream& os) { os << "value"; }
+};
+
+// 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"; }
+};
+
+
+////////// ErrorHandlers //////////////
+
+struct ThrowingHandler {
+ static void Handle(std::string message) {
+ ThrowErr(Exc::Crypto::InputParam, message);
+ }
+};
+
+
+// base class for parameter check
+struct ParamCheckBase {
+ virtual ~ParamCheckBase() {}
+ virtual void Check(const CryptoAlgorithm& ca) const = 0;
+};
+
+typedef std::unique_ptr<const ParamCheckBase> ParamCheckBasePtr;
+
+typedef std::vector<ParamCheckBasePtr> ValidatorVector;
+
+
+// ValidatorVector builder. Creates a vector of ParamCheckBasePtr's specified as Args
+template <typename ...Args>
+struct VBuilder;
+
+template <typename First>
+struct VBuilder<First> {
+static ValidatorVector Build() {
+ ValidatorVector validators;
+ Add(validators);
+ return validators;
+ }
+protected:
+ static void Add(ValidatorVector& validators) {
+ validators.emplace_back(new First);
+ }
+};
+
+template <typename First, typename ...Args>
+struct VBuilder<First, Args...> : public VBuilder<First>, public VBuilder<Args...> {
+ static ValidatorVector Build() {
+ ValidatorVector validators;
+ Add(validators);
+ return validators;
+ }
+protected:
+ static void Add(ValidatorVector& validators) {
+ VBuilder<First>::Add(validators);
+ VBuilder<Args...>::Add(validators);
+ }
+};
+
+/*
+ * Generic struct responsible for checking a single constraint on given algorithm parameter
+ *
+ * Name - name of param to check
+ * Type - type of param value
+ * Mandatory - true if param is mandatory
+ * Validator - class providing validation function bool Check(const CryptoAlgorithm&)
+ * Getter - gets the value used for validation (param value itself or a buffer size for example)
+ * ErrorHandler - class providing method for error handling void Handle(std::string)
+ */
+
+template <ParamName Name,
+ typename Type,
+ bool Mandatory,
+ typename Validator = DefaultValidator<Type>,
+ typename Getter = DefaultGetter<Type>,
+ typename ErrorHandler = ThrowingHandler>
+struct ParamCheck : public ParamCheckBase {
+ void Check(const CryptoAlgorithm& ca) const {
+ Type value;
+ std::ostringstream os;
+
+ // check existence
+ if(!ca.getParam(Name,value)) {
+ if (Mandatory) {
+ os << "Mandatory parameter " << static_cast<int>(Name) << " doesn't exist";
+ ErrorHandler::Handle(os.str());
+ }
+ return;
+ }
+ // validate
+ if(!Validator::Check(Getter::Get(value))) {
+ os << "The ";
+ Getter::What(os);
+ os << " of param '" << static_cast<int>(Name) << "'=" <<
+ static_cast<int>(Getter::Get(value)) << " ";
+ Validator::Why(os);
+ ErrorHandler::Handle(os.str());
+ }
+ }
+};
+
+} // namespace Crypto
+} // namespace CKM
#include <exception>
#include <fstream>
#include <utility>
+#include <algorithm>
#include <openssl/evp.h>
#include <openssl/obj_mac.h>
#include <dpl/log/log.h>
#include <generic-backend/exception.h>
+#include <generic-backend/algo-validation.h>
#include <sw-backend/internals.h>
#include <sw-backend/crypto.h>
#define DEV_HW_RANDOM_FILE "/dev/hwrng"
#define DEV_URANDOM_FILE "/dev/urandom"
+namespace CKM {
+namespace Crypto {
+namespace SW {
+namespace Internals {
+
namespace {
typedef std::unique_ptr<EVP_MD_CTX, std::function<void(EVP_MD_CTX*)>> EvpMdCtxUPtr;
typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX*)>> EvpPkeyCtxUPtr;
typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
typedef int(*I2D_CONV)(BIO*, EVP_PKEY*);
-CKM::RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) {
+
+const size_t DEFAULT_AES_GCM_TAG_LEN = 128; // tag length in bits according to W3C Crypto API
+const size_t DEFAULT_AES_IV_LEN = 16; // default iv size in bytes for AES
+
+RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) {
BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
if (NULL == pkey) {
- ThrowErr(CKM::Exc::Crypto::InternalError, "attempt to parse an empty key!");
+ ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!");
}
if (NULL == bio.get()) {
- ThrowErr(CKM::Exc::Crypto::InternalError, "Error in memory allocation! Function: BIO_new.");
+ ThrowErr(Exc::Crypto::InternalError, "Error in memory allocation! Function: BIO_new.");
}
if (1 != fun(bio.get(), pkey)) {
- ThrowErr(CKM::Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER");
+ ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER");
}
- CKM::RawBuffer output(8196);
+ RawBuffer output(8196);
int size = BIO_read(bio.get(), output.data(), output.size());
if (size <= 0) {
- ThrowErr(CKM::Exc::Crypto::InternalError, "Error in BIO_read: ", size);
+ ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size);
}
output.resize(size);
return output;
}
-template<typename T>
-T unpack(
- const CKM::CryptoAlgorithm &alg,
- CKM::ParamName paramName)
+// encryption / decryption
+typedef ParamCheck<ParamName::ALGO_TYPE,
+ AlgoType,
+ true,
+ Type<AlgoType>::Equals<AlgoType::AES_CTR,
+ AlgoType::AES_CBC,
+ AlgoType::AES_GCM,
+ AlgoType::AES_CFB,
+ AlgoType::RSA_OAEP>> IsEncryption;
+
+typedef ParamCheck<ParamName::ED_IV,
+ RawBuffer,
+ true,
+ Type<size_t>::Equals<DEFAULT_AES_IV_LEN>,
+ BufferSizeGetter> IvSizeCheck;
+
+typedef ParamCheck<ParamName::ED_CTR_LEN,
+ int,
+ false,
+ Type<int>::Equals<128>> CtrLenCheck;
+
+typedef ParamCheck<ParamName::ED_IV,
+ RawBuffer,
+ true,
+ DefaultValidator<size_t>,
+ BufferSizeGetter> GcmIvCheck;
+
+typedef ParamCheck<ParamName::ED_TAG_LEN,
+ int,
+ false,
+ Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck;
+
+// sign / verify
+typedef ParamCheck<ParamName::ALGO_TYPE,
+ AlgoType,
+ false,
+ Type<AlgoType>::Equals<AlgoType::RSA_SV,
+ AlgoType::DSA_SV,
+ AlgoType::ECDSA_SV>> IsSignVerify;
+
+typedef ParamCheck<ParamName::SV_HASH_ALGO,
+ HashAlgorithm,
+ false,
+ Type<HashAlgorithm>::Equals<HashAlgorithm::NONE,
+ HashAlgorithm::SHA1,
+ HashAlgorithm::SHA256,
+ HashAlgorithm::SHA384,
+ HashAlgorithm::SHA512>> HashAlgoCheck;
+
+typedef ParamCheck<ParamName::SV_RSA_PADDING,
+ RSAPaddingAlgorithm,
+ false,
+ Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE,
+ RSAPaddingAlgorithm::PKCS1,
+ RSAPaddingAlgorithm::X931>> RsaPaddingCheck;
+
+// key generation
+typedef ParamCheck<ParamName::ALGO_TYPE,
+ AlgoType,
+ true,
+ Type<AlgoType>::Equals<AlgoType::RSA_GEN,
+ AlgoType::DSA_GEN,
+ AlgoType::ECDSA_GEN>> IsAsymGeneration;
+
+typedef ParamCheck<ParamName::ALGO_TYPE,
+ AlgoType,
+ true,
+ Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration;
+
+typedef ParamCheck<ParamName::GEN_KEY_LEN,
+ int,
+ true,
+ Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck;
+
+typedef ParamCheck<ParamName::GEN_KEY_LEN,
+ int,
+ true,
+ Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck;
+
+typedef ParamCheck<ParamName::GEN_KEY_LEN,
+ int,
+ true,
+ Type<int>::Equals<128, 192, 256>> AesKeyLenCheck;
+
+typedef ParamCheck<ParamName::GEN_EC,
+ ElipticCurve,
+ true,
+ Type<ElipticCurve>::Equals<ElipticCurve::prime192v1,
+ ElipticCurve::prime256v1,
+ ElipticCurve::secp384r1>> EcdsaEcCheck;
+
+typedef std::map<AlgoType, ValidatorVector> ValidatorMap;
+ValidatorMap initValidators() {
+ ValidatorMap validators;
+ validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
+ validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build());
+ validators.emplace(AlgoType::DSA_SV, VBuilder<HashAlgoCheck>::Build());
+ validators.emplace(AlgoType::ECDSA_SV, VBuilder<HashAlgoCheck>::Build());
+ validators.emplace(AlgoType::RSA_GEN, VBuilder<RsaKeyLenCheck>::Build());
+ validators.emplace(AlgoType::DSA_GEN, VBuilder<DsaKeyLenCheck>::Build());
+ validators.emplace(AlgoType::ECDSA_GEN, VBuilder<EcdsaEcCheck>::Build());
+ validators.emplace(AlgoType::AES_GEN, VBuilder<AesKeyLenCheck>::Build());
+ validators.emplace(AlgoType::AES_CTR, VBuilder<IvSizeCheck, CtrLenCheck>::Build());
+ 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());
+ return validators;
+};
+ValidatorMap g_validators = initValidators();
+
+template <typename TypeCheck>
+void validateParams(const CryptoAlgorithm& ca)
{
- T result;
- if (!alg.getParam(paramName, result)) {
- ThrowErr(CKM::Exc::Crypto::InputParam, "Wrong input param");
+ // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation)
+ TypeCheck tc;
+ tc.Check(ca);
+
+ AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE);
+ for(const auto& validator : g_validators.at(at)) {
+ validator->Check(ca);
}
- return result;
}
} // anonymous namespace
-namespace CKM {
-namespace Crypto {
-namespace SW {
-namespace Internals {
-
int initialize() {
int hw_rand_ret = 0;
int u_rand_ret = 0;
return Token(backendId, DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key+sizeBytes));
}
+TokenPair generateAKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
+{
+ validateParams<IsAsymGeneration>(algorithm);
+
+ AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE);
+ if(keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN)
+ {
+ int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
+ if(keyType == AlgoType::RSA_GEN)
+ return createKeyPairRSA(backendId, keyLength);
+ else
+ return createKeyPairDSA(backendId, keyLength);
+ }
+ else // AlgoType::ECDSA_GEN
+ {
+ ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
+ return createKeyPairECDSA(backendId, ecType);
+ }
+}
+
+Token generateSKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm)
+{
+ validateParams<IsSymGeneration>(algorithm);
+
+ int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN);
+ return createKeyAES(backendId, keySizeBits);
+}
+
RawBuffer encryptDataAesCbc(
const RawBuffer &key,
const RawBuffer &data,
const CryptoAlgorithm &alg,
const RawBuffer &data)
{
+ validateParams<IsEncryption>(alg);
AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
switch(keyType)
case AlgoType::AES_CBC:
return encryptDataAesCbc(key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
case AlgoType::AES_GCM:
- return encryptDataAesGcmPacked(key, data, unpack<RawBuffer>(alg, ParamName::ED_IV),
- unpack<int>(alg, ParamName::ED_TAG_LEN));
+ {
+ int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
+ alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
+ return encryptDataAesGcmPacked(key,
+ data,
+ unpack<RawBuffer>(alg, ParamName::ED_IV),
+ tagLenBits/8);
+ }
default:
break;
}
const CryptoAlgorithm &alg,
const RawBuffer &data)
{
+ validateParams<IsEncryption>(alg);
AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
switch(keyType)
case AlgoType::AES_CBC:
return decryptDataAesCbc(key, data, unpack<RawBuffer>(alg, ParamName::ED_IV));
case AlgoType::AES_GCM:
- return decryptDataAesGcmPacked(key, data, unpack<RawBuffer>(alg, ParamName::ED_IV),
- unpack<int>(alg, ParamName::ED_TAG_LEN));
+ {
+ int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
+ alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
+ return decryptDataAesGcmPacked(key,
+ data,
+ unpack<RawBuffer>(alg, ParamName::ED_IV),
+ tagLenBits/8);
+ }
default:
break;
}
const CryptoAlgorithm &alg,
const RawBuffer &message)
{
+ validateParams<IsSignVerify>(alg);
+
int rsa_padding = NOT_DEFINED;
const EVP_MD *md_algo = NULL;
const RawBuffer &message,
const RawBuffer &signature)
{
+ validateParams<IsSignVerify>(alg);
+
int rsa_padding = NOT_DEFINED;
const EVP_MD *md_algo = NULL;
TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type1);
Token createKeyAES(CryptoBackend backendId, const int sizeBits);
+TokenPair generateAKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm);
+Token generateSKey(CryptoBackend backendId, const CryptoAlgorithm &algorithm);
+
RawBuffer symmetricEncrypt(const RawBuffer &key,
const CryptoAlgorithm &alg,
const RawBuffer &data);
std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(const RawBuffer &key,
const RawBuffer &data,
const RawBuffer &iv,
- int tagSize);
+ int tagSizeBits);
RawBuffer decryptDataAesGcm(const RawBuffer &key,
const RawBuffer &data,
namespace Crypto {
namespace SW {
+namespace {
+
+AlgoType key2algo(DataType type) {
+ switch(static_cast<int>(type)) {
+ case DataType::Type::KEY_RSA_PRIVATE:
+ case DataType::Type::KEY_RSA_PUBLIC:
+ return AlgoType::RSA_SV;
+ case DataType::Type::KEY_DSA_PRIVATE:
+ case DataType::Type::KEY_DSA_PUBLIC:
+ return AlgoType::DSA_SV;
+ case DataType::Type::KEY_ECDSA_PRIVATE:
+ case DataType::Type::KEY_ECDSA_PUBLIC:
+ return AlgoType::ECDSA_SV;
+ default:
+ ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", type);
+ }
+}
+
+} // namespace anonymous
+
typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
RawBuffer SKey::getBinary() const {
const CryptoAlgorithm &alg,
const RawBuffer &message)
{
- return Internals::sign(getEvpShPtr().get(), alg, message);
+ CryptoAlgorithm algWithType(alg);
+ algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type));
+ return Internals::sign(getEvpShPtr().get(), algWithType, message);
}
RawBuffer AKey::getBinary() const {
}
int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign) {
- return Internals::verify(getEvpShPtr().get(), alg, message, sign);
+ CryptoAlgorithm algWithType(alg);
+ EVP_PKEY* evp = getEvpShPtr().get();
+ AlgoType type;
+
+ // setup algorithm type basing on evp key type if it doesn't exist
+ if(!algWithType.getParam(ParamName::ALGO_TYPE, type)) {
+ int subType = EVP_PKEY_type(evp->type);
+ switch(subType) {
+ case EVP_PKEY_RSA:
+ type = AlgoType::RSA_SV; break;
+ case EVP_PKEY_DSA:
+ type = AlgoType::DSA_SV; break;
+ case EVP_PKEY_EC:
+ type = AlgoType::ECDSA_SV; break;
+ default:
+ ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", subType);
+ }
+ algWithType.setParam(ParamName::ALGO_TYPE, type);
+ }
+ return Internals::verify(evp, algWithType, message, sign);
}
EvpShPtr AKey::getEvpShPtr() {
TokenPair Store::generateAKey(const CryptoAlgorithm &algorithm)
{
- AlgoType keyType = AlgoType::RSA_GEN;
- algorithm.getParam(ParamName::ALGO_TYPE, keyType);
-
- if(keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN)
- {
- int keyLength = 0;
- if(!algorithm.getParam(ParamName::GEN_KEY_LEN, keyLength))
- ThrowErr(Exc::Crypto::InputParam, "Error, parameter GEN_KEY_LEN not found.");
-
- if(keyType == AlgoType::RSA_GEN)
- return Internals::createKeyPairRSA(m_backendId, keyLength);
- else
- return Internals::createKeyPairDSA(m_backendId, keyLength);
- }
- else if(keyType == AlgoType::ECDSA_GEN)
- {
- int ecType = 0;
- if(!algorithm.getParam(ParamName::GEN_EC, ecType))
- ThrowErr(Exc::Crypto::InputParam, "Error, parameter GEN_EC not found.");
-
- return Internals::createKeyPairECDSA(m_backendId, static_cast<ElipticCurve>(ecType));
- }
- ThrowErr(Exc::Crypto::InputParam, "wrong key type");
+ return Internals::generateAKey(m_backendId, algorithm);
}
Token Store::generateSKey(const CryptoAlgorithm &algorithm)
{
- int keyLength = 0;
- if(!algorithm.getParam(ParamName::GEN_KEY_LEN, keyLength))
- ThrowErr(Exc::Crypto::InputParam, "Error, parameter GEN_KEY_LEN not found.");
-
- return Internals::createKeyAES(m_backendId, keyLength);
+ return Internals::generateSKey(m_backendId, algorithm);
}
Token Store::import(DataType dataType, const RawBuffer &buffer) {
const PolicySerializable &policy)
{
CryptoAlgorithm keyGenAlgorithm;
+ keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm);