Add ML-KEM keypair creation sw-backend implementation
authorJan Wojtkowski <j.wojtkowski@samsung.com>
Thu, 27 Jun 2024 10:04:13 +0000 (12:04 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Wed, 4 Sep 2024 11:44:32 +0000 (13:44 +0200)
Change-Id: I9102452d64ef09b82b09aad0da287f247bad729e

22 files changed:
packaging/key-manager.spec
src/include/ckm/ckm-key.h
src/include/ckm/ckm-manager.h
src/include/ckm/ckm-type.h
src/include/ckmc/ckmc-manager.h
src/manager/CMakeLists.txt
src/manager/client-capi/ckmc-manager.cpp
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/client/client-manager.cpp
src/manager/common/data-type.cpp
src/manager/common/data-type.h
src/manager/common/key-impl.cpp
src/manager/common/key-impl.h
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/crypto/sw-backend/internals.cpp
src/manager/crypto/sw-backend/internals.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-service.cpp
unit-tests/CMakeLists.txt
unit-tests/test_data-type.cpp

index 7f9e1c9d607ea8c0c5d8f188de51ab2a9eb26fb5..09eab47ed10152ccbb529ef9bb4072a0ce809438 100644 (file)
@@ -55,6 +55,7 @@ Requires: libkey-manager-common = %{version}-%{release}
 %if "%{build_type}" == "COVERAGE"
 BuildRequires: lcov
 %endif
+BuildRequires: liboqs
 
 %{?systemd_requires}
 
index 6b586c6d8f7b706014804f77ff635c19ff3e8622..e24d112f014581463e0f285dec0a1becb5adb7f5 100644 (file)
@@ -42,6 +42,11 @@ public:
 
        static KeyShPtr createAES(
                const RawBuffer &rawBuffer);
+
+       static KeyShPtr createKEM(
+               const KeyType &type,
+               const RawBuffer &rawBuffer,
+               const Password &password = Password());
 };
 
 } // namespace CKM
index fbf633c50da78affeadc5e7b2b5e1f91e6b90416..9bc04f4e5bf44046aebf63d64ef6e70d5e68dd60 100644 (file)
@@ -104,6 +104,13 @@ public:
                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,
index a7d2c7bdb69fdf378bbdd6f961a218ef19af3f1e..60c681a11561e88d7aadc8a628c451a4eeb5e5e3 100644 (file)
@@ -92,7 +92,9 @@ enum class KeyType : int {
        KEY_ECDSA_PRIVATE,
        KEY_DSA_PUBLIC,
        KEY_DSA_PRIVATE,
-       KEY_AES
+       KEY_AES,
+       KEY_KEM_PUBLIC,
+       KEY_KEM_PRIVATE,
 };
 
 enum class DataFormat : int {
@@ -107,6 +109,11 @@ enum class ElipticCurve : int {
        secp384r1
 };
 
+enum class KemType : int {
+       ML_KEM_768 = 0,
+       ML_KEM_1024,
+};
+
 enum class CertificateFieldId : int {
        ISSUER = 0,
        SUBJECT
@@ -209,10 +216,11 @@ enum class ParamName : int {
        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)
@@ -233,6 +241,7 @@ enum class AlgoType : int {
        DSA_GEN,
        ECDSA_GEN,
        AES_GEN,
+       KEM_GEN,
 };
 
 // cryptographic algorithm description
index 28cb10b060f84c101204d01d9cb62ccdfc0c819f..487290035f236b7db515245c87d024aacbb64966 100644 (file)
@@ -48,8 +48,9 @@ extern "C" {
  * @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
index ced080ad214127f31196243e8e960c0e5142140c..332c2dc855839b7e03cf3cf575c573b2b13eae37 100644 (file)
@@ -65,6 +65,7 @@ SET_TARGET_PROPERTIES(
 
 TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER_COMMON}
     ${COMMON_DEP_LIBRARIES}
+    liboqs.a
     )
 
 ##########################################################################
index bf1219f8211584118de8858bd7ada848fac31b10..aee627f45f48354a146ab2c506d88766eb28fc52 100644 (file)
@@ -353,6 +353,10 @@ int ckmc_save_key(const char *alias, const ckmc_key_s key,
                        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));
        }
@@ -1368,13 +1372,20 @@ int ckmc_create_key_pair_kem(const ckmc_kem_type_e kem_type,
                              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
@@ -1431,4 +1442,4 @@ int ckmc_key_derive_hybrid(const ckmc_param_list_h params,
        (void) new_key_policy;
 
        return CKMC_ERROR_NONE;
-}
\ No newline at end of file
+}
index 3f1f6e20d3a3892d616a0e0a918bdde319a70acb..e60c49811a292ab2cd4256dfb9cad8462d3f8a91 100644 (file)
@@ -310,7 +310,15 @@ int Manager::Impl::getKey(const Alias &alias, const Password &password,
        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!");
@@ -489,6 +497,17 @@ int Manager::Impl::createKeyAES(
        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,
@@ -520,6 +539,12 @@ int Manager::Impl::createKeyPair(
                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;
        }
@@ -528,14 +553,23 @@ int Manager::Impl::createKeyPair(
 
        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
 }
index 896bb8d83efbe2eaf5c3358d0dafb0df770c9717..c78b91d9f45d73c4f5bded749385d7e205e7072d 100644 (file)
@@ -85,6 +85,13 @@ public:
                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,
index eb8f42cd9ca0c448a2caa8c8c96f1d743520204f..2aa26dd6843a89eebe932fb7d3a5c53bbea54358 100644 (file)
@@ -175,6 +175,17 @@ int Manager::createKeyPairECDSA(
                                                                          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,
index 38d9c3d9e1fbddd80363d6c54738e462d19802f7..0494175c21da711b96d1877d64652cb896b529e9 100644 (file)
@@ -64,6 +64,14 @@ DataType::DataType(KeyType key)
                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;
@@ -116,6 +124,16 @@ bool DataType::isSymmetricKey() const
        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)
@@ -130,6 +148,7 @@ bool DataType::isKeyPrivate() const
        case KEY_RSA_PRIVATE:
        case KEY_DSA_PRIVATE:
        case KEY_ECDSA_PRIVATE:
+       case KEY_KEM_PRIVATE:
                return true;
 
        default:
@@ -143,6 +162,7 @@ bool DataType::isKeyPublic() const
        case KEY_RSA_PUBLIC:
        case KEY_DSA_PUBLIC:
        case KEY_ECDSA_PUBLIC:
+       case KEY_KEM_PUBLIC:
                return true;
 
        default:
index ad2a7046c2ee753d1f9b426b3dd209c99a86c65d..a68df567c25cef0585d7cdc7fafd6c16a5bcd559 100644 (file)
@@ -38,6 +38,8 @@ public:
                KEY_DSA_PUBLIC,
                KEY_DSA_PRIVATE,
                KEY_AES,
+               KEY_KEM_PUBLIC,
+               KEY_KEM_PRIVATE,
                CERTIFICATE = 20,
                BINARY_DATA,
                CHAIN_CERT_0 = 30,
@@ -59,7 +61,7 @@ public:
 
                // 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,
@@ -81,6 +83,8 @@ public:
 
        bool isKey() const;
        bool isSymmetricKey() const;
+       bool isKemPrivateKey() const;
+       bool isKemPublicKey() const;
        bool isChainCert() const;
        bool isKeyPrivate() const;
        bool isKeyPublic() const;
index 8a4ef6198744970445ab6567b4cf291dac1f3133..de21accf0d120e826bd713be18ed3985dc77ecf0 100644 (file)
@@ -158,6 +158,37 @@ KeyImpl::KeyImpl(const RawBuffer &buf, const Password &password) :
                         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;
@@ -200,7 +231,13 @@ KeyImpl::KeyImpl(EvpShPtr pkey, KeyType type) : m_pkey(pkey), m_type(type)
 
 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
@@ -236,6 +273,10 @@ RawBuffer KeyImpl::getDER() const
        case KeyType::KEY_ECDSA_PUBLIC:
                return getDERPUB();
 
+       case KeyType::KEY_KEM_PRIVATE:
+       case KeyType::KEY_KEM_PUBLIC:
+               return m_key;
+
        default:
                break;
        }
@@ -253,7 +294,23 @@ KeyShPtr Key::create(const RawBuffer &raw, const Password &password)
 
                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();
index dbd92d7cde5a54c9e0cfe08d7ffdc27982dc03c5..aed0835cce8c31013c81977f700e48298771363b 100644 (file)
@@ -36,6 +36,7 @@ public:
        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;
@@ -44,17 +45,14 @@ public:
        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;
 };
 
index f2eca03cacfc87d5134f314c228f44ec474bd1cd..e090360a83b153fcda36be6ba847b8f2042007e9 100644 (file)
@@ -238,6 +238,7 @@ void CryptoAlgorithmSerializable::Deserialize(IStream &stream)
                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:
index 8196f9ce19336652bf240e9d0986368f4d53aeb3..047a77fc14c53e52f19b28d4b3c08a944ad210c1 100644 (file)
@@ -60,6 +60,7 @@ enum class LogicCommand : int {
        REMOVE,
        CREATE_KEY_AES,
        CREATE_KEY_PAIR,
+       CREATE_KEY_PAIR_KEM,
        GET_CHAIN_CERT,
        GET_CHAIN_ALIAS,
        CREATE_SIGNATURE,
index 763735eeacaaf4f9f5727a6a117e25582e93805c..9f670bba38157f4dfdef4c7da23382bfc3dce808 100644 (file)
@@ -36,6 +36,8 @@
 #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>
@@ -157,7 +159,8 @@ typedef ParamCheck<ParamName::ALGO_TYPE,
                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,
@@ -186,6 +189,12 @@ typedef ParamCheck<ParamName::GEN_EC,
                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,
@@ -254,6 +263,7 @@ ValidatorMap initValidators()
        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());
@@ -549,6 +559,25 @@ DataPair createKeyPairECDSA(ElipticCurve type)
        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
@@ -740,6 +769,26 @@ int getCurve(const EC_KEY* ecKey)
 
 } // 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)
 {
@@ -754,6 +803,9 @@ 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);
index d91dddbd812c3da967017872d56d698c2be1df37..94e22db9e6042da1e38791320b3fda07113d610a 100644 (file)
@@ -25,6 +25,8 @@
 #include <sw-backend/obj.h>
 #include <sw-backend/crypto.h>
 
+#include <oqs/kem.h>
+
 namespace CKM {
 namespace Crypto {
 namespace SW {
@@ -40,6 +42,9 @@ typedef std::pair<Data, Data> DataPair;
 
 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);
 
index dc67f76c8454d39c5e2d4b44e011f7d37e818e1f..515847d779fe8b1366ebfd5d765eb1b0e08b1522 100644 (file)
@@ -85,6 +85,10 @@ int toBinaryData(const Crypto::Data &input, Crypto::Data &output)
 
                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);
 
@@ -1176,7 +1180,8 @@ RawBuffer CKMLogic::createKeyPair(
                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(
@@ -1184,7 +1189,7 @@ RawBuffer CKMLogic::createKeyPair(
 
                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(
index 7cfac0f5a548fd61413f012edbca6c6e62747067..5ebe54d18aa5a5a008612d7cfc92578b12b657e5 100644 (file)
@@ -638,6 +638,39 @@ RawBuffer CKMService::ProcessExtended(Credentials &cred, MessageBuffer &buffer,
                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);
        }
index 1dfb7beeba97e5eb6e70c99330ae9099d370967d..44ca12f1b715b913e7cbda765f6f4259a7111ee4 100644 (file)
@@ -156,6 +156,7 @@ TARGET_LINK_LIBRARIES(
     ${KM_LINK_EXTRA_DEPS}
     ${CMAKE_THREAD_LIBS_INIT}
     boost_unit_test_framework
+    liboqs.a
     -ldl
 )
 
index 984e1512224158a373d3ce42642310d2a82a7fdd..eaf9e21771d1fd8646e32eb04b8c74b68402bb95 100644 (file)
@@ -33,7 +33,7 @@ BOOST_AUTO_TEST_SUITE(DATA_TYPE_TEST)
 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);