Add ML-KEM (en/de)capsulation tz-backend implementation 57/315557/24
authorJan Wojtkowski <j.wojtkowski@samsung.com>
Thu, 1 Aug 2024 15:08:49 +0000 (17:08 +0200)
committerJan Wojtkowski <j.wojtkowski@samsung.com>
Tue, 3 Sep 2024 07:18:59 +0000 (09:18 +0200)
Change-Id: Ibf4edadd8ef700030880edd27a0e41741b151c9b

src/manager/crypto/tz-backend/internals.cpp
src/manager/crypto/tz-backend/internals.h
src/manager/crypto/tz-backend/obj.cpp
src/manager/crypto/tz-backend/obj.h
src/manager/crypto/tz-backend/tz-context.cpp
src/manager/crypto/tz-backend/tz-context.h
src/manager/service/ckm-logic.cpp

index 6e6cf69cf02efe1fa151c92b8cb2cda2d677f307..0008208c410aa613d6767d5fccca0d60a33982cb 100644 (file)
@@ -508,6 +508,48 @@ RawBuffer unwrapConcatenatedData(const RawBuffer &wrappingKeyId,
                                                                                                                           keySize);
 }
 
+RawBuffer encapsulateKey(const RawBuffer &publicKeyId,
+                                                const Pwd &publicKeyPwd,
+                                                const CryptoAlgorithm &params,
+                                                const Password &sharedSecretPwd,
+                                                const RawBuffer &sharedSecretIV,
+                                                RawBuffer &sharedSecretTag,
+                                                const RawBuffer &sharedSecretId)
+{
+       CKM::KemType kt = unpack<CKM::KemType>(params, ParamName::GEN_KEM_TYPE);
+       RawBuffer sharedSecretPwdBuf(sharedSecretPwd.begin(), sharedSecretPwd.end());
+
+       return TrustZoneContext::Instance().encapsulateKey(publicKeyId,
+                                                                                                          publicKeyPwd,
+                                                                                                          toTzKem(kt),
+                                                                                                          sharedSecretPwdBuf,
+                                                                                                          sharedSecretIV,
+                                                                                                          sharedSecretTag,
+                                                                                                          sharedSecretId);
+}
+
+void decapsulateKey(const RawBuffer &privateKeyId,
+                                       const Pwd &privateKeyPwd,
+                                       const CryptoAlgorithm &params,
+                                       const Password &sharedSecretPwd,
+                                       const RawBuffer &sharedSecretIV,
+                                       RawBuffer &sharedSecretTag,
+                                       const RawBuffer &sharedSecretId,
+                                       const RawBuffer &ciphertext)
+{
+       CKM::KemType kt = unpack<CKM::KemType>(params, ParamName::GEN_KEM_TYPE);
+       RawBuffer sharedSecretPwdBuf(sharedSecretPwd.begin(), sharedSecretPwd.end());
+
+       TrustZoneContext::Instance().decapsulateKey(privateKeyId,
+                                                                                               privateKeyPwd,
+                                                                                               toTzKem(kt),
+                                                                                               sharedSecretPwdBuf,
+                                                                                               sharedSecretIV,
+                                                                                               sharedSecretTag,
+                                                                                               sharedSecretId,
+                                                                                               ciphertext);
+}
+
 RawBuffer getData(const RawBuffer &dataId,
                                  const Pwd &pwd,
                                  const DataType &type)
index 14a79869fdaab7048b0939f7467353ed8f326624..eb945ad1d31b6b85c693d92239012855a6d9891e 100644 (file)
@@ -95,6 +95,23 @@ RawBuffer unwrapConcatenatedData(const RawBuffer &wrappingKeyId,
                                                                 const RawBuffer &encryptedKeyId,
                                                                 size_t keySize);
 
+RawBuffer encapsulateKey(const RawBuffer &publicKeyId,
+                                                const Pwd &publicKeyPwd,
+                                                const CryptoAlgorithm &params,
+                                                const Password &sharedSecretPwd,
+                                                const RawBuffer &sharedSecretIV,
+                                                RawBuffer &sharedSecretTag,
+                                                const RawBuffer &sharedSecretId);
+
+void decapsulateKey(const RawBuffer &privateKeyId,
+                                       const Pwd &privateKeyPwd,
+                                       const CryptoAlgorithm &params,
+                                       const Password &sharedSecretPwd,
+                                       const RawBuffer &sharedSecretIV,
+                                       RawBuffer &sharedSecretTag,
+                                       const RawBuffer &sharedSecretId,
+                                       const RawBuffer &ciphertext);
+
 RawBuffer getData(const RawBuffer &dataId,
                                  const Pwd &pwd,
                                  const DataType &type);
index b45ca747ef4d1fc82d528f8e4c9159d443fc1341..01667b84ded6afc115e132854cba0375302885c9 100644 (file)
@@ -26,6 +26,7 @@
 #include <tz-backend/ctx.h>
 #include <tz-backend/store.h>
 #include <tz-backend/internals.h>
+#include <dpl/log/log.h>
 
 namespace CKM {
 namespace Crypto {
@@ -71,6 +72,61 @@ Token BData::derive(const CryptoAlgorithm &alg, const Password &pass, const RawB
        return Token(backendId(), DataType(KeyType::KEY_AES), Store::pack(hash, pass, iv, tag));
 }
 
+std::tuple<Token, RawBuffer> BData::encapsulateKey(const CryptoAlgorithm &params,
+                                                                                                  const Token &,
+                                                                                                  const Password &,
+                                                                                                  const Password &sharedSecretPass,
+                                                                                                  const RawBuffer &sharedSecretHash)
+{
+       RawBuffer sharedSecretIV;
+       RawBuffer sharedSecretTag;
+
+       if (!sharedSecretPass.empty()) {
+               // IV is needed for data encryption with pwd
+               sharedSecretIV = Internals::generateIV();
+       }
+
+       RawBuffer ciphertext = Internals::encapsulateKey(getId(),
+                                                                                                        getPassword(),
+                                                                                                        params,
+                                                                                                        sharedSecretPass,
+                                                                                                        sharedSecretIV,
+                                                                                                        sharedSecretTag,
+                                                                                                        sharedSecretHash);
+
+       return std::make_tuple(Token(backendId(), DataType::KEY_AES, Store::pack(
+                                                  sharedSecretHash, sharedSecretPass, sharedSecretIV, sharedSecretTag)),
+                                                  ciphertext);
+}
+
+Token BData::decapsulateKey(const CryptoAlgorithm &params,
+                                                       const Token &,
+                                                       const Password &,
+                                                       const Password &sharedSecretPass,
+                                                       const RawBuffer &ciphertext,
+                                                       const RawBuffer &sharedSecretHash)
+{
+       RawBuffer sharedSecretIV;
+       RawBuffer sharedSecretTag;
+
+       if (!sharedSecretPass.empty()) {
+               // IV is needed for data encryption with pwd
+               sharedSecretIV = Internals::generateIV();
+       }
+
+       Internals::decapsulateKey(getId(),
+                                                         getPassword(),
+                                                         params,
+                                                         sharedSecretPass,
+                                                         sharedSecretIV,
+                                                         sharedSecretTag,
+                                                         sharedSecretHash,
+                                                         ciphertext);
+
+       return Token(backendId(), DataType::KEY_AES, Store::pack(
+                                sharedSecretHash, sharedSecretPass, sharedSecretIV, sharedSecretTag));
+}
+
 Token Key::unwrap(const CryptoAlgorithm &params,
                                  const Data &encryptedKey,
                                  const Password &pass,
@@ -296,6 +352,26 @@ std::tuple<Token, RawBuffer> Cert::unwrapConcatenated(const CryptoAlgorithm &,
        ThrowErr(Exc::Crypto::OperationNotSupported);
 }
 
+std::tuple<Token, RawBuffer> Cert::encapsulateKey(const CryptoAlgorithm &,
+                                                                                                 const Token &,
+                                                                                                 const Password &,
+                                                                                                 const Password &,
+                                                                                                 const RawBuffer &)
+{
+       ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
+Token Cert::decapsulateKey(const CryptoAlgorithm &,
+                                                  const Token &,
+                                                  const Password &,
+                                                  const Password &,
+                                                  const RawBuffer &,
+                                                  const RawBuffer &)
+{
+       ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
+
 } // namespace TZ
 } // namespace Crypto
 } // namespace CKM
index 70488e03eeb24ca817373764ebd587276b30b7f0..92bac22cc118a8a6a1651fa92ed436aac41cca09 100644 (file)
@@ -89,6 +89,19 @@ public:
        }
        Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
 
+       std::tuple<Token, RawBuffer> encapsulateKey(const CryptoAlgorithm &params,
+                                                                                               const Token &pubKey,
+                                                                                               const Password &pubKeyPass,
+                                                                                               const Password &sharedSecretPass,
+                                                                                               const RawBuffer &) override;
+
+       Token decapsulateKey(const CryptoAlgorithm &params,
+                                                const Token &privKey,
+                                                const Password &privKeyPass,
+                                                const Password &sharedSecretPass,
+                                                const RawBuffer &ciphertext,
+                                                const RawBuffer &) override;
+
 protected:
        int m_scheme;
        Pwd m_password;
@@ -178,6 +191,19 @@ public:
                                                                                                        const Password &,
                                                                                                        size_t,
                                                                                                        const RawBuffer &) override;
+
+       std::tuple<Token, RawBuffer> encapsulateKey(const CryptoAlgorithm &,
+                                                                                               const Token &,
+                                                                                               const Password &,
+                                                                                               const Password &,
+                                                                                               const RawBuffer &) override;
+
+       Token decapsulateKey(const CryptoAlgorithm &,
+                                                const Token &,
+                                                const Password &,
+                                                const Password &,
+                                                const RawBuffer &,
+                                                const RawBuffer &) override;
 };
 
 } // namespace TZ
index c04139e9138983cf478a409e8f12d329bc9a9c4b..4339647fa1aae838a36d7729e28b3fb31e96f5bd 100644 (file)
@@ -949,6 +949,103 @@ RawBuffer TrustZoneContext::unwrapConcatenatedData(const RawBuffer &wrappingKeyI
        return userData;
 }
 
+RawBuffer TrustZoneContext::encapsulateKey(const RawBuffer &publicKeyId,
+                                                                                  const Pwd &publicKeyPwd,
+                                                                                  tz_kem kemType,
+                                                                                  const RawBuffer &sharedSecretPwdBuf,
+                                                                                  const RawBuffer &sharedSecretIV,
+                                                                                  RawBuffer &sharedSecretTag,
+                                                                                  const RawBuffer &sharedSecretId)
+{
+       // command ID = CMD_ENCAPSULATE_KEY
+       LogDebug("TrustZoneContext::encapsulateKey");
+
+       TZSerializer sIn = makeSerializer(publicKeyId,
+                                                                         publicKeyPwd,
+                                                                         EncPwd{sharedSecretPwdBuf, sharedSecretIV},
+                                                                         sharedSecretId);
+
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TZSerializer sOut;
+       uint32_t outMemorySize = 0;
+       switch (kemType)
+       {
+       case ML_KEM_768:
+               outMemorySize = 1088;
+               break;
+       case ML_KEM_1024:
+               outMemorySize = 1568;
+               break;
+       default:
+               break;
+       }
+       sOut.Push(new TZSerializableBinary(outMemorySize, false));
+       if (!sharedSecretPwdBuf.empty()) {
+               uint32_t tagSizeBytes = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
+               sOut.Push(new TZSerializableBinary(tagSizeBytes));
+       }
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+       op.params[0].value.a = static_cast<uint32_t>(kemType);
+
+       Execute(CMD_ENCAPSULATE_KEY, &op);
+
+       sOut.Deserialize(outMemory);
+       RawBuffer ciphertext;
+       sOut.Pull(ciphertext);
+
+       if (!sharedSecretPwdBuf.empty()) {
+               sOut.Pull(sharedSecretTag);
+       }
+
+       return ciphertext;
+}
+
+void TrustZoneContext::decapsulateKey(const RawBuffer &privateKeyId,
+                                                                         const Pwd &privateKeyPwd,
+                                                                         tz_kem kemType,
+                                                                         const RawBuffer &sharedSecretPwdBuf,
+                                                                         const RawBuffer &sharedSecretIV,
+                                                                         RawBuffer &sharedSecretTag,
+                                                                         const RawBuffer &sharedSecretId,
+                                                                         const RawBuffer &ciphertext)
+{
+       // command ID = CMD_DECAPSULATE_KEY
+       LogDebug("TrustZoneContext::decapsulateKey");
+
+       TZSerializer sIn = makeSerializer(privateKeyId,
+                                                                         privateKeyPwd,
+                                                                         EncPwd{sharedSecretPwdBuf, sharedSecretIV},
+                                                                         sharedSecretId,
+                                                                         ciphertext);
+
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TZSerializer sOut;
+       if (!sharedSecretPwdBuf.empty()) {
+               uint32_t tagSizeBytes = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
+               sOut.Push(new TZSerializableBinary(tagSizeBytes));
+       }
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
+       if (!sharedSecretPwdBuf.empty())
+               op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+
+       op.params[0].value.a = static_cast<uint32_t>(kemType);
+
+       Execute(CMD_DECAPSULATE_KEY, &op);
+
+       if (!sharedSecretPwdBuf.empty()) {
+               sOut.Deserialize(outMemory);
+               sOut.Pull(sharedSecretTag);
+       }
+}
+
 void TrustZoneContext::GetDataSize(const RawBuffer &dataId,
                                                                   const Pwd &pwd,
                                                                   const tz_data_type type,
@@ -997,7 +1094,6 @@ void TrustZoneContext::getData(const RawBuffer &dataId,
        sOut.Pull(data);
 }
 
-
 void TrustZoneContext::destroyData(const RawBuffer &dataId)
 {
        //      command ID = CMD_DESTROY_DATA
index 768604fcaa6bd3677124b1bbcc6e54de20923153..b5dacb559804311dc940cba3aecdbed9b74cebea 100644 (file)
@@ -143,6 +143,23 @@ public:
                                                                         const RawBuffer &encryptedKeyId,
                                                                         size_t keySize);
 
+       RawBuffer encapsulateKey(const RawBuffer &publicKeyId,
+                                                        const Pwd &publicKeyPwd,
+                                                        tz_kem kemType,
+                                                        const RawBuffer &sharedSecretPwdBuf,
+                                                        const RawBuffer &sharedSecretIV,
+                                                        RawBuffer &sharedSecretTag,
+                                                        const RawBuffer &sharedSecretId);
+
+       void decapsulateKey(const RawBuffer &privateKeyId,
+                                               const Pwd &privateKeyPwd,
+                                               tz_kem kemType,
+                                               const RawBuffer &sharedSecretPwdBuf,
+                                               const RawBuffer &sharedSecretIV,
+                                               RawBuffer &sharedSecretTag,
+                                               const RawBuffer &sharedSecretId,
+                                               const RawBuffer &ciphertext);
+
        void executeCrypt(tz_command cmd,
                                        tz_algo_type algo,
                                        tz_hash_type hash,
index 9bf0716e74090950e3082c15582de51f86c90a01..899102fb08ecd3276d16005ab5663737f6756239 100644 (file)
@@ -1879,7 +1879,6 @@ RawBuffer CKMLogic::decapsulateKey(
 
                retCode2 = readRowHelper(false, cred, DataType::KEY_KEM_PRIVATE, privateKeyAlias, privateKeyOwner,
                                                                 privateKeyPassword, privateKeyRow, privateKeyType);
-
                if (retCode2 != CKM_API_SUCCESS)
                        return retCode2;