From 7959a37ba0936508894ee23ab637e9c7f744e35a Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 22 Mar 2023 09:48:31 +0100 Subject: [PATCH] Key unwrapping implementation in TZ backend Change-Id: I1ada1788c7f436b9cdd22cc7734eb3ab0159c544 --- src/manager/crypto/tz-backend/internals.cpp | 72 ++++++++++++++++++++++++++++ src/manager/crypto/tz-backend/internals.h | 9 ++++ src/manager/crypto/tz-backend/obj.cpp | 36 ++++++++++++++ src/manager/crypto/tz-backend/obj.h | 11 +++++ src/manager/crypto/tz-backend/tz-context.cpp | 51 ++++++++++++++++++++ src/manager/crypto/tz-backend/tz-context.h | 13 +++++ 6 files changed, 192 insertions(+) diff --git a/src/manager/crypto/tz-backend/internals.cpp b/src/manager/crypto/tz-backend/internals.cpp index 5b8ad1e..cec70b8 100644 --- a/src/manager/crypto/tz-backend/internals.cpp +++ b/src/manager/crypto/tz-backend/internals.cpp @@ -151,6 +151,8 @@ namespace Crypto { namespace TZ { namespace Internals { +namespace { + tz_algo_type getGenSKeyType(AlgoType type) { switch (type) @@ -189,6 +191,44 @@ tz_hash_type getHashType(HashAlgorithm hash) } } +void decompose(const CryptoAlgorithm &alg, + AlgoType &algo, + uint32_t &ctrLenOrTagSizeBits, + RawBuffer &iv, + RawBuffer &aad) +{ + algo = unpack(alg, ParamName::ALGO_TYPE); + switch (algo) { + case AlgoType::AES_CTR: + iv = unpack(alg, ParamName::ED_IV); + ctrLenOrTagSizeBits = unpack(alg, ParamName::ED_CTR_LEN); + // counter length is in bits + if (ctrLenOrTagSizeBits != Params::DEFAULT_AES_IV_LEN * 8) { + LogError("CTR length invalid: " << std::to_string(ctrLenOrTagSizeBits)); + ThrowErr(Exc::Crypto::InputParam, "Invalid CTR length"); + } + break; + case AlgoType::AES_CBC: + iv = unpack(alg, ParamName::ED_IV); + break; + case AlgoType::AES_CFB: + iv = unpack(alg, ParamName::ED_IV); + break; + case AlgoType::AES_GCM: + iv = unpack(alg, ParamName::ED_IV); + alg.getParam(ParamName::ED_TAG_LEN, ctrLenOrTagSizeBits); + alg.getParam(ParamName::ED_AAD, aad); + break; + case AlgoType::RSA_OAEP: + break; + default: + ThrowErr(Exc::Crypto::InputParam, "Invalid decryption algorithm"); + break; + } +} + +} // namespace + RawBuffer generateIV() { RawBuffer result; @@ -324,6 +364,38 @@ void importData(const Data &data, hash); } +void importWrappedKey(const RawBuffer &wrappingKey, + const Pwd &wrappingKeyPwd, + const CryptoAlgorithm &alg, + const Data &encryptedKey, + const Password &encryptedKeyPassword, + const RawBuffer &encryptedKeyIV, + RawBuffer &encryptedKeyTag, + const RawBuffer &encryptedKeyId) +{ + RawBuffer encryptedKeyPwdBuf(encryptedKeyPassword.begin(), encryptedKeyPassword.end()); + + AlgoType algo; + uint32_t ctrLenOrTagSizeBits = 0; + RawBuffer iv; + RawBuffer aad; + decompose(alg, algo, ctrLenOrTagSizeBits, iv, aad); + + // TODO it is awful! + TrustZoneContext::Instance().importWrappedKey(wrappingKey, + wrappingKeyPwd, + getAlgType(algo), + iv, + ctrLenOrTagSizeBits, + aad, + toTzDataType(encryptedKey.type), + encryptedKey.data, + encryptedKeyPwdBuf, + encryptedKeyIV, + encryptedKeyTag, + encryptedKeyId); +} + RawBuffer getData(const RawBuffer &dataId, const Pwd &pwd) { diff --git a/src/manager/crypto/tz-backend/internals.h b/src/manager/crypto/tz-backend/internals.h index bdfcc03..77b8c36 100644 --- a/src/manager/crypto/tz-backend/internals.h +++ b/src/manager/crypto/tz-backend/internals.h @@ -62,6 +62,15 @@ void importData(const Data &key, RawBuffer &tag, const RawBuffer &hash); +void importWrappedKey(const RawBuffer &wrappingKey, + const Pwd &wrappingKeyPwd, + const CryptoAlgorithm &alg, + const Data &encryptedKey, + const Password &encryptedKeyPassword, + const RawBuffer &encryptedKeyIV, + RawBuffer &encryptedKeyTag, + const RawBuffer &encryptedKeyId); + RawBuffer getData(const RawBuffer &dataId, const Pwd &pwd); diff --git a/src/manager/crypto/tz-backend/obj.cpp b/src/manager/crypto/tz-backend/obj.cpp index 86ac7a6..717c012 100644 --- a/src/manager/crypto/tz-backend/obj.cpp +++ b/src/manager/crypto/tz-backend/obj.cpp @@ -68,6 +68,35 @@ Token BData::derive(const CryptoAlgorithm &alg, const Password &pass, const RawB return Token(backendId(), DataType(KeyType::KEY_AES), Store::pack(hash, pass, iv, tag)); } +Token Key::unwrap(const CryptoAlgorithm ¶ms, + const Data &encryptedKey, + const Password &pass, + const RawBuffer &hash) +{ + + if (!encryptedKey.type.isKey() || encryptedKey.type.isEllipticCurve()) + ThrowErr(Exc::Crypto::DataTypeNotSupported, "Invalid data provided for import"); + + RawBuffer passIV; + RawBuffer tag; + + if (!pass.empty()) { + // IV is needed for data encryption with pwd + passIV = Internals::generateIV(); + } + + Internals::importWrappedKey(getBinary(), + getPassword(), + params, + encryptedKey, + pass, + passIV, + tag, + hash); + + return Token(backendId(), encryptedKey.type, Store::pack(hash, pass, passIV, tag)); +} + RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data) { return Internals::symmetricEncrypt(getBinary(), getPassword(), alg, data); @@ -134,6 +163,13 @@ int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, return Internals::verify(getBinary(), getPassword(), algWithType, message, sign); } +Token Cert::unwrap(const CryptoAlgorithm &, + const Data &, + const Password &, + const RawBuffer &) +{ + ThrowErr(Exc::Crypto::OperationNotSupported); +} } // namespace TZ } // namespace Crypto diff --git a/src/manager/crypto/tz-backend/obj.h b/src/manager/crypto/tz-backend/obj.h index 77b3be8..96e4efc 100644 --- a/src/manager/crypto/tz-backend/obj.h +++ b/src/manager/crypto/tz-backend/obj.h @@ -21,6 +21,7 @@ #pragma once #include +#include #include namespace CKM { @@ -90,6 +91,11 @@ public: return m_password; } + Token unwrap(const CryptoAlgorithm ¶ms, + const Data &encryptedKey, + const Password &pass, + const RawBuffer &hash) override; + protected: int m_scheme; Pwd m_password; @@ -122,6 +128,11 @@ class Cert : public AKey { public: Cert(CryptoBackend backendId, int scheme, RawBuffer buffer, Pwd pwd, DataType dataType) : AKey(backendId, scheme, std::move(buffer), std::move(pwd), dataType) {} + + Token unwrap(const CryptoAlgorithm &, + const Data &, + const Password &, + const RawBuffer &) override; }; } // namespace TZ diff --git a/src/manager/crypto/tz-backend/tz-context.cpp b/src/manager/crypto/tz-backend/tz-context.cpp index a058e1b..a998bc9 100644 --- a/src/manager/crypto/tz-backend/tz-context.cpp +++ b/src/manager/crypto/tz-backend/tz-context.cpp @@ -599,6 +599,57 @@ void TrustZoneContext::importData( LogDebug("Imported object ID is (hex): " << rawToHexString(hash)); } +void TrustZoneContext::importWrappedKey(const RawBuffer &wrappingKey, + const Pwd &wrappingKeyPwd, + tz_algo_type algo, + const RawBuffer &iv, + const uint32_t ctrLenOrTagSizeBits, + const RawBuffer &aad, + const tz_data_type encryptedKeyType, + const RawBuffer &encryptedKey, + const RawBuffer &encryptedKeyPwdBuf, + const RawBuffer &encryptedKeyIV, + RawBuffer &encryptedKeyTag, + const RawBuffer &encryptedKeyId) +{ + // command ID = CMD_IMPORT_WRAPPED_KEY + LogDebug("TrustZoneContext::importWrappedKey encryptedKey size = [" << encryptedKey.size() << "]"); + + auto sIn = makeSerializer(wrappingKey, + wrappingKeyPwd, + algo, + iv, + ctrLenOrTagSizeBits, + aad, + encryptedKeyType, + encryptedKey, + EncPwd{encryptedKeyPwdBuf, encryptedKeyIV}, + encryptedKeyId); + + TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); + sIn.Serialize(inMemory); + + TZSerializer sOut; + if (!encryptedKeyPwdBuf.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 (!encryptedKeyPwdBuf.empty()) + op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory); + + Execute(CMD_IMPORT_WRAPPED_KEY, &op); + + if (!encryptedKeyPwdBuf.empty()) { + sOut.Deserialize(outMemory); + sOut.Pull(encryptedKeyTag); + } + + LogDebug("Imported object ID is (hex): " << rawToHexString(encryptedKeyId)); +} + void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize) { // command ID = CMD_GET_DATA_SIZE diff --git a/src/manager/crypto/tz-backend/tz-context.h b/src/manager/crypto/tz-backend/tz-context.h index 2a1cff3..71ef9c9 100644 --- a/src/manager/crypto/tz-backend/tz-context.h +++ b/src/manager/crypto/tz-backend/tz-context.h @@ -89,6 +89,19 @@ public: RawBuffer &pwdTag, const RawBuffer &hash); + void importWrappedKey(const RawBuffer &wrappingKey, + const Pwd &wrappingKeyPwd, + tz_algo_type algo, + const RawBuffer &iv, + const uint32_t ctrLenOrTagSizeBits, + const RawBuffer &aad, + const tz_data_type encryptedKeyType, + const RawBuffer &encryptedKey, + const RawBuffer &encryptedKeyPwdBuf, + const RawBuffer &encryptedKeyIV, + RawBuffer &encryptedKeyTag, + const RawBuffer &encryptedKeyHash); + void executeCrypt(tz_command cmd, tz_algo_type algo, const RawBuffer &keyId, -- 2.7.4