Cipher API implementation in TZ backend 06/294006/5
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 9 Jun 2023 08:51:08 +0000 (10:51 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 14 Jun 2023 09:34:44 +0000 (11:34 +0200)
Change-Id: I2510dfb8f7e1722ee300edce6e983075a0c5303a

src/manager/crypto/tz-backend/ctx.cpp [new file with mode: 0644]
src/manager/crypto/tz-backend/ctx.h [new file with mode: 0644]
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

diff --git a/src/manager/crypto/tz-backend/ctx.cpp b/src/manager/crypto/tz-backend/ctx.cpp
new file mode 100644 (file)
index 0000000..1fcc80b
--- /dev/null
@@ -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 <generic-backend/exception.h>
+#include <tz-backend/ctx.h>
+#include <tz-backend/internals.h>
+
+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 (file)
index 0000000..d12b5ce
--- /dev/null
@@ -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 <generic-backend/gctx.h>
+#include <ckm/ckm-type.h>
+
+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
index 51bce1d..aca0124 100644 (file)
@@ -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<AlgoType>(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<RawBuffer>(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,
index 5c1596c..cb6b814 100644 (file)
@@ -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,
index 94a4c58..d743753 100644 (file)
  * @author     Lukasz Kostyra (l.kostyra@samsung.com)
  * @version    1.0
  */
+#include <memory>
+#include <utility>
 #include <generic-backend/exception.h>
 #include <generic-backend/algo-validation.h>
 #include <tz-backend/obj.h>
+#include <tz-backend/ctx.h>
 #include <tz-backend/store.h>
 #include <tz-backend/internals.h>
 
@@ -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<CipherCtx>(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)
index 13f63a0..dd35a8e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <generic-backend/gobj.h>
 #include <generic-backend/gstore.h>
+#include <generic-backend/gctx.h>
 #include <data-type.h>
 
 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 {
index 06e9706..e8c500b 100644 (file)
@@ -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,
index bee3dd5..da27aa2 100644 (file)
@@ -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,