Add ML-KEM derive hybrid tz-backend implementation 54/316554/15
authorDariusz Michaluk <d.michaluk@samsung.com>
Thu, 22 Aug 2024 11:44:31 +0000 (13:44 +0200)
committerJan Wojtkowski <j.wojtkowski@samsung.com>
Tue, 3 Sep 2024 07:19:07 +0000 (09:19 +0200)
Change-Id: I1b807e0fcef017c9ee8725230eb7430a49f74d39

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

index 0008208c410aa613d6767d5fccca0d60a33982cb..2f7afe647eba81c250141d7bf467aaebc4e48fbf 100644 (file)
@@ -1050,6 +1050,78 @@ void deriveKBKDF(const RawBuffer &secretId,
                                                                                          keyHash);
 }
 
+void deriveHybridKBKDF(const RawBuffer &firstSecretId,
+                                          const Pwd &firstSecretPwd,
+                                          const RawBuffer &secondSecretId,
+                                          const Pwd &secondSecretPwd,
+                                          const CryptoAlgorithm &alg,
+                                          const Password &keyPwd,
+                                          const RawBuffer &keyPwdIV,
+                                          RawBuffer &keyTag,
+                                          const RawBuffer &keyHash)
+{
+       RawBuffer label, context, fixed;
+       size_t rlenBits = 32, llenBits = 32, tmp;
+       bool hasLabel = alg.getParam(ParamName::KBKDF_LABEL, label);
+       bool hasContext = alg.getParam(ParamName::KBKDF_CONTEXT, context);
+       bool hasFixed = alg.getParam(ParamName::KBKDF_FIXED_INPUT, fixed);
+       auto counterLocation = unpack<KbkdfCounterLocation>(alg, ParamName::KBKDF_COUNTER_LOCATION);
+       auto mode = unpack<KbkdfMode>(alg, ParamName::KBKDF_MODE);
+       auto prf = unpack<KdfPrf>(alg, ParamName::KDF_PRF);
+       auto length = unpack<size_t>(alg, ParamName::KDF_LEN);
+       alg.getParam(ParamName::KBKDF_RLEN, rlenBits);
+       bool hasLLen = alg.getParam(ParamName::KBKDF_LLEN, llenBits);
+       bool noSeparator = alg.getParam(ParamName::KBKDF_NO_SEPARATOR, tmp);
+
+       if (counterLocation != KbkdfCounterLocation::BEFORE_FIXED &&
+               counterLocation != KbkdfCounterLocation::MIDDLE_FIXED &&
+               counterLocation != KbkdfCounterLocation::AFTER_FIXED)
+               ThrowErr(Exc::Crypto::InputParam, "Invalid counter location");
+
+       if (mode != KbkdfMode::COUNTER)
+               ThrowErr(Exc::Crypto::InputParam, "Invalid mode");
+
+       if (prf != KdfPrf::HMAC_SHA256 && prf != KdfPrf::HMAC_SHA384 && prf != KdfPrf::HMAC_SHA512)
+               ThrowErr(Exc::Crypto::InputParam, "Invalid pseudo random function");
+
+       if (hasFixed) {
+               if (hasLabel || hasContext || noSeparator || hasLLen ||
+                       counterLocation == KbkdfCounterLocation::MIDDLE_FIXED)
+                       ThrowErr(Exc::Crypto::InputParam, "Unexpected parameters for fixed input mode.");
+       } else {
+               if (!hasLabel || !hasContext)
+                       ThrowErr(Exc::Crypto::InputParam, "Missing label and/or context.");
+               if (llenBits != 0 && llenBits != 8 && llenBits != 16 && llenBits != 24 && llenBits != 32)
+                       ThrowErr(Exc::Crypto::InputParam, "Invalid llen value");
+       }
+       if (length != 16 && length != 24 && length != 32)
+               ThrowErr(Exc::Crypto::InputParam, "Invalid key length");
+
+       if (rlenBits != 8 && rlenBits != 16 && rlenBits != 24 && rlenBits != 32)
+               ThrowErr(Exc::Crypto::InputParam, "Invalid rlen value");
+
+       RawBuffer keyPwdBuf(keyPwd.begin(), keyPwd.end());
+
+       TrustZoneContext::Instance().executeHybridKbkdf(firstSecretId,
+                                                                                                       firstSecretPwd,
+                                                                                                       secondSecretId,
+                                                                                                       secondSecretPwd,
+                                                                                                       length,
+                                                                                                       label,
+                                                                                                       context,
+                                                                                                       fixed,
+                                                                                                       toTzPrf(prf),
+                                                                                                       toTzKbkdfMode(mode),
+                                                                                                       toTzCtrLoc(counterLocation),
+                                                                                                       rlenBits,
+                                                                                                       llenBits,
+                                                                                                       noSeparator,
+                                                                                                       keyPwdBuf,
+                                                                                                       keyPwdIV,
+                                                                                                       keyTag,
+                                                                                                       keyHash);
+}
+
 size_t maxChunkSize()
 {
        return TrustZoneContext::Instance().getMaxChunkSize();
index eb945ad1d31b6b85c693d92239012855a6d9891e..7a5fc13d89faf6a9a0e6fcf6cc1a2112c40ba192 100644 (file)
@@ -201,6 +201,16 @@ void deriveKBKDF(const RawBuffer &secretId,
                                 RawBuffer &keyTag,
                                 const RawBuffer &keyHash);
 
+void deriveHybridKBKDF(const RawBuffer &firstSecretId,
+                                          const Pwd &firstSecretPwd,
+                                          const RawBuffer &secondSecretId,
+                                          const Pwd &secondSecretPwd,
+                                          const CryptoAlgorithm &alg,
+                                          const Password &keyPwd,
+                                          const RawBuffer &keyPwdIV,
+                                          RawBuffer &keyTag,
+                                          const RawBuffer &keyHash);
+
 size_t maxChunkSize();
 } // namespace Internals
 } // namespace TZ
index 01667b84ded6afc115e132854cba0375302885c9..2d30c98264702937e3b7bdfa9085c734301f3b9a 100644 (file)
@@ -127,6 +127,49 @@ Token BData::decapsulateKey(const CryptoAlgorithm &params,
                                 sharedSecretHash, sharedSecretPass, sharedSecretIV, sharedSecretTag));
 }
 
+Token BData::deriveHybrid(const CryptoAlgorithm &alg,
+                                                 const Token &,
+                                                 const Password &,
+                                                 const Token &secondKey,
+                                                 const Password &secondPass,
+                                                 const Password &newKeyPass,
+                                                 const RawBuffer &hash)
+{
+       auto algo = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
+       if (algo != AlgoType::KBKDF)
+               ThrowErr(Exc::Crypto::InputParam, "Wrong algorithm");
+
+       RawBuffer newKeyIV;
+       RawBuffer newKeyTag;
+       if (!newKeyPass.empty()) {
+               // IV is needed for key encryption
+               newKeyIV = Internals::generateIV();
+       }
+
+       int secondKeyScheme;
+       RawBuffer secondKeyId;
+       RawBuffer secondKeyIV;
+       RawBuffer secondKeyTag;
+       Store::unpack(secondKey.data,
+                                 secondPass,
+                                 secondKeyScheme,
+                                 secondKeyId,
+                                 secondKeyIV,
+                                 secondKeyTag);
+
+       Internals::deriveHybridKBKDF(getId(),
+                                                                getPassword(),
+                                                                secondKeyId,
+                                                                Pwd(secondPass, secondKeyIV, secondKeyTag),
+                                                                alg,
+                                                                newKeyPass,
+                                                                newKeyIV,
+                                                                newKeyTag,
+                                                                hash);
+
+       return Token(backendId(), DataType(KeyType::KEY_AES), Store::pack(hash, newKeyPass, newKeyIV, newKeyTag));
+}
+
 Token Key::unwrap(const CryptoAlgorithm &params,
                                  const Data &encryptedKey,
                                  const Password &pass,
@@ -229,6 +272,17 @@ Token AKey::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBu
        return Token(backendId(), DataType::BINARY_DATA, Store::pack(hash, pass, iv, tag));
 }
 
+Token AKey::deriveHybrid(const CryptoAlgorithm &,
+                                                const Token &,
+                                                const Password &,
+                                                const Token &,
+                                                const Password &,
+                                                const Password &,
+                                                const RawBuffer &)
+{
+       ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
 GCtxShPtr AKey::initContext(const CryptoAlgorithm &, bool)
 {
        ThrowErr(Exc::Crypto::OperationNotSupported);
index 92bac22cc118a8a6a1651fa92ed436aac41cca09..790b66d4dbbbf73d894f1114b159cddb9622f7c6 100644 (file)
@@ -88,6 +88,13 @@ public:
                return m_password;
        }
        Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
+       Token deriveHybrid(const CryptoAlgorithm &alg,
+                                          const Token &firstKey,
+                                          const Password &firstPass,
+                                          const Token &secondKey,
+                                          const Password &secondPass,
+                                          const Password &newKeyPass,
+                                          const RawBuffer &hash) override;
 
        std::tuple<Token, RawBuffer> encapsulateKey(const CryptoAlgorithm &params,
                                                                                                const Token &pubKey,
@@ -153,6 +160,13 @@ public:
        RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) override;
        RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) override;
        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;
        GCtxShPtr initContext(const CryptoAlgorithm &, bool) override;
 
        RawBuffer wrapConcatenated(const CryptoAlgorithm &params,
index 4339647fa1aae838a36d7729e28b3fb31e96f5bd..bb455e1d030af5028e15d090d39829c72eb44d90 100644 (file)
@@ -1212,6 +1212,69 @@ void TrustZoneContext::executeKbkdf(const RawBuffer& secretId,
        LogDebug("Derived object ID is (hex): " << rawToHexString(keyHash));
 }
 
+void TrustZoneContext::executeHybridKbkdf(const RawBuffer& firstSecretId,
+                                                                                 const Pwd& firstSecretPwd,
+                                                                                 const RawBuffer& secondSecretId,
+                                                                                 const Pwd& secondSecretPwd,
+                                                                                 size_t length,
+                                                                                 const RawBuffer& label,
+                                                                                 const RawBuffer& context,
+                                                                                 const RawBuffer& fixed,
+                                                                                 tz_prf prf,
+                                                                                 tz_kbkdf_mode mode,
+                                                                                 tz_kbkdf_ctr_loc location,
+                                                                                 size_t rlen,
+                                                                                 size_t llen,
+                                                                                 bool noSeparator,
+                                                                                 const RawBuffer &keyPwdBuf,
+                                                                                 const RawBuffer &keyPwdIV,
+                                                                                 RawBuffer &keyTag,
+                                                                                 const RawBuffer &keyHash)
+{
+       // command ID = CMD_DERIVE_HYBRID
+       LogDebug("TrustZoneContext::executeHybridKbkdf");
+
+       auto sIn = makeSerializer(firstSecretId,
+                                                         firstSecretPwd,
+                                                         secondSecretId,
+                                                         secondSecretPwd,
+                                                         length,
+                                                         label,
+                                                         context,
+                                                         fixed,
+                                                         prf,
+                                                         mode,
+                                                         location,
+                                                         rlen,
+                                                         llen,
+                                                         noSeparator,
+                                                         EncPwd{keyPwdBuf, keyPwdIV}, keyHash);
+
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
+
+       TZSerializer sOut;
+       if (!keyPwdBuf.empty()) {
+               sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
+       }
+
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+
+       TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
+       if (!keyPwdBuf.empty())
+               op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+       op.params[0].value.a = ALGO_KBKDF_DRV;
+
+       Execute(CMD_DERIVE_HYBRID, &op);
+
+       if (!keyPwdBuf.empty()) {
+               sOut.Deserialize(outMemory);
+               sOut.Pull(keyTag);
+       }
+
+       LogDebug("Derived object ID is (hex): " << rawToHexString(keyHash));
+}
+
 uint32_t TrustZoneContext::getMaxChunkSize()
 {
        // command ID = CMD_GET_MAX_CHUNK_SIZE
index b5dacb559804311dc940cba3aecdbed9b74cebea..ce82b6c335a5a44aa20c51d9914e7f6cd7078c21 100644 (file)
@@ -253,6 +253,25 @@ public:
                                          RawBuffer &keyTag,
                                          const RawBuffer &keyHash);
 
+       void executeHybridKbkdf(const RawBuffer& firstSecretId,
+                                                       const Pwd& firstSecretPwd,
+                                                       const RawBuffer& secondSecretId,
+                                                       const Pwd& secondSecretPwd,
+                                                       size_t length,
+                                                       const RawBuffer& label,
+                                                       const RawBuffer& context,
+                                                       const RawBuffer& fixed,
+                                                       tz_prf prf,
+                                                       tz_kbkdf_mode mode,
+                                                       tz_kbkdf_ctr_loc location,
+                                                       size_t rlen,
+                                                       size_t llen,
+                                                       bool noSeparator,
+                                                       const RawBuffer &keyPwdBuf,
+                                                       const RawBuffer &keyPwdIV,
+                                                       RawBuffer &keyTag,
+                                                       const RawBuffer &keyHash);
+
        uint32_t getMaxChunkSize();
 
 private: