Change serialization in TZ backend to match km-ta changes 24/211824/7
authorTomasz Swierczek <t.swierczek@samsung.com>
Mon, 5 Aug 2019 14:47:47 +0000 (16:47 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 27 Aug 2019 07:36:11 +0000 (07:36 +0000)
Changed functions:

* CMD_GENERATE_KEY
* CMD_ENCRYPT
* CMD_DECRYPT
* CMD_SIGN
* CMD_VERIFY
* CMD_GENERATE_IV
* CMD_GENERATE_KEY_PWD
* CMD_DESTROY_KEY

Change-Id: I3d4789b895ca66245f1e700a98f177f56e7a3e28

src/manager/crypto/tz-backend/tz-context.cpp
src/manager/crypto/tz-backend/tz-serializer.cpp

index eb42ff4..917716e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017-2019 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.
@@ -78,31 +78,6 @@ const std::unordered_map<tz_algo_type, size_t> MAX_KEY_SIZE = {
        { ALGO_DSA_SV, 4096 / 8 }
 };
 
-void DeserializeKeyID(TrustZoneMemory &mem, RawBuffer &id)
-{
-       LogDebug("Deserializing key ID");
-
-       KM_SymmetricInput* output = nullptr;
-       int ret = KM_ParamsDeserializationInit(mem.Get()->buffer, mem.Get()->size, &output);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize key ID data deserialization: ", ret);
-       }
-
-       KM_OutData* outData = nullptr;
-       ret = KM_ParamsDeserializeOutData(output, &outData);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize key ID data: ", ret);
-       }
-
-       if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
-               ThrowErr(Exc::Crypto::InternalError, "Deserialized invalid key ID");
-       }
-
-       // data_size should contain how much memory we actually took for our cipher operation
-       id.resize(outData->data_size);
-       memcpy(id.data(), outData->data, outData->data_size);
-}
-
 } // anonymous namespace
 
 TrustZoneContext::TrustZoneContext()
@@ -126,14 +101,6 @@ TrustZoneContext& TrustZoneContext::Instance()
 void TrustZoneContext::generateIV(RawBuffer& iv)
 {
        // command ID = CMD_GENERATE_IV
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [1].memref.buffer - output
-       //   [1].memref.size - output size
-       // output:
-       //   [0].value.a - return code
-
        // IV generation is a simple call - no need to serialize data
        // just provide the output buffer with size equal to iv.
        uint32_t ivSize = Params::DEFAULT_AES_IV_LEN;
@@ -156,33 +123,23 @@ void TrustZoneContext::generateSKey(tz_algo_type algo,
                                                                        RawBuffer &keyId)
 {
        // command ID = CMD_GENERATE_KEY
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [0].value.a - key type
-       //   [0].value.b - key bit size
-       // output:
-       //   [0].value.a - return code
-       //   [1].memref - serialized key reference
-
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.out_size = KM_KEY_ID_SIZE;
-       uint32_t keyMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory keyMemory(m_Context, keyMemorySize, TEEC_MEM_OUTPUT);
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
+
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
                                                                        TEEC_NONE, TEEC_NONE);
        op.params[0].value.a = algo;
        op.params[0].value.b = keySizeBits;
-       op.params[1].memref.parent = keyMemory.Get();
+       op.params[1].memref.parent = outMemory.Get();
        op.params[1].memref.offset = 0;
-       op.params[1].memref.size = keyMemorySize;
+       op.params[1].memref.size = outMemory.Get()->size;
        Execute(CMD_GENERATE_KEY, &op);
 
-       DeserializeKeyID(keyMemory, keyId);
+       sOut.Deserialize(outMemory);
+       sOut.Pull(keyId);
 }
 
 void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
@@ -193,43 +150,15 @@ void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
                                                                        RawBuffer &pwdTag)
 {
        // command ID = CMD_GENERATE_KEY_PWD
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [0].value.a - key type
-       //   [0].value.b - key size in bits
-       //   [1].memref  - input (seralized pwd/iv for pbkdf2)
-       // output:
-       //   [0].value.a - return code
-       //   [2].memref - serialized key reference ID
-
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.with_pwd_data = true;
-       bufSize.pwd_size = static_cast<uint32_t>(pwd.size());
-       bufSize.pwd_iv_size = static_cast<uint32_t>(iv.size());
-       uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.out_size = KM_KEY_ID_SIZE;
-       bufSize.tag_size = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
-       uint32_t keyMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory keyMemory(m_Context, keyMemorySize, TEEC_MEM_OUTPUT);
-
-       KM_SymmetricInput* input = nullptr;
-       int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
-       }
+       TZSerializer sIn;
+       sIn.Push(new TZSerializablePwdData(pwd, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
 
-       ret = KM_ParamsSerializePwdData(input, pwd.data(), pwd.size(), iv.data(), iv.size(),
-                                                                       nullptr, 0, Params::DERIVED_KEY_LENGTH_BITS,
-                                                                       Params::DERIVED_KEY_ITERATIONS, bufSize.tag_size * 8);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
-       }
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
+       sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
@@ -239,44 +168,22 @@ void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
        op.params[1].memref.parent = inMemory.Get();
        op.params[1].memref.offset = 0;
        op.params[1].memref.size = inMemory.Get()->size;
-       op.params[2].memref.parent = keyMemory.Get();
+       op.params[2].memref.parent = outMemory.Get();
        op.params[2].memref.offset = 0;
-       op.params[2].memref.size = keyMemory.Get()->size;
+       op.params[2].memref.size = outMemory.Get()->size;
        Execute(CMD_GENERATE_KEY_PWD, &op);
 
-       DeserializeKeyID(keyMemory, keyId);
-
-       KM_SymmetricInput* output = nullptr;
-       ret = KM_ParamsDeserializationInit(keyMemory.Get()->buffer, keyMemory.Get()->size, &output);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize deserialization for generated key ID");
-       }
-
-       KM_OutData* outData = nullptr;
-       ret = KM_ParamsDeserializeOutData(output, &outData);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize generated key ID");
-       }
-
-       KM_TagData* tagData = nullptr;
-       ret = KM_ParamsDeserializeTagData(output, &tagData);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize key's tag");
-       }
+       sOut.Deserialize(outMemory);
+       sOut.Pull(keyId);
+       sOut.Pull(pwdTag);
 
-       if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
+       if (keyId.size() != KM_KEY_ID_SIZE) {
                ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key ID");
        }
 
-       if (tagData == nullptr || tagData->data_size != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
+       if (pwdTag.size() != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
                ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag");
        }
-
-       keyId.resize(KM_KEY_ID_SIZE);
-       memcpy(keyId.data(), outData->data, KM_KEY_ID_SIZE);
-
-       pwdTag.resize(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
-       memcpy(pwdTag.data(), tagData->data, Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
 }
 
 void TrustZoneContext::GenerateAKey(tz_command commandId,
@@ -362,23 +269,6 @@ void TrustZoneContext::generateRSAKey(uint32_t keySizeBits,
                                                                        RawBuffer &privKeyTag)
 {
        // command ID = CMD_GENERATE_RSA_KEYPAIR
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [0].value.b - key bit size
-       //   [1].memref - reference to serialized buffer:
-       //       flag marking the public key password presence,
-       //       public key password data if the flag above is not 0,
-       //       flag marking the private key password presence,
-       //       public key private data if the flag above is not 0,
-       // output:
-       //   [0].value.a - return code
-       //   [2].memref
-       //       Public key ID,
-       //       public key tag if password was present,
-       //       Private key ID,
-       //       private key tag if password was present,
-
        TZSerializer sIn;
 
        GenerateAKey(CMD_GENERATE_RSA_KEYPAIR,
@@ -408,24 +298,6 @@ void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
                                                                        RawBuffer &privKeyTag)
 {
        // command ID = CMD_GENERATE_DSA_KEYPAIR
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [0].value.b - key bit size
-       //   [1].memref - reference to serialized buffer:
-       //       prime, subprime, base,
-       //       flag marking the public key password presence,
-       //       public key password data if the flag above is not 0,
-       //       flag marking the private key password presence,
-       //       public key private data if the flag above is not 0,
-       // output:
-       //   [0].value.a - return code
-       //   [2].memref
-       //       Public key ID,
-       //       public key tag if password was present,
-       //       Private key ID,
-       //       private key tag if password was present,
-
        TZSerializer sIn;
        sIn.Push(new TZSerializableBinary(prime));
        sIn.Push(new TZSerializableBinary(subprime));
@@ -453,80 +325,41 @@ void TrustZoneContext::executeCrypt(tz_command cmd,
                                                                        RawBuffer &out)
 {
        // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [0].value.a - keyid
-       //   [0].value.b - algo
-       //   [1].memref - input data (serialized key/input)
-       // returned:
-       //   [0].value.a - return code
-       //   [2].memref - serialized output buffer
-
        if (keyId.size() != KM_KEY_ID_SIZE) {
                ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
                        + std::to_string(keyId.size()) + ")");
        }
 
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.input_size = static_cast<uint32_t>(data.size());
-       bufSize.with_pwd_data = true;
-       bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
-       bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
-       bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
-       bufSize.iv_size = static_cast<uint32_t>(iv.size());
-       bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
-       uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
+       TZSerializer sIn;
+       sIn.Push(new TZSerializableBinary(data));
+       int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
+       sIn.Push(new TZSerializableFlag(pwd_flag));
+       if (pwd_flag)
+               sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
+                                                                          pwd.getIV(),
+                                                                          pwd.getTag().size() * 8,
+                                                                          pwd.getTag()));
+       if (algo != ALGO_RSA)
+               sIn.Push(new TZSerializableBinary(iv));
+       sIn.Push(new TZSerializableBinary(keyId));
 
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
 
        // decrypt operation does not require padding
-       bufSize.out_size = static_cast<uint32_t>(data.size());
+       uint32_t outMemorySize = data.size();
        if (cmd == CMD_ENCRYPT) {
                if (algo == ALGO_RSA) {
                        // We don't know the key length
-                       bufSize.out_size = MAX_KEY_SIZE.at(ALGO_RSA);
+                       outMemorySize = MAX_KEY_SIZE.at(ALGO_RSA);
                } else {
-                       bufSize.out_size = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
+                       outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
                }
        }
-       uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
-
-       KM_SymmetricInput* input = nullptr;
-       int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
-       }
-
-       ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
-       }
-
-       uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
-       ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
-                                                                       pwd.getIV().data(), pwd.getIV().size(),
-                                                                       pwd.getTag().data(), pwd.getTag().size(),
-                                                                       Params::DERIVED_KEY_LENGTH_BITS,
-                                                                       Params::DERIVED_KEY_ITERATIONS,
-                                                                       pwdTagSizeBits);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
-       }
-
-       ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
-       }
 
-       ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
-       }
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(outMemorySize));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
@@ -538,26 +371,11 @@ void TrustZoneContext::executeCrypt(tz_command cmd,
        op.params[2].memref.parent = outMemory.Get();
        op.params[2].memref.offset = 0;
        op.params[2].memref.size = outMemory.Get()->size;
-       Execute(cmd, &op);
 
-       KM_SymmetricInput* output = nullptr;
-       ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
-       }
-
-       KM_OutData* outData = nullptr;
-       ret = KM_ParamsDeserializeOutData(output, &outData);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
-       }
+       Execute(cmd, &op);
 
-       // data_size should contain how much memory we actually took for our cipher operation
-       out.clear();
-       if (outData) {
-               out.resize(outData->data_size);
-               memcpy(out.data(), outData->data, outData->data_size);
-       }
+       sOut.Deserialize(outMemory);
+       sOut.Pull(out);
 }
 
 void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
@@ -570,78 +388,34 @@ void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
                                                                                RawBuffer &tag)
 {
        // command ID = CMD_ENCRYPT (from km_ta_defines.h)
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [0].value.a - keyid
-       //   [0].value.b - algo
-       //   [1].memref - input data (serialized key/input/iv/aad)
-       // returned:
-       //   [0].value.a - return code
-       //   [2].memref - output
-
        if (keyId.size() != KM_KEY_ID_SIZE) {
                ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
        }
 
-       uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.input_size = static_cast<uint32_t>(data.size());
-       bufSize.with_pwd_data = true;
-       bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
-       bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
-       bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
-       bufSize.iv_size = static_cast<uint32_t>(iv.size());
-       bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
-       bufSize.with_ae_data = true;
-       bufSize.aad_size = static_cast<uint32_t>(aad.size());
-       uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.out_size = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
-       bufSize.tag_size = static_cast<uint32_t>(tagSizeBytes);
-       uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
-
-       KM_SymmetricInput* input = nullptr;
-       int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
-       }
-
-       ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
-       }
-
-       uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
-       ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
-                                                                       pwd.getIV().data(), pwd.getIV().size(),
-                                                                       pwd.getTag().data(), pwd.getTag().size(),
-                                                                       Params::DERIVED_KEY_LENGTH_BITS,
-                                                                       Params::DERIVED_KEY_ITERATIONS,
-                                                                       pwdTagSizeBits);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
-       }
+       TZSerializer sIn;
+       sIn.Push(new TZSerializableBinary(data));
+       int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
+       sIn.Push(new TZSerializableFlag(pwd_flag));
+       if (pwd_flag)
+               sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
+                                                                          pwd.getIV(),
+                                                                          pwd.getTag().size() * 8,
+                                                                          pwd.getTag()));
+       sIn.Push(new TZSerializableBinary(iv));
+       sIn.Push(new TZSerializableBinary(keyId));
+       sIn.Push(new TZSerializableBinary(aad));
+       sIn.Push(new TZSerializableFlag(tagSizeBits));
 
-       ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
-       }
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
 
-       ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
-       }
+       uint32_t outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
+       uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
 
-       ret = KM_ParamsSerializeAEData(input, tagSizeBits, 0, aad.data(), aad.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize auth data for TZ crypto operation: ", ret);
-       }
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(outMemorySize));
+       sOut.Push(new TZSerializableBinary(tagSizeBytes));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
@@ -653,125 +427,49 @@ void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
        op.params[2].memref.parent = outMemory.Get();
        op.params[2].memref.offset = 0;
        op.params[2].memref.size = outMemory.Get()->size;
-       Execute(CMD_ENCRYPT, &op);
 
-       KM_SymmetricInput* output = nullptr;
-       ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
-       }
-
-       KM_OutData* outData = nullptr;
-       ret = KM_ParamsDeserializeOutData(output, &outData);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
-       }
-
-       KM_TagData* tagData = nullptr;
-       ret = KM_ParamsDeserializeTagData(output, &tagData);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize tag data: ", ret);
-       }
-
-       out.clear();
-       if (outData) {
-               out.resize(outData->data_size);
-               memcpy(out.data(), outData->data, outData->data_size);
-       }
+       Execute(CMD_ENCRYPT, &op);
 
-       tag.clear();
-       if (tagData && tagData->data_size) {
-               tag.resize(tagData->data_size);
-               memcpy(tag.data(), tagData->data, tagData->data_size);
-       }
+       sOut.Deserialize(outMemory);
+       sOut.Pull(out);
+       sOut.Pull(tag);
 }
 
 void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
                                                                                const Pwd &pwd,
                                                                                const RawBuffer &iv,
-                                                                               int tagSizeBits,
+                                                                               int  tagSizeBits,
                                                                                const RawBuffer &tag,
                                                                                const RawBuffer &aad,
                                                                                const RawBuffer &data,
                                                                                RawBuffer &out)
 {
        // command ID = CMD_DECRYPT (from km_ta_defines.h)
-       //
-       // TEEC_Operation layout:
-       // params:
-       //   [0].value.a - keyid
-       //   [0].value.b - algo
-       //   [1].memref - input data (serialized key/input/iv/tag/aad)
-       // returned:
-       //   [0].value.a - output size
-       //   [2].memref - output (decrypted data)
-
        if (keyId.size() != KM_KEY_ID_SIZE) {
                ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
        }
 
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.input_size = static_cast<uint32_t>(data.size());
-       bufSize.with_pwd_data = true;
-       bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
-       bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
-       bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
-       bufSize.iv_size = static_cast<uint32_t>(iv.size());
-       bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
-       bufSize.with_ae_data = true;
-       bufSize.aad_size = static_cast<uint32_t>(aad.size());
-       bufSize.tag_size = static_cast<uint32_t>(tag.size());
-       uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.out_size = static_cast<uint32_t>(data.size());
-       uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
-
-       KM_SymmetricInput* input = nullptr;
-       int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
-       }
-
-       ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
-       }
-
-       uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
-       ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
-                                                                       pwd.getIV().data(), pwd.getIV().size(),
-                                                                       pwd.getTag().data(), pwd.getTag().size(),
-                                                                       Params::DERIVED_KEY_LENGTH_BITS,
-                                                                       Params::DERIVED_KEY_ITERATIONS,
-                                                                       pwdTagSizeBits);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
-       }
-
-       ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
-       }
-
-       ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
-       }
+       TZSerializer sIn;
+       sIn.Push(new TZSerializableBinary(data));
+       int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
+       sIn.Push(new TZSerializableFlag(pwd_flag));
+       if (pwd_flag)
+               sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
+                                                                          pwd.getIV(),
+                                                                          pwd.getTag().size() * 8,
+                                                                          pwd.getTag()));
+       sIn.Push(new TZSerializableBinary(iv));
+       sIn.Push(new TZSerializableBinary(keyId));
+       sIn.Push(new TZSerializableBinary(aad));
+       sIn.Push(new TZSerializableFlag(tagSizeBits));
+       sIn.Push(new TZSerializableBinary(tag));
 
-       ret = KM_ParamsSerializeAEData(input, tagSizeBits, 0, aad.data(), aad.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize auth data for TZ crypto operation: ", ret);
-       }
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
 
-       ret = KM_ParamsSerializeTagData(input, tag.data(), tag.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize tag data for TZ crypto operation: ", ret);
-       }
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(data.size()));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
@@ -783,25 +481,11 @@ void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
        op.params[2].memref.parent = outMemory.Get();
        op.params[2].memref.offset = 0;
        op.params[2].memref.size = outMemory.Get()->size;
-       Execute(CMD_DECRYPT, &op);
 
-       KM_SymmetricInput* output = nullptr;
-       ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
-       }
-
-       KM_OutData* outData = nullptr;
-       ret = KM_ParamsDeserializeOutData(output, &outData);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
-       }
+       Execute(CMD_DECRYPT, &op);
 
-       out.clear();
-       if (outData) {
-               out.resize(outData->data_size);
-               memcpy(out.data(), outData->data, outData->data_size);
-       }
+       sOut.Deserialize(outMemory);
+       sOut.Pull(out);
 }
 
 void TrustZoneContext::executeSign(tz_algo_type algo,
@@ -812,67 +496,27 @@ void TrustZoneContext::executeSign(tz_algo_type algo,
                                                                RawBuffer &signature)
 {
        // command ID = CMD_SIGN (from km_ta_defines.h)
-       //
-       // TEEC_Operation layout:
-       // input params:
-       //   [0].value.a - algorithm type (tz_algo_type)
-       //   [0].value.b - hash type (tz_hash_type)
-       //   [1].memref  - reference to serialized buffer:
-       //       KM_ParamsSerializeInputData with data to sign
-       //       KM_ParamsSerializeKeyId with key id
-       // output params:
-       //   [0].value.a - return code
-       //   [2].memref  - reference to serialized buffer:
-       //       KM_ParamsSerializeOutData with signature data
-
        if (keyId.size() != KM_KEY_ID_SIZE) {
                ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
                        + std::to_string(keyId.size()) + ")");
        }
 
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.input_size = static_cast<uint32_t>(message.size());
-       bufSize.with_pwd_data = true;
-       bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
-       bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
-       bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
-       bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
-       uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.out_size = MAX_KEY_SIZE.at(algo);
-       uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
-
-       KM_SymmetricInput* input = nullptr;
-       int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ sign operations");
-       }
-
-       ret = KM_ParamsSerializeInputData(input, message.data(), message.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ sign operation: ", ret);
-       }
-
-       uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
-       ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
-                                                                       pwd.getIV().data(), pwd.getIV().size(),
-                                                                       pwd.getTag().data(), pwd.getTag().size(),
-                                                                       Params::DERIVED_KEY_LENGTH_BITS,
-                                                                       Params::DERIVED_KEY_ITERATIONS,
-                                                                       pwdTagSizeBits);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ sign operation: ", ret);
-       }
+       TZSerializer sIn;
+       sIn.Push(new TZSerializableBinary(message));
+       int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
+       sIn.Push(new TZSerializableFlag(pwd_flag));
+       if (pwd_flag)
+               sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
+                                                                          pwd.getIV(),
+                                                                          pwd.getTag().size() * 8,
+                                                                          pwd.getTag()));
+       sIn.Push(new TZSerializableBinary(keyId));
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
 
-       ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ sign operation: ", ret);
-       }
+       TZSerializer sOut;
+       sOut.Push(new TZSerializableBinary(MAX_KEY_SIZE.at(algo)));
+       TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
@@ -887,20 +531,8 @@ void TrustZoneContext::executeSign(tz_algo_type algo,
        op.params[2].memref.size = outMemory.Get()->size;
        Execute(CMD_SIGN, &op);
 
-       KM_SymmetricInput* output = nullptr;
-       ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
-       }
-
-       KM_OutData* outData = nullptr;
-       ret = KM_ParamsDeserializeOutData(output, &outData);
-       if (ret || !outData || outData->data_size == 0) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
-       }
-
-       signature.resize(outData->data_size);
-       memcpy(signature.data(), outData->data, outData->data_size);
+       sOut.Deserialize(outMemory);
+       sOut.Pull(signature);
 }
 
 int TrustZoneContext::executeVerify(tz_algo_type algo,
@@ -911,66 +543,24 @@ int TrustZoneContext::executeVerify(tz_algo_type algo,
                                                                        const RawBuffer &signature)
 {
        // command ID = CMD_VERIFY (from km_ta_defines.h)
-       //
-       // TEEC_Operation layout:
-       // input params:
-       //   [0].value.a - algorithm type (tz_algo_type)
-       //   [0].value.b - hash type (tz_hash_type)
-       //   [1].memref  - reference to serialized buffer:
-       //       KM_ParamsSerializeInputData with verify data (signature hidden in Tag data)
-       //       KM_ParamsSerializeKeyId with key id
-       // output params:
-       //   [0].value.a - return code
-
        if (keyId.size() != KM_KEY_ID_SIZE) {
                ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
                        + std::to_string(keyId.size()) + ")");
        }
 
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.input_size = static_cast<uint32_t>(message.size());
-       bufSize.with_pwd_data = true;
-       bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
-       bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
-       bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
-       bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
-       bufSize.tag_size = static_cast<uint32_t>(signature.size());
-       uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
-
-       KM_SymmetricInput* input = nullptr;
-       int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ sign operations");
-       }
-
-       ret = KM_ParamsSerializeInputData(input, message.data(), message.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ sign operation: ", ret);
-       }
-
-       uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
-       ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
-                                                                       pwd.getIV().data(), pwd.getIV().size(),
-                                                                       pwd.getTag().data(), pwd.getTag().size(),
-                                                                       Params::DERIVED_KEY_LENGTH_BITS,
-                                                                       Params::DERIVED_KEY_ITERATIONS,
-                                                                       pwdTagSizeBits);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ sign operation: ", ret);
-       }
-
-       ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ sign operation: ", ret);
-       }
-
-       ret = KM_ParamsSerializeTagData(input, signature.data(), signature.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize signature data for TZ sign operation: ", ret);
-       }
+       TZSerializer sIn;
+       sIn.Push(new TZSerializableBinary(message));
+       sIn.Push(new TZSerializableBinary(signature));
+       int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
+       sIn.Push(new TZSerializableFlag(pwd_flag));
+       if (pwd_flag)
+               sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
+                                                                          pwd.getIV(),
+                                                                          pwd.getTag().size() * 8,
+                                                                          pwd.getTag()));
+       sIn.Push(new TZSerializableBinary(keyId));
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
@@ -998,34 +588,14 @@ int TrustZoneContext::executeVerify(tz_algo_type algo,
 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
 {
        // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
-       //
-       // TEEC_Operation layout:
-       // input params:
-       //   [1].memref - input data (serialized key ID)
-       // output params:
-       //   [0].value.a - return code
-
        if (keyId.size() != KM_KEY_ID_SIZE) {
                ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
        }
 
-       KM_BufferSizeDesc bufSize;
-
-       memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
-       bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
-       uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
-       TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
-
-       KM_SymmetricInput* input = nullptr;
-       int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization: ", ret);
-       }
-
-       ret = KM_ParamsSerializeInputData(input, keyId.data(), keyId.size());
-       if (ret) {
-               ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key ID to destroy: ", ret);
-       }
+       TZSerializer sIn;
+       sIn.Push(new TZSerializableBinary(keyId));
+       TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+       sIn.Serialize(inMemory);
 
        TEEC_Operation op;
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
@@ -1048,21 +618,6 @@ void TrustZoneContext::importData(
                                RawBuffer &pwdTag)
 {
        // command ID = CMD_IMPORT_DATA
-       // input:
-       //    [1].memref  - reference to serialized buffer:
-       //        uint32_t dataType contains information about type stored as binary data
-       //        KM_BinaryData with binary data
-       //        uint32_t binary/key size in bits
-       //        KM_BinaryData IV for data decryption with built in key
-       //        KM_BinaryData TAG for data decryption with built in key
-       //        uint32_t boolean value - true if password is provided
-       //        KM_PwdData with password (optional)
-       // Output:
-       //    [0].value.a - return code
-       //    [2].memref  - reference to serialized buffer:
-       //        KM_BinaryData with data id
-       //        KM_BinaryData with tag id (optional, if password was provided)
-
        TZSerializer sIn;
        sIn.Push(new TZSerializableFlag(dataType));
        sIn.Push(new TZSerializableBinary(data));
@@ -1111,13 +666,6 @@ void TrustZoneContext::importData(
 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
 {
        // command ID = CMD_GET_DATA_SIZE
-       // TA will decrypt data with password if provided
-       // Parameters:
-       //    [1].memref  - reference to serialized buffer:
-       //        KM_BinaryData with object ID
-       // Output:
-       //    [0].value.a - return code
-       //    [0].value.b - size of buffer to be passed from CA
        LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
 
        TZSerializer sIn;
@@ -1142,16 +690,6 @@ void TrustZoneContext::getData(const RawBuffer &dataId,
                         RawBuffer &data)
 {
        // command ID = CMD_GET_DATA
-       // TA will decrypt data with password if provided
-       // Parameters:
-       //    [1].memref  - reference to serialized buffer:
-       //        KM_BinaryData with object ID
-       //        uint32_t boolean value - true if password is provided
-       //        KM_PwdData with password (optional)
-       // Output:
-       //    [0].value.a - return code
-       //    [2].memref  - reference to serialized buffer:
-       //        KM_BinaryData with binary data
        LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
 
        TZSerializer sIn;
@@ -1198,12 +736,6 @@ void TrustZoneContext::getData(const RawBuffer &dataId,
 void TrustZoneContext::destroyData(const RawBuffer &dataId)
 {
        //      command ID = CMD_DESTROY_DATA
-       //  TEEC_Operation parameters layout:
-       //      input:
-       //     [1].memref  - reference to serialized buffer:
-       //         KM_BinaryData with object ID
-       //  output:
-       //     [0].value.a - return code
        LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
        TZSerializer sIn;
        sIn.Push(new TZSerializableBinary(dataId));
index 27cf705..b268e22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2019 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.