From: Jan Wojtkowski Date: Fri, 19 Jul 2024 13:55:30 +0000 (+0200) Subject: Add ML-KEM derive hybrid sw-backend implementation X-Git-Tag: accepted/tizen/7.0/unified/20240905.165637~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=592a05236e161895e34fc40d30b249bd24f07175;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git Add ML-KEM derive hybrid sw-backend implementation Change-Id: Ica9e6e6a778d293ff8d0ca66e06a3d2299ad6e64 --- diff --git a/src/include/ckm/ckm-manager.h b/src/include/ckm/ckm-manager.h index 9b7994f7..064733a7 100644 --- a/src/include/ckm/ckm-manager.h +++ b/src/include/ckm/ckm-manager.h @@ -230,6 +230,14 @@ public: const Policy &sharedSecretPolicy, const RawBuffer &ciphertext); + int deriveHybrid(const CryptoAlgorithm ¶ms, + const Alias &firstSecretAlias, + const Password &firstSecretPassword, + const Alias &secondSecretAlias, + const Password &secondSecretPassword, + const Alias &newKeyAlias, + const Policy &newKeyPolicy); + int initializeCipher(const CryptoAlgorithm ¶ms, const Alias &keyAlias, const Password &keyPassword, diff --git a/src/manager/client-capi/ckmc-manager.cpp b/src/manager/client-capi/ckmc-manager.cpp index 49fcbb3e..a0cb41b8 100644 --- a/src/manager/client-capi/ckmc-manager.cpp +++ b/src/manager/client-capi/ckmc-manager.cpp @@ -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 + (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 } diff --git a/src/manager/client/client-manager-impl.cpp b/src/manager/client/client-manager-impl.cpp index 56e2de22..30fd8ca8 100644 --- a/src/manager/client/client-manager-impl.cpp +++ b/src/manager/client/client-manager-impl.cpp @@ -963,6 +963,38 @@ int Manager::Impl::decapsulateKey(const CryptoAlgorithm ¶ms, EXCEPTION_GUARD_END } +int Manager::Impl::deriveHybrid(const CryptoAlgorithm ¶ms, + 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 ¶ms, const Alias &keyAlias, diff --git a/src/manager/client/client-manager-impl.h b/src/manager/client/client-manager-impl.h index 88969a3d..8133d5fc 100644 --- a/src/manager/client/client-manager-impl.h +++ b/src/manager/client/client-manager-impl.h @@ -195,6 +195,14 @@ public: const Policy &sharedSecretPolicy, const RawBuffer &ciphertext); + int deriveHybrid(const CryptoAlgorithm ¶ms, + const Alias &firstSecretAlias, + const Password &firstSecretPassword, + const Alias &secondSecretAlias, + const Password &secondSecretPassword, + const Alias &newKeyAlias, + const Policy &newKeyPolicy); + int initializeCipher(const CryptoAlgorithm ¶ms, const Alias &keyAlias, const Password &keyPassword, diff --git a/src/manager/client/client-manager.cpp b/src/manager/client/client-manager.cpp index dc1c065b..4487d522 100644 --- a/src/manager/client/client-manager.cpp +++ b/src/manager/client/client-manager.cpp @@ -421,6 +421,25 @@ int Manager::decapsulateKey(const CryptoAlgorithm ¶ms, ); } +int Manager::deriveHybrid(const CryptoAlgorithm ¶ms, + 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 ¶ms, const Alias &keyAlias, diff --git a/src/manager/common/protocols.h b/src/manager/common/protocols.h index 07296798..3c3c43a1 100644 --- a/src/manager/common/protocols.h +++ b/src/manager/common/protocols.h @@ -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 { diff --git a/src/manager/crypto/generic-backend/gobj.h b/src/manager/crypto/generic-backend/gobj.h index 5167ca05..5368b68e 100644 --- a/src/manager/crypto/generic-backend/gobj.h +++ b/src/manager/crypto/generic-backend/gobj.h @@ -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*/) { diff --git a/src/manager/crypto/sw-backend/obj.cpp b/src/manager/crypto/sw-backend/obj.cpp index 9263e9c7..51083191 100644 --- a/src/manager/crypto/sw-backend/obj.cpp +++ b/src/manager/crypto/sw-backend/obj.cpp @@ -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 ¶ms, + 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 ¶ms, 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 diff --git a/src/manager/crypto/sw-backend/obj.h b/src/manager/crypto/sw-backend/obj.h index 86cb0201..9aa825de 100644 --- a/src/manager/crypto/sw-backend/obj.h +++ b/src/manager/crypto/sw-backend/obj.h @@ -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; }; diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index 5aad7baf..9bf0716e 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -1898,6 +1898,70 @@ RawBuffer CKMLogic::decapsulateKey( return SerializeMessage(msgID, retCode); } +RawBuffer CKMLogic::deriveHybrid( + const Credentials &cred, + const int msgID, + const CryptoAlgorithm ¶ms, + 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; diff --git a/src/manager/service/ckm-logic.h b/src/manager/service/ckm-logic.h index c75b9f1b..ac81d77b 100644 --- a/src/manager/service/ckm-logic.h +++ b/src/manager/service/ckm-logic.h @@ -274,6 +274,20 @@ public: const PolicySerializable &sharedSecretPolicy, const RawBuffer &ciphertext); + RawBuffer deriveHybrid( + const Credentials &cred, + const int msgID, + const CryptoAlgorithm ¶ms, + 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); diff --git a/src/manager/service/ckm-service.cpp b/src/manager/service/ckm-service.cpp index 0e1e77c5..1ca76cfe 100644 --- a/src/manager/service/ckm-service.cpp +++ b/src/manager/service/ckm-service.cpp @@ -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); }