From: Krzysztof Jackiewicz Date: Fri, 9 Jun 2023 08:51:08 +0000 (+0200) Subject: Cipher API implementation in TZ backend X-Git-Tag: accepted/tizen/6.0/unified/20230621.004733~1^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=06d7da75c5abef7127e10a6b7d1e0f5ea703172d;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git Cipher API implementation in TZ backend Change-Id: I2510dfb8f7e1722ee300edce6e983075a0c5303a --- diff --git a/src/manager/crypto/tz-backend/ctx.cpp b/src/manager/crypto/tz-backend/ctx.cpp new file mode 100644 index 0000000..1fcc80b --- /dev/null +++ b/src/manager/crypto/tz-backend/ctx.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#include +#include +#include + +namespace CKM { +namespace Crypto { + +void CipherCtx::customize(const CryptoAlgorithm& algo) +{ + RawBuffer aad; + if (!algo.getParam(ParamName::ED_AAD, aad)) + ThrowErr(Exc::InputParam, "Missing AAD"); + + Internals::addAAD(m_opId, aad); +} + +RawBuffer CipherCtx::update(const RawBuffer& input) +{ + return Internals::updateCipher(input); +} + +RawBuffer CipherCtx::finalize(const RawBuffer& input) +{ + /* + * It is assumed that finalize for GCM encryption will return the GCM tag only. + * In case of GCM decryption the tag will be passed as finalizeCipher argument. + */ + return Internals::finalizeCipher(input); +} + +} // namespace Crypto +} // namespace CKM diff --git a/src/manager/crypto/tz-backend/ctx.h b/src/manager/crypto/tz-backend/ctx.h new file mode 100644 index 0000000..d12b5ce --- /dev/null +++ b/src/manager/crypto/tz-backend/ctx.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +#pragma once + +#include +#include + +namespace CKM { +namespace Crypto { + +class CipherCtx : public GCtx { +public: + explicit CipherCtx(uint32_t opId) : m_opId(opId) {} + + void customize(const CryptoAlgorithm& algo) override; + RawBuffer update(const RawBuffer& input) override; + RawBuffer finalize(const RawBuffer& input) override; + +private: + uint32_t m_opId; +}; + +} // namespace Crypto +} // namespace CKM diff --git a/src/manager/crypto/tz-backend/internals.cpp b/src/manager/crypto/tz-backend/internals.cpp index 51bce1d..aca0124 100644 --- a/src/manager/crypto/tz-backend/internals.cpp +++ b/src/manager/crypto/tz-backend/internals.cpp @@ -659,6 +659,57 @@ RawBuffer asymmetricDecrypt(const RawBuffer &key, "Incorrect algorithm provided for asymmetric crypto operation"); } +uint32_t initCipher(const RawBuffer &key, + const Pwd &pwd, + const CryptoAlgorithm &alg, + bool encrypt) +{ + AlgoType algo = unpack(alg, ParamName::ALGO_TYPE); + + switch (algo) + { + case AlgoType::AES_GCM: { + int tagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS; + alg.getParam(ParamName::ED_TAG_LEN, tagSizeBits); + RawBuffer aad; + alg.getParam(ParamName::ED_AAD, aad); + return TrustZoneContext::Instance().initGcmCipher(encrypt ? CIPHER_ENCRYPT : CIPHER_DECRYPT, + key, + pwd, + unpack(alg, ParamName::ED_IV), + tagSizeBits, + aad); + } + case AlgoType::AES_CBC: + case AlgoType::AES_CTR: + case AlgoType::AES_CFB: + // TODO optionally implement above modes as well + default: + break; + }; + + ThrowErr(Exc::Crypto::OperationNotSupported, + "Incorrect algorithm provided for symmetric crypto operation"); +} + +void addAAD(uint32_t opId, + const RawBuffer &aad) +{ + TrustZoneContext::Instance().addGcmAAD(opId, aad); +} + +RawBuffer updateCipher(uint32_t opId, + const RawBuffer &data) +{ + return TrustZoneContext::Instance().updateGcmCipher(opId, data); +} + +RawBuffer finalizeCipher(uint32_t opId, + const RawBuffer &data) +{ + return TrustZoneContext::Instance().finalizeGcmCipher(opId, data); +} + RawBuffer sign(const RawBuffer &pkey, const Pwd &pwd, const CryptoAlgorithm &alg, diff --git a/src/manager/crypto/tz-backend/internals.h b/src/manager/crypto/tz-backend/internals.h index 5c1596c..cb6b814 100644 --- a/src/manager/crypto/tz-backend/internals.h +++ b/src/manager/crypto/tz-backend/internals.h @@ -122,6 +122,20 @@ RawBuffer decryptDataAesGcm(const RawBuffer &key, const RawBuffer &data, const RawBuffer &aad = RawBuffer()); +uint32_t initCipher(const RawBuffer &key, + const Pwd &pwd, + const CryptoAlgorithm &alg, + bool encrypt); + +void addAAD(uint32_t opId, + const RawBuffer &aad); + +RawBuffer updateCipher(uint32_t opId, + const RawBuffer &data); + +RawBuffer finalizeCipher(uint32_t opId, + const RawBuffer &data); + RawBuffer sign(const RawBuffer &pkey, const Pwd &pwd, const CryptoAlgorithm &alg, diff --git a/src/manager/crypto/tz-backend/obj.cpp b/src/manager/crypto/tz-backend/obj.cpp index 94a4c58..d743753 100644 --- a/src/manager/crypto/tz-backend/obj.cpp +++ b/src/manager/crypto/tz-backend/obj.cpp @@ -18,9 +18,12 @@ * @author Lukasz Kostyra (l.kostyra@samsung.com) * @version 1.0 */ +#include +#include #include #include #include +#include #include #include @@ -129,6 +132,13 @@ RawBuffer SKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher) return Internals::symmetricDecrypt(getBinary(), getPassword(), alg, cipher); } +GCtxShPtr SKey::initContext(const CryptoAlgorithm &alg, bool onward) +{ + auto opId = Internals::initCipher(getBinary(), getPassword(), alg, onward); + + return std::make_shared(opId); +} + RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data) { return Internals::asymmetricEncrypt(getBinary(), getPassword(), alg, data); @@ -162,6 +172,11 @@ Token AKey::derive(const CryptoAlgorithm &alg, const Password &pass, const RawBu return Token(backendId(), DataType::BINARY_DATA, Store::pack(hash, pass, iv, tag)); } +GCtxShPtr AKey::initContext(const CryptoAlgorithm &, bool) +{ + ThrowErr(Exc::Crypto::OperationNotSupported); +} + RawBuffer AKey::sign( const CryptoAlgorithm &alg, const RawBuffer &message) diff --git a/src/manager/crypto/tz-backend/obj.h b/src/manager/crypto/tz-backend/obj.h index 13f63a0..dd35a8e 100644 --- a/src/manager/crypto/tz-backend/obj.h +++ b/src/manager/crypto/tz-backend/obj.h @@ -22,6 +22,7 @@ #include #include +#include #include namespace CKM { @@ -113,6 +114,7 @@ public: RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) override; RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) override; + GCtxShPtr initContext(const CryptoAlgorithm &, bool) override; }; class AKey : public Key { @@ -126,6 +128,7 @@ public: RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) override; RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) override; Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override; + GCtxShPtr initContext(const CryptoAlgorithm &, bool) override; }; class Cert : public AKey { diff --git a/src/manager/crypto/tz-backend/tz-context.cpp b/src/manager/crypto/tz-backend/tz-context.cpp index 06e9706..e8c500b 100644 --- a/src/manager/crypto/tz-backend/tz-context.cpp +++ b/src/manager/crypto/tz-backend/tz-context.cpp @@ -476,6 +476,91 @@ void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId, sOut.Pull(out); } +uint32_t TrustZoneContext::initGcmCipher(uint32_t encrypt, + const RawBuffer &keyId, + const Pwd &pwd, + const RawBuffer &iv, + int tagSizeBits, + const RawBuffer &aad) +{ + // command ID = CMD_CIPHER_INIT (from km_ta_defines.h) + if (keyId.size() != KM_KEY_ID_SIZE) { + ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer"); + } + + auto sIn = makeSerializer(pwd, iv, keyId, aad, tagSizeBits); + TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); + sIn.Serialize(inMemory); + + TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory); + op.params[0].value.a = ALGO_AES_GCM; + op.params[0].value.b = encrypt; + + Execute(CMD_CIPHER_INIT, &op); + + return op.params[0].value.b; +} + +void TrustZoneContext::addGcmAAD(uint32_t opId, + const RawBuffer &aad) +{ + // command ID = CMD_CIPHER_INIT_AAD (from km_ta_defines.h) + auto sIn = makeSerializer(aad); + TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); + sIn.Serialize(inMemory); + + TEEC_Operation op = makeOp(TEEC_VALUE_INPUT, inMemory); + op.params[0].value.a = opId; + + Execute(CMD_CIPHER_INIT_AAD, &op); +} + +RawBuffer TrustZoneContext::updateGcmCipher(uint32_t opId, + const RawBuffer &data) +{ + auto sIn = makeSerializer(data); + TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); + sIn.Serialize(inMemory); + + TZSerializer sOut; + sOut.Push(new TZSerializableBinary(data.size())); + TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT); + + TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory); + op.params[0].value.a = opId; + + Execute(CMD_CIPHER_UPDATE, &op); + + sOut.Deserialize(outMemory); + + RawBuffer out; + sOut.Pull(out); + return out; +} + +RawBuffer TrustZoneContext::finalizeGcmCipher(uint32_t opId, + const RawBuffer &data) +{ + auto sIn = makeSerializer(data); + TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); + sIn.Serialize(inMemory); + + TZSerializer sOut; + sOut.Push(new TZSerializableBinary(data.size())); + TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT); + + TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory); + op.params[0].value.a = opId; + + Execute(CMD_CIPHER_FINALIZE, &op); + + sOut.Deserialize(outMemory); + + RawBuffer out; + sOut.Pull(out); + return out; +} + void TrustZoneContext::executeSign(tz_algo_type algo, tz_hash_type hash, const RawBuffer &keyId, diff --git a/src/manager/crypto/tz-backend/tz-context.h b/src/manager/crypto/tz-backend/tz-context.h index bee3dd5..da27aa2 100644 --- a/src/manager/crypto/tz-backend/tz-context.h +++ b/src/manager/crypto/tz-backend/tz-context.h @@ -136,6 +136,22 @@ public: const RawBuffer &data, RawBuffer &out); + uint32_t initGcmCipher(uint32_t encrypt, + const RawBuffer &keyId, + const Pwd &pwd, + const RawBuffer &iv, + int tagSizeBits, + const RawBuffer &aad); + + void addGcmAAD(uint32_t opId, + const RawBuffer &aad); + + RawBuffer updateGcmCipher(uint32_t opId, + const RawBuffer &data); + + RawBuffer finalizeGcmCipher(uint32_t opId, + const RawBuffer &data); + void executeSign(tz_algo_type algo, tz_hash_type hash, const RawBuffer &keyId,