%if "%{build_type}" == "COVERAGE"
BuildRequires: lcov
%endif
+BuildRequires: liboqs
%{?systemd_requires}
static KeyShPtr createAES(
const RawBuffer &rawBuffer);
+
+ static KeyShPtr createKEM(
+ const KeyType &type,
+ const RawBuffer &rawBuffer,
+ const Password &password = Password());
};
} // namespace CKM
const Policy &policyPrivateKey = Policy(),
const Policy &policyPublicKey = Policy());
+ int createKeyPairKEM(
+ const KemType type,
+ const Alias &privateKeyAlias,
+ const Alias &publicKeyAlias,
+ const Policy &policyPrivateKey = Policy(),
+ const Policy &policyPublicKey = Policy());
+
int createKeyAES(
const int size, // size in bits [128, 192, 256]
const Alias &keyAlias,
KEY_ECDSA_PRIVATE,
KEY_DSA_PUBLIC,
KEY_DSA_PRIVATE,
- KEY_AES
+ KEY_AES,
+ KEY_KEM_PUBLIC,
+ KEY_KEM_PRIVATE,
};
enum class DataFormat : int {
secp384r1
};
+enum class KemType : int {
+ ML_KEM_768 = 0,
+ ML_KEM_1024,
+};
+
enum class CertificateFieldId : int {
ISSUER = 0,
SUBJECT
KBKDF_LLEN,
KBKDF_NO_SEPARATOR,
ECDH_PUBKEY,
+ GEN_KEM_TYPE,
// special values marking valid values range
FIRST = ALGO_TYPE,
- LAST = ECDH_PUBKEY
+ LAST = GEN_KEM_TYPE
};
// algorithm types (ALGO_TYPE param)
DSA_GEN,
ECDSA_GEN,
AES_GEN,
+ KEM_GEN,
};
// cryptographic algorithm description
* @since_tizen 2.3
* @remarks %http://tizen.org/privilege/keymanager (public level privilege) is no longer required to
* use this function since 3.0.
- * @remarks Currently API supports seven types of keys. These are RSA public/private key,
- * DSA public/private key, ECDSA public/private key, and AES symmetric key.
+ * @remarks Currently API supports nine types of keys. These are RSA public/private key,
+ * DSA public/private key, ECDSA public/private key, KEM public/private key and
+ * AES symmetric key.
* @remarks key_type in key may be set to #CKMC_KEY_NONE as an input. key_type is determined inside
* key manager during storing keys.
* @remarks Some private key files are protected by a password. If raw_key in key read from those
TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER_COMMON}
${COMMON_DEP_LIBRARIES}
+ liboqs.a
)
##########################################################################
return CKMC_ERROR_INVALID_PARAMETER;
ckmKey = CKM::Key::createAES(buffer);
+ } else if (key.key_type == CKMC_KEY_KEM_PRIVATE) {
+ ckmKey = CKM::Key::createKEM(CKM::KeyType::KEY_KEM_PRIVATE, buffer, _tostring(key.password));
+ } else if (key.key_type == CKMC_KEY_KEM_PUBLIC) {
+ ckmKey = CKM::Key::createKEM(CKM::KeyType::KEY_KEM_PUBLIC, buffer, _tostring(key.password));
} else {
ckmKey = CKM::Key::create(buffer, _tostring(key.password));
}
const ckmc_policy_s policy_private_key,
const ckmc_policy_s policy_public_key)
{
- (void) kem_type;
- (void) private_key_alias;
- (void) public_key_alias;
- (void) policy_private_key;
- (void) policy_public_key;
+ EXCEPTION_GUARD_START_CAPI
- return CKMC_ERROR_NONE;
+ if (private_key_alias == nullptr || public_key_alias == nullptr)
+ return CKMC_ERROR_INVALID_PARAMETER;
+
+ auto mgr = CKM::Manager::create();
+ return to_ckmc_error(mgr->createKeyPairKEM(
+ static_cast<CKM::KemType>(static_cast<int>(kem_type)),
+ CKM::Alias(private_key_alias),
+ CKM::Alias(public_key_alias),
+ _toCkmPolicy(policy_private_key),
+ _toCkmPolicy(policy_public_key)));
+
+ EXCEPTION_GUARD_END
}
KEY_MANAGER_CAPI
(void) new_key_policy;
return CKMC_ERROR_NONE;
-}
\ No newline at end of file
+}
if (retCode != CKM_API_SUCCESS)
return retCode;
- KeyShPtr keyParsed = recvDataType.isSymmetricKey() ? Key::createAES(rawData) : Key::create(rawData);
+ KeyShPtr keyParsed = nullptr;
+ if (recvDataType.isSymmetricKey())
+ keyParsed = Key::createAES(rawData);
+ else if (recvDataType.isKemPrivateKey())
+ keyParsed = Key::createKEM(KeyType::KEY_KEM_PRIVATE, rawData);
+ else if (recvDataType.isKemPublicKey())
+ keyParsed = Key::createKEM(KeyType::KEY_KEM_PUBLIC, rawData);
+ else
+ keyParsed = Key::create(rawData);
if (!keyParsed) {
LogDebug("Key empty - failed to parse!");
EXCEPTION_GUARD_END
}
+int Manager::Impl::createKeyPairKEM(
+ const KemType type,
+ const Alias &privateKeyAlias,
+ const Alias &publicKeyAlias,
+ const Policy &policyPrivateKey,
+ const Policy &policyPublicKey)
+{
+ return this->createKeyPair(CKM::KeyType::KEY_KEM_PUBLIC,
+ static_cast<int>(type), privateKeyAlias, publicKeyAlias,
+ policyPrivateKey, policyPublicKey);
+}
int Manager::Impl::createKeyPair(
const KeyType key_type,
keyGenAlgorithm.setParam(ParamName::GEN_EC, additional_param);
break;
+ case KeyType::KEY_KEM_PUBLIC:
+ case KeyType::KEY_KEM_PRIVATE:
+ keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::KEM_GEN);
+ keyGenAlgorithm.setParam(ParamName::GEN_KEM_TYPE, additional_param);
+ break;
+
default:
return CKM_API_ERROR_INPUT_PARAM;
}
AliasSupport privateHelper(privateKeyAlias);
AliasSupport publicHelper(publicKeyAlias);
-
- return Request(*this, LogicCommand::CREATE_KEY_PAIR, m_storageConnection,
+ if (key_type == KeyType::KEY_KEM_PUBLIC || key_type == KeyType::KEY_KEM_PRIVATE) {
+ return Request(*this, LogicCommand::CREATE_KEY_PAIR_KEM, m_extendedConnection,
+ CryptoAlgorithmSerializable(keyGenAlgorithm),
+ privateHelper.getName(), privateHelper.getOwner(),
+ publicHelper.getName(), publicHelper.getOwner(),
+ PolicySerializable(policyPrivateKey),
+ PolicySerializable(policyPublicKey)
+ ).maybeDeserialize();
+ } else {
+ return Request(*this, LogicCommand::CREATE_KEY_PAIR, m_storageConnection,
CryptoAlgorithmSerializable(keyGenAlgorithm),
PolicySerializable(policyPrivateKey),
PolicySerializable(policyPublicKey),
privateHelper.getName(), privateHelper.getOwner(),
publicHelper.getName(), publicHelper.getOwner()
).maybeDeserialize();
+ }
EXCEPTION_GUARD_END
}
const Policy &policyPrivateKey = Policy(),
const Policy &policyPublicKey = Policy());
+ int createKeyPairKEM(
+ const KemType type,
+ const Alias &privateKeyAlias,
+ const Alias &publicKeyAlias,
+ const Policy &policyPrivateKey = Policy(),
+ const Policy &policyPublicKey = Policy());
+
int createKeyAES(
const int size, // size in bits [128, 192, 256]
const Alias &keyAlias,
policyPrivateKey, policyPublicKey);
}
+int Manager::createKeyPairKEM(
+ const KemType type,
+ const Alias &privateKeyAlias,
+ const Alias &publicKeyAlias,
+ const Policy &policyPrivateKey,
+ const Policy &policyPublicKey)
+{
+ return m_impl->createKeyPairKEM(type, privateKeyAlias, publicKeyAlias,
+ policyPrivateKey, policyPublicKey);
+}
+
int Manager::createKeyAES(
const int size,
const Alias &keyAlias,
m_dataType = KEY_ECDSA_PRIVATE;
break;
+ case KeyType::KEY_KEM_PUBLIC:
+ m_dataType = KEY_KEM_PUBLIC;
+ break;
+
+ case KeyType::KEY_KEM_PRIVATE:
+ m_dataType = KEY_KEM_PRIVATE;
+ break;
+
case KeyType::KEY_AES:
m_dataType = KEY_AES;
break;
return (KEY_AES == m_dataType);
}
+bool DataType::isKemPublicKey() const
+{
+ return (KEY_KEM_PUBLIC == m_dataType);
+}
+
+bool DataType::isKemPrivateKey() const
+{
+ return (KEY_KEM_PRIVATE == m_dataType);
+}
+
bool DataType::isChainCert() const
{
if (DB_CHAIN_FIRST <= m_dataType && DB_CHAIN_LAST >= m_dataType)
case KEY_RSA_PRIVATE:
case KEY_DSA_PRIVATE:
case KEY_ECDSA_PRIVATE:
+ case KEY_KEM_PRIVATE:
return true;
default:
case KEY_RSA_PUBLIC:
case KEY_DSA_PUBLIC:
case KEY_ECDSA_PUBLIC:
+ case KEY_KEM_PUBLIC:
return true;
default:
KEY_DSA_PUBLIC,
KEY_DSA_PRIVATE,
KEY_AES,
+ KEY_KEM_PUBLIC,
+ KEY_KEM_PRIVATE,
CERTIFICATE = 20,
BINARY_DATA,
CHAIN_CERT_0 = 30,
// Special types to support database,
DB_KEY_FIRST = KEY_RSA_PUBLIC,
- DB_KEY_LAST = KEY_AES,
+ DB_KEY_LAST = KEY_KEM_PRIVATE,
DB_CHAIN_FIRST = CHAIN_CERT_0,
DB_CHAIN_LAST = CHAIN_CERT_15,
DB_FIRST = KEY_RSA_PUBLIC,
bool isKey() const;
bool isSymmetricKey() const;
+ bool isKemPrivateKey() const;
+ bool isKemPublicKey() const;
bool isChainCert() const;
bool isKeyPrivate() const;
bool isKeyPublic() const;
isPrivate);
}
+KeyImpl::KeyImpl(const KeyType &type, const RawBuffer &buf, const Password &password) :
+ m_key(buf),
+ m_pass(password),
+ m_type(type)
+{
+ // buf stores KEM in bytes -> compare the sizes
+ switch (buf.size()) {
+ case 1184:
+ case 1568:
+ case 2400:
+ case 3168:
+ break;
+
+ default:
+ m_key.clear();
+ }
+
+ switch (type) {
+ case KeyType::KEY_KEM_PRIVATE:
+ m_type = KeyType::KEY_KEM_PRIVATE;
+ break;
+
+ case KeyType::KEY_KEM_PUBLIC:
+ m_type = KeyType::KEY_KEM_PUBLIC;
+ break;
+
+ default:
+ m_type = KeyType::KEY_NONE;
+ }
+}
+
KeyImpl::KeyImpl(EvpShPtr pkey, KeyType type) : m_pkey(pkey), m_type(type)
{
int expected_type = EVP_PKEY_NONE;
bool KeyImpl::empty() const
{
- return !m_pkey;
+ return (!m_pkey && m_key.empty());
+}
+
+int KeyImpl::getSize() const
+{
+ // TODO m_pkey size
+ return m_key.size();
}
KeyImpl::EvpShPtr KeyImpl::getEvpShPtr() const
case KeyType::KEY_ECDSA_PUBLIC:
return getDERPUB();
+ case KeyType::KEY_KEM_PRIVATE:
+ case KeyType::KEY_KEM_PUBLIC:
+ return m_key;
+
default:
break;
}
return output;
} catch (...) {
- LogError("Critical error: Unknown exception was caught during KeyImpl creation");
+ LogError("Critical error: Unknown exception was caught during KeyImpl \
+ creation in Key::create() method");
+ }
+
+ return KeyShPtr();
+}
+
+KeyShPtr Key::createKEM(const KeyType &type, const RawBuffer &raw, const Password &password)
+{
+ try {
+ KeyShPtr output = std::make_shared<KeyImpl>(type, raw, password);
+ if (output->empty())
+ output.reset();
+ return output;
+ } catch (...) {
+ LogError("Critical error: Unknown exception was caught during KeyImpl \
+ creation in Key::createKEM() method");
}
return KeyShPtr();
KeyImpl(const KeyImpl &second) = delete;
KeyImpl &operator=(const KeyImpl &second) = delete;
KeyImpl(const RawBuffer &buffer, const Password &password = Password());
+ KeyImpl(const KeyType &type, const RawBuffer &buffer, const Password &password = Password());
KeyImpl(EvpShPtr pkey, KeyType type);
virtual KeyType getType() const;
virtual RawBuffer getDERPRV() const;
virtual EvpShPtr getEvpShPtr() const;
- virtual int getSize() const
- {
- // TODO
- return 0;
- }
-
+ virtual int getSize() const;
virtual bool empty() const;
virtual ~KeyImpl() {}
protected:
EvpShPtr m_pkey;
+ RawBuffer m_key;
+ Password m_pass;
KeyType m_type;
};
case ParamName::ED_OAEP_HASH:
case ParamName::GEN_KEY_LEN:
case ParamName::GEN_EC:
+ case ParamName::GEN_KEM_TYPE:
case ParamName::SV_HASH_ALGO:
case ParamName::SV_RSA_PADDING:
case ParamName::KDF_LEN:
REMOVE,
CREATE_KEY_AES,
CREATE_KEY_PAIR,
+ CREATE_KEY_PAIR_KEM,
GET_CHAIN_CERT,
GET_CHAIN_ALIAS,
CREATE_SIGNATURE,
#include <openssl/obj_mac.h>
#include <openssl/kdf.h>
+#include <oqs/kem.h>
+
#include <ckm/ckm-error.h>
#include <key-impl.h>
#include <dpl/log/log.h>
true,
Type<AlgoType>::Equals<AlgoType::RSA_GEN,
AlgoType::DSA_GEN,
- AlgoType::ECDSA_GEN>> IsAsymGeneration;
+ AlgoType::ECDSA_GEN,
+ AlgoType::KEM_GEN>> IsAsymGeneration;
typedef ParamCheck<ParamName::ALGO_TYPE,
AlgoType,
ElipticCurve::prime256v1,
ElipticCurve::secp384r1>> EcdsaEcCheck;
+typedef ParamCheck<ParamName::GEN_KEM_TYPE,
+ KemType,
+ true,
+ Type<KemType>::Equals<KemType::ML_KEM_768,
+ KemType::ML_KEM_1024>> KemTypeCheck;
+
// key derivation
typedef ParamCheck<ParamName::ALGO_TYPE,
AlgoType,
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::KEM_GEN, VBuilder<KemTypeCheck>::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());
return paramgenKeyPair(pctx, KeyType::KEY_ECDSA_PRIVATE, KeyType::KEY_ECDSA_PUBLIC);
}
+
+DataPair createKeyPairKEM(const KemType kemType)
+{
+ OqsKemPtr kem = createNewKem(kemType);
+ RawBuffer pub(kem->length_public_key, 0x00);
+ RawBuffer priv(kem->length_secret_key, 0x00);
+
+ OQS_STATUS rc = OQS_KEM_keypair(kem.get(), pub.data(), priv.data());
+ if (rc != OQS_SUCCESS) {
+ ThrowErr(Exc::Crypto::InternalError,
+ "Error in KEM key generation, OQS_STATUS: ",
+ static_cast<int>(rc));
+ }
+
+ return std::make_pair<Data, Data>(
+ {DataType(KeyType::KEY_KEM_PRIVATE), priv},
+ {DataType(KeyType::KEY_KEM_PUBLIC), pub});
+}
+
Data createKeyAES(const int sizeBits)
{
// validateParams<IsSymGeneration> should prevent it
} // namespace
+OqsKemPtr createNewKem(const KemType type)
+{
+ OqsKemPtr kem;
+ switch(type){
+ case KemType::ML_KEM_768:
+ kem = std::shared_ptr<OQS_KEM>(OQS_KEM_new(OQS_KEM_alg_ml_kem_768), OQS_KEM_free);
+ break;
+
+ case KemType::ML_KEM_1024:
+ kem = std::shared_ptr<OQS_KEM>(OQS_KEM_new(OQS_KEM_alg_ml_kem_1024), OQS_KEM_free);
+ break;
+ }
+
+ if (kem == nullptr) {
+ ThrowErr(CKM::Exc::Crypto::InternalError, "Invalid OQS algorithm name was provided, or the \
+ requested algorithm was disabled at compile-time.");
+ }
+
+ return kem;
+}
DataPair generateAKey(const CryptoAlgorithm &algorithm)
{
return createKeyPairRSA(keyLength);
else
return createKeyPairDSA(keyLength);
+ } else if (keyType == AlgoType::KEM_GEN) {
+ KemType kemType = unpack<KemType>(algorithm, ParamName::GEN_KEM_TYPE);
+ return createKeyPairKEM(kemType);
} else { // AlgoType::ECDSA_GEN
ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC);
return createKeyPairECDSA(ecType);
#include <sw-backend/obj.h>
#include <sw-backend/crypto.h>
+#include <oqs/kem.h>
+
namespace CKM {
namespace Crypto {
namespace SW {
typedef std::unique_ptr<Cipher::EvpCipherWrapper<RawBuffer>> EvpCipherPtr;
+typedef std::shared_ptr<OQS_KEM> OqsKemPtr;
+
+OqsKemPtr createNewKem(const CKM::KemType type);
DataPair generateAKey(const CryptoAlgorithm &algorithm);
Data generateSKey(const CryptoAlgorithm &algorithm);
if (input.type.isSymmetricKey())
output_key = CKM::Key::createAES(input.data);
+ else if (input.type.isKemPrivateKey())
+ output_key = CKM::Key::createKEM(KeyType::KEY_KEM_PRIVATE, input.data);
+ else if (input.type.isKemPublicKey())
+ output_key = CKM::Key::createKEM(KeyType::KEY_KEM_PUBLIC, input.data);
else
output_key = CKM::Key::create(input.data);
const std::unordered_map<AlgoType, DataType::Type> algoTypeToDataTypeConverter = {
{ AlgoType::RSA_GEN, DataType::Type::KEY_RSA_PRIVATE },
{ AlgoType::DSA_GEN, DataType::Type::KEY_DSA_PRIVATE },
- { AlgoType::ECDSA_GEN, DataType::Type::KEY_ECDSA_PRIVATE }
+ { AlgoType::ECDSA_GEN, DataType::Type::KEY_ECDSA_PRIVATE },
+ { AlgoType::KEM_GEN, DataType::Type::KEY_KEM_PRIVATE },
};
const auto dataTypeIt = algoTypeToDataTypeConverter.find(
if (dataTypeIt == algoTypeToDataTypeConverter.cend())
{
- ThrowErr(Exc::InputParam, "Error, key pair must be RSA or DSA or ECDSA.");
+ ThrowErr(Exc::InputParam, "Error, key pair must be RSA or DSA or ECDSA or KEM.");
}
TokenPair keys = m_decider.getStore(
break;
}
+ case LogicCommand::CREATE_KEY_PAIR_KEM: {
+ CryptoAlgorithmSerializable keyGenAlgorithm;
+ Name privateKeyName;
+ ClientId explicitOwnerPrivate;
+ Name publicKeyName;
+ ClientId explicitOwnerPublic;
+ PolicySerializable policyPrivateKey;
+ PolicySerializable policyPublicKey;
+
+ buffer.Deserialize(keyGenAlgorithm,
+ privateKeyName,
+ explicitOwnerPrivate,
+ publicKeyName,
+ explicitOwnerPublic,
+ policyPrivateKey,
+ policyPublicKey);
+
+ logicFunc = [&, keyGenAlgorithm, privateKeyName, explicitOwnerPrivate, publicKeyName,
+ explicitOwnerPublic, policyPrivateKey, policyPublicKey]() {
+ return m_logic->createKeyPair(
+ cred,
+ msgId,
+ keyGenAlgorithm,
+ privateKeyName,
+ cred.effectiveOwner(explicitOwnerPrivate),
+ publicKeyName,
+ cred.effectiveOwner(explicitOwnerPublic),
+ policyPrivateKey,
+ policyPublicKey);
+ };
+ break;
+ }
+
default:
Throw(Exception::BrokenProtocol);
}
${KM_LINK_EXTRA_DEPS}
${CMAKE_THREAD_LIBS_INIT}
boost_unit_test_framework
+ liboqs.a
-ldl
)
NEGATIVE_TEST_CASE(CONSTRUCTOR)
{
BOOST_REQUIRE_THROW(DataType(KeyType::KEY_NONE), Exc::InputParam);
- BOOST_REQUIRE_THROW(DataType(static_cast<KeyType>(static_cast<int>(KeyType::KEY_AES) + 1)),
+ BOOST_REQUIRE_THROW(DataType(static_cast<KeyType>(static_cast<int>(KeyType::KEY_KEM_PRIVATE) + 1)),
Exc::InputParam);
BOOST_REQUIRE_THROW(DataType(static_cast<DataType::Type>(DataType::DB_FIRST - 1)),
Exc::InputParam);