Add ML-KEM derive hybrid sw-backend implementation
authorJan Wojtkowski <j.wojtkowski@samsung.com>
Fri, 19 Jul 2024 13:55:30 +0000 (15:55 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Wed, 4 Sep 2024 11:45:09 +0000 (13:45 +0200)
Change-Id: Ica9e6e6a778d293ff8d0ca66e06a3d2299ad6e64

12 files changed:
src/include/ckm/ckm-manager.h
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/protocols.h
src/manager/crypto/generic-backend/gobj.h
src/manager/crypto/sw-backend/obj.cpp
src/manager/crypto/sw-backend/obj.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp

index 9b7994f781c014ad2c2efcf1f000e9fc2f30a860..064733a731e71073202db137284bf933d3072fd6 100644 (file)
@@ -230,6 +230,14 @@ public:
                                           const Policy &sharedSecretPolicy,
                                           const RawBuffer &ciphertext);
 
+       int deriveHybrid(const CryptoAlgorithm &params,
+                                        const Alias &firstSecretAlias,
+                                        const Password &firstSecretPassword,
+                                        const Alias &secondSecretAlias,
+                                        const Password &secondSecretPassword,
+                                        const Alias &newKeyAlias,
+                                        const Policy &newKeyPolicy);
+
        int initializeCipher(const CryptoAlgorithm &params,
                                                 const Alias &keyAlias,
                                                 const Password &keyPassword,
index 49fcbb3e3136549a5904acbcb04ff18093972702..a0cb41b85d5c69539a18336c15befa3c58ea9b19 100644 (file)
@@ -1468,13 +1468,27 @@ int ckmc_key_derive_hybrid(const ckmc_param_list_h params,
                            const char *new_key_alias,
                            const ckmc_policy_s new_key_policy)
 {
-       (void) params;
-       (void) first_secret_alias;
-       (void) first_secret_password;
-       (void) second_secret_alias;
-       (void) second_secret_password;
-       (void) new_key_alias;
-       (void) new_key_policy;
+       EXCEPTION_GUARD_START_CAPI
 
-       return CKMC_ERROR_NONE;
+       if (params == nullptr || first_secret_alias == nullptr ||
+               second_secret_alias == nullptr || new_key_alias == nullptr)
+               return CKMC_ERROR_INVALID_PARAMETER;
+
+       const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
+                                                                        (params);
+
+       int ret = 0;
+       auto mgr = CKM::Manager::create();
+
+       ret = to_ckmc_error(
+               mgr->deriveHybrid(*ca,
+                                                 CKM::Alias(first_secret_alias),
+                                                 _tostring(first_secret_password),
+                                                 CKM::Alias(second_secret_alias),
+                                                 _tostring(second_secret_password),
+                                                 CKM::Alias(new_key_alias),
+                                                 _toCkmPolicy(new_key_policy)));
+
+       return ret;
+       EXCEPTION_GUARD_END
 }
index 56e2de22fa060f3f5cbe81aacfa9086f4890cffe..30fd8ca80b4de083b4fa6e13d10660b721c6a888 100644 (file)
@@ -963,6 +963,38 @@ int Manager::Impl::decapsulateKey(const CryptoAlgorithm &params,
        EXCEPTION_GUARD_END
 }
 
+int Manager::Impl::deriveHybrid(const CryptoAlgorithm &params,
+                                                               const Alias &firstSecretAlias,
+                                                               const Password &firstSecretPassword,
+                                                               const Alias &secondSecretAlias,
+                                                               const Password &secondSecretPassword,
+                                                               const Alias &newKeyAlias,
+                                                               const Policy &newKeyPolicy)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport firstSecretAliasHelper(firstSecretAlias);
+       AliasSupport secondSecretAliasHelper(secondSecretAlias);
+       AliasSupport newKeyAliasHelper(newKeyAlias);
+
+       return Request(*this,
+               LogicCommand::DERIVE_HYBRID,
+               m_extendedConnection,
+               CryptoAlgorithmSerializable(params),
+               firstSecretAliasHelper.getName(),
+               firstSecretAliasHelper.getOwner(),
+               firstSecretPassword,
+               secondSecretAliasHelper.getName(),
+               secondSecretAliasHelper.getOwner(),
+               secondSecretPassword,
+               newKeyAliasHelper.getName(),
+               newKeyAliasHelper.getOwner(),
+               PolicySerializable(newKeyPolicy)
+       ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
 int Manager::Impl::initializeCipher(
        const CryptoAlgorithm &params,
        const Alias &keyAlias,
index 88969a3dba8d7d3af2a57e21bc7433bc78317590..8133d5fc5b1d5936d85d426df7fe2c92e8726f8f 100644 (file)
@@ -195,6 +195,14 @@ public:
                                           const Policy &sharedSecretPolicy,
                                           const RawBuffer &ciphertext);
 
+       int deriveHybrid(const CryptoAlgorithm &params,
+                                        const Alias &firstSecretAlias,
+                                        const Password &firstSecretPassword,
+                                        const Alias &secondSecretAlias,
+                                        const Password &secondSecretPassword,
+                                        const Alias &newKeyAlias,
+                                        const Policy &newKeyPolicy);
+
        int initializeCipher(const CryptoAlgorithm &params,
                                                 const Alias &keyAlias,
                                                 const Password &keyPassword,
index dc1c065b09de305a8f0caaf7858f735593d77803..4487d522709398540db082b0b0aaf717dbc8c6f9 100644 (file)
@@ -421,6 +421,25 @@ int Manager::decapsulateKey(const CryptoAlgorithm &params,
        );
 }
 
+int Manager::deriveHybrid(const CryptoAlgorithm &params,
+                                                 const Alias &firstSecretAlias,
+                                                 const Password &firstSecretPassword,
+                                                 const Alias &secondSecretAlias,
+                                                 const Password &secondSecretPassword,
+                                                 const Alias &newKeyAlias,
+                                                 const Policy &newKeyPolicy)
+{
+       return m_impl->deriveHybrid(
+               params,
+               firstSecretAlias,
+               firstSecretPassword,
+               secondSecretAlias,
+               secondSecretPassword,
+               newKeyAlias,
+               newKeyPolicy
+       );
+}
+
 int Manager::initializeCipher(
        const CryptoAlgorithm &params,
        const Alias &keyAlias,
index 072967984b0c03b6cf524af1ed82d8885cb65bd7..3c3c43a18e96ab351b4a48aecf44bc77436f8ef8 100644 (file)
@@ -76,7 +76,8 @@ enum class LogicCommand : int {
        UNWRAP_CONCATENATED_DATA,
        GET_BACKEND_INFO,
        ENCAPSULATE_KEY,
-       DECAPSULATE_KEY
+       DECAPSULATE_KEY,
+       DERIVE_HYBRID
 };
 
 enum class EncryptionCommand : int {
index 5167ca05696656e7434b1846d9ebe6b5b4ff047c..5368b68ef8a795e2d1174eb03de4b4f05f997cde 100644 (file)
@@ -128,6 +128,17 @@ public:
                ThrowErr(Exc::Crypto::OperationNotSupported);
        }
 
+       virtual Token deriveHybrid(const CryptoAlgorithm &,
+                                                          const Token &,
+                                                          const Password &,
+                                                          const Token &,
+                                                          const Password &,
+                                                          const Password &,
+                                                          const RawBuffer &)
+       {
+               ThrowErr(Exc::Crypto::OperationNotSupported);
+       }
+
        // onward = true for encryption/signing, false for decryption/verification
        virtual GCtxShPtr initContext(const CryptoAlgorithm &, bool /*onward*/)
        {
index 9263e9c73388c646cf9c635699d49750685355c3..5108319175bcdf1e150988e26618568153d22968 100644 (file)
@@ -72,6 +72,25 @@ Token BData::derive(const CryptoAlgorithm &alg, const Password &pass, const RawB
        return Token(backendId(), data.type, Store::pack(data.buffer, pass));
 }
 
+Token BData::deriveHybrid(const CryptoAlgorithm &params,
+                                                 const Token &firstKey,
+                                                 const Password &firstPass,
+                                                 const Token &secondKey,
+                                                 const Password &secondPass,
+                                                 const Password &newKeyPass,
+                                                 const RawBuffer &)
+{
+       RawBuffer firstKeyBuffer = Store::unpack(firstKey.data, firstPass);
+       RawBuffer secondKeyBuffer = Store::unpack(secondKey.data, secondPass);
+
+       firstKeyBuffer.reserve(firstKeyBuffer.size() + secondKeyBuffer.size());
+       firstKeyBuffer.insert(firstKeyBuffer.end(), secondKeyBuffer.begin(), secondKeyBuffer.end());
+
+       auto data = Internals::deriveKBKDF(firstKeyBuffer, params);
+
+       return Token(backendId(), data.type, Store::pack(data.buffer, newKeyPass));
+}
+
 Token Key::unwrap(const CryptoAlgorithm &params,
                                  const Data &wrappedKey,
                                  const Password &pass,
@@ -387,6 +406,17 @@ Token Cert::decapsulateKey(const CryptoAlgorithm &,
        ThrowErr(Exc::Crypto::OperationNotSupported);
 }
 
+Token Cert::deriveHybrid(const CryptoAlgorithm &,
+                                                const Token &,
+                                                const Password &,
+                                                const Token &,
+                                                const Password &,
+                                                const Password &,
+                                                const RawBuffer &)
+{
+       ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
 } // namespace SW
 } // namespace Crypto
 } // namespace CKM
index 86cb02013d04e00788ac3aee61f7161174d9143b..9aa825de030ad97abcf9c15af68380a75997ed41 100644 (file)
@@ -44,6 +44,13 @@ public:
                return m_raw;
        }
        Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
+       Token deriveHybrid(const CryptoAlgorithm &,
+                                          const Token &,
+                                          const Password &,
+                                          const Token &,
+                                          const Password &,
+                                          const Password &,
+                                          const RawBuffer &) override;
 
 protected:
        RawBuffer m_raw;
@@ -151,6 +158,14 @@ public:
                                                 const RawBuffer &,
                                                 const RawBuffer &) override;
 
+       Token deriveHybrid(const CryptoAlgorithm &,
+                                          const Token &,
+                                          const Password &,
+                                          const Token &,
+                                          const Password &,
+                                          const Password &,
+                                          const RawBuffer &) override;
+
 protected:
        EvpShPtr getEvpShPtr() override;
 };
index 5aad7bafbe2329900a74f5e7d3a165de06711b58..9bf0716e74090950e3082c15582de51f86c90a01 100644 (file)
@@ -1898,6 +1898,70 @@ RawBuffer CKMLogic::decapsulateKey(
        return SerializeMessage(msgID, retCode);
 }
 
+RawBuffer CKMLogic::deriveHybrid(
+       const Credentials &cred,
+       const int msgID,
+       const CryptoAlgorithm &params,
+       const Name &firstSecretAlias,
+       const ClientId &firstSecretOwner,
+       const Password &firstSecretPassword,
+       const Name &secondSecretAlias,
+       const ClientId &secondSecretOwner,
+       const Password &secondSecretPassword,
+       const Name &newKeyAlias,
+       const ClientId &newKeyOwner,
+       const PolicySerializable &newKeyPolicy)
+{
+       DB::Row firstKeyRow, secondKeyRow;
+       DataType firstKeyType, secondKeyType;
+
+       return SerializeMessage(msgID, tryRet([&] {
+               Crypto::GObjUPtr obj;
+               DataType objType;
+               auto [dbOp, digest, ret] = beginSaveAndGetHash(cred, newKeyAlias, newKeyOwner);
+               if (ret != CKM_API_SUCCESS)
+                       return ret;
+
+               ret = readDataHelper(false, cred, DataType::DB_KEY_LAST,
+                                                        firstSecretAlias, firstSecretOwner, firstSecretPassword, obj, objType);
+               if (ret != CKM_API_SUCCESS) {
+                       ret = readDataHelper(false, cred, DataType::BINARY_DATA,
+                                                                firstSecretAlias, firstSecretOwner, firstSecretPassword, obj, objType);
+                       if (ret != CKM_API_SUCCESS)
+                               return ret;
+
+                       ret = readRowHelper(false, cred, DataType::BINARY_DATA, firstSecretAlias, firstSecretOwner,
+                                                       firstSecretPassword, firstKeyRow, firstKeyType);
+
+               } else {
+                       ret = readRowHelper(false, cred, DataType::KEY_AES, firstSecretAlias, firstSecretOwner,
+                                                               firstSecretPassword, firstKeyRow, firstKeyType);
+                       if (ret != CKM_API_SUCCESS)
+                               return ret;
+               }
+
+               ret = readRowHelper(false, cred, DataType::KEY_AES, secondSecretAlias, secondSecretOwner,
+                                                               secondSecretPassword, secondKeyRow, secondKeyType);
+               if (ret != CKM_API_SUCCESS) {
+                       ret = readRowHelper(false, cred, DataType::BINARY_DATA, secondSecretAlias, secondSecretOwner,
+                                                       secondSecretPassword, secondKeyRow, secondKeyType);
+                       if (ret != CKM_API_SUCCESS)
+                               return ret;
+               }
+
+               if (firstKeyRow.backendId != secondKeyRow.backendId) {
+                               LogError("Mismatched backends");
+                               return CKM_API_ERROR_INPUT_PARAM;
+               }
+
+               Token newKey = obj->deriveHybrid(params, firstKeyRow, firstSecretPassword, secondKeyRow,
+                                                                                secondSecretPassword, newKeyPolicy.password, digest);
+
+               dbOp.finalize(std::move(newKey), newKeyPolicy);
+               return CKM_API_SUCCESS;
+       }));
+}
+
 RawBuffer CKMLogic::getBackendInfo(const int msgID, BackendId backend)
 {
        BackendInfo info;
index c75b9f1bd44ac1e50077c4d47e01d07d3a1f49a5..ac81d77b30556a2b96dac4429a2f31db211eb3a8 100644 (file)
@@ -274,6 +274,20 @@ public:
                const PolicySerializable &sharedSecretPolicy,
                const RawBuffer &ciphertext);
 
+       RawBuffer deriveHybrid(
+               const Credentials &cred,
+               const int msgID,
+               const CryptoAlgorithm &params,
+               const Name &firstSecretAlias,
+               const ClientId &firstSecretOwner,
+               const Password &firstSecretPassword,
+               const Name &secondSecretAlias,
+               const ClientId &secondSecretOwner,
+               const Password &secondSecretPassword,
+               const Name &newKeyAlias,
+               const ClientId &newKeyOwner,
+               const PolicySerializable &newKeyPolicy);
+
        RawBuffer getBackendInfo(
                const int msgID,
                BackendId backend);
index 0e1e77c577c6b7c11c21d6b7bc0528fb145201af..1ca76cfe7a1737982d882fb3a8f9168db6759afd 100644 (file)
@@ -738,8 +738,53 @@ RawBuffer CKMService::ProcessExtended(Credentials &cred, MessageBuffer &buffer,
                                                ciphertext);
                };
                break;
+
        }
 
+       case LogicCommand::DERIVE_HYBRID: {
+               CryptoAlgorithmSerializable params;
+               Name firstSecretAlias;
+               ClientId firstSecretOwner;
+               Password firstSecretPassword;
+               Name secondSecretAlias;
+               ClientId secondSecretOwner;
+               Password secondSecretPassword;
+               Name newKeyAlias;
+               ClientId newKeyOwner;
+               PolicySerializable newKeyPolicy;
+
+               buffer.Deserialize(params,
+                                                  firstSecretAlias,
+                                                  firstSecretOwner,
+                                                  firstSecretPassword,
+                                                  secondSecretAlias,
+                                                  secondSecretOwner,
+                                                  secondSecretPassword,
+                                                  newKeyAlias,
+                                                  newKeyOwner,
+                                                  newKeyPolicy);
+
+               logicFunc = [&, params, firstSecretAlias, firstSecretOwner, firstSecretPassword,
+                                        secondSecretAlias, secondSecretOwner, secondSecretPassword, newKeyAlias,
+                                        newKeyOwner, newKeyPolicy]() {
+                       return m_logic->deriveHybrid(
+                                               cred,
+                                               msgId,
+                                               params,
+                                               firstSecretAlias,
+                                               cred.effectiveOwner(firstSecretOwner),
+                                               firstSecretPassword,
+                                               secondSecretAlias,
+                                               cred.effectiveOwner(secondSecretOwner),
+                                               secondSecretPassword,
+                                               newKeyAlias,
+                                               cred.effectiveOwner(newKeyOwner),
+                                               newKeyPolicy);
+                       };
+                       break;
+
+               }
+
        default:
                Throw(Exception::BrokenProtocol);
        }