/*
- * Copyright (c) 2017 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017-2021 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.
* @version 1.0
*/
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
#include <tz-backend/tz-context.h>
#include <tz-backend/tz-memory.h>
#include <generic-backend/exception.h>
#include <cstdint>
#include <cstring>
#include <cassert>
-#include <iomanip>
-#include <sstream>
#include <unordered_map>
namespace CKM {
// whatever TA will return us.
const uint32_t CIPHER_EXTRA_PADDING_SIZE = 16;
+// Maximum size of GCM tag in bytes.
+const size_t MAX_GCM_TAG_SIZE = 16;
+
// Identifier of our TA
const TEEC_UUID KEY_MANAGER_TA_UUID = KM_TA_UUID;
//raw to hex string conversion to print persistent storage data ID
static std::string rawToHexString(const RawBuffer &raw)
{
- std::string dump;
-
- for (auto &e : raw) {
- char buf[3];
- snprintf(buf, sizeof(buf), "%02x", (e & 0xff));
- dump.push_back(buf[0]);
- dump.push_back(buf[1]);
- }
-
- return dump;
+ return hexDump<std::string>(raw);
}
/*
const std::unordered_map<tz_algo_type, size_t> MAX_KEY_SIZE = {
{ ALGO_RSA, 4096 / 8 },
{ ALGO_RSA_SV, 4096 / 8 },
- { ALGO_DSA_SV, 4096 / 8 }
+ { ALGO_DSA_SV, 4096 / 8 },
+ { ALGO_ECDSA_SV, 1024 / 8 } // 384*2 + additional space for DERR encoding
+};
+
+struct EncPwd {
+ const RawBuffer &password;
+ const RawBuffer &iv;
};
-void DeserializeKeyID(TrustZoneMemory &mem, RawBuffer &id)
+template <typename T>
+void push(TZSerializer& ser, const T& value)
{
- LogDebug("Deserializing key ID");
+ ser.Push(new TZSerializableFlag(static_cast<uint32_t>(value)));
+}
- 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);
- }
+template<>
+void push<RawBuffer>(TZSerializer& ser, const RawBuffer& value)
+{
+ ser.Push(new TZSerializableBinary(value));
+}
- KM_OutData* outData = nullptr;
- ret = KM_ParamsDeserializeOutData(output, &outData);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize key ID data: ", ret);
- }
+template<>
+void push<Pwd>(TZSerializer& ser, const Pwd& value)
+{
+ int32_t pwd_flag = value.getPassword().empty() ? 0 : 1;
+ ser.Push(new TZSerializableFlag(pwd_flag));
+ if (pwd_flag)
+ ser.Push(new TZSerializablePwdData(value.getPassword(),
+ value.getIV(),
+ value.getTag().size() * 8,
+ value.getTag()));
+}
- if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
- ThrowErr(Exc::Crypto::InternalError, "Deserialized invalid key ID");
- }
+template<>
+void push<EncPwd>(TZSerializer& ser, const EncPwd& value)
+{
+ int32_t pwd_flag = value.password.empty() ? 0 : 1;
+ ser.Push(new TZSerializableFlag(pwd_flag));
+ if (pwd_flag)
+ ser.Push(new TZSerializablePwdData(value.password,
+ value.iv,
+ Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
+}
- // 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);
+template <typename T, typename ...Args>
+void push(TZSerializer& ser, const T& first, const Args&... args)
+{
+ push<T>(ser, first);
+ push<Args...>(ser, args...);
+}
+
+template <typename ...Args>
+TZSerializer makeSerializer(const Args&... args)
+{
+ TZSerializer ser;
+ push<Args...>(ser, args...);
+ return ser;
}
} // anonymous namespace
return instance;
}
+TEEC_Operation makeOp(uint32_t value, TrustZoneMemory& mem1)
+{
+ TEEC_Operation op;
+
+ op.paramTypes = TEEC_PARAM_TYPES(value, TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE);
+
+ op.params[1].memref.parent = mem1.Get();
+ op.params[1].memref.offset = 0;
+ op.params[1].memref.size = mem1.Get()->size;
+ return op;
+}
+
+TEEC_Operation makeOp(uint32_t value, TrustZoneMemory& mem1, TrustZoneMemory& mem2)
+{
+ TEEC_Operation op = makeOp(value, mem1);
+
+ op.paramTypes = TEEC_PARAM_TYPES(value, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE);
+
+ op.params[2].memref.parent = mem2.Get();
+ op.params[2].memref.offset = 0;
+ op.params[2].memref.size = mem2.Get()->size;
+
+ return op;
+}
+
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;
TrustZoneMemory ivMemory(m_Context, ivSize, TEEC_MEM_OUTPUT);
- TEEC_Operation op;
- op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
- TEEC_NONE, TEEC_NONE);
- op.params[1].memref.parent = ivMemory.Get();
- op.params[1].memref.offset = 0;
- op.params[1].memref.size = ivMemory.Get()->size;
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, ivMemory);
+
Execute(CMD_GENERATE_IV, &op);
iv.resize(ivSize);
void TrustZoneContext::generateSKey(tz_algo_type algo,
uint32_t keySizeBits,
- RawBuffer &keyId)
+ const RawBuffer &hash)
{
// 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);
+ auto sIn = makeSerializer(hash);
+ 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,
- TEEC_NONE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
op.params[0].value.a = algo;
op.params[0].value.b = keySizeBits;
- op.params[1].memref.parent = keyMemory.Get();
- op.params[1].memref.offset = 0;
- op.params[1].memref.size = keyMemorySize;
- Execute(CMD_GENERATE_KEY, &op);
- DeserializeKeyID(keyMemory, keyId);
+ Execute(CMD_GENERATE_KEY, &op);
}
void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
const RawBuffer &pwd,
const RawBuffer &iv,
const uint32_t keySizeBits,
- RawBuffer &keyId,
- RawBuffer &pwdTag)
+ RawBuffer &pwdTag,
+ const RawBuffer &hash)
{
// 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));
+ sIn.Push(new TZSerializableBinary(hash));
+ 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(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,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
op.params[0].value.a = algo;
op.params[0].value.b = keySizeBits;
- 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.offset = 0;
- op.params[2].memref.size = keyMemory.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");
- }
+ Execute(CMD_GENERATE_KEY_PWD, &op);
- if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
- ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key ID");
- }
+ sOut.Deserialize(outMemory);
+ sOut.Pull(pwdTag);
- 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,
TZSerializer &sIn,
- uint32_t keySizeBits,
+ uint32_t genParam, // key size in bits or EC type
const RawBuffer &pubPwd,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag)
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
uint32_t pubTagSize = 0;
uint32_t privTagSize = 0;
-
uint32_t pubPwdExists = pubPwd.empty() ? 0 : 1;
- sIn.Push(new TZSerializableFlag(pubPwdExists));
if (pubPwdExists) {
- sIn.Push(new TZSerializablePwdData(pubPwd, pubPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
- pubTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
+ pubTagSize = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
}
uint32_t privPwdExists = privPwd.empty() ? 0 : 1;
- sIn.Push(new TZSerializableFlag(privPwdExists));
if (privPwdExists) {
- sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
- privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
+ privTagSize = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
}
+ push(sIn, EncPwd{pubPwd, pubPwdIv}, EncPwd{privPwd, privPwdIv}, hashPriv, hashPub);
TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
sIn.Serialize(inMemory);
TZSerializer sOut;
- sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
sOut.Push(new TZSerializableBinary(pubTagSize));
- sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
sOut.Push(new TZSerializableBinary(privTagSize));
TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
- TEEC_Operation op;
- op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
- op.params[0].value.b = keySizeBits;
- 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 = outMemory.Get();
- op.params[2].memref.offset = 0;
- op.params[2].memref.size = outMemory.Get()->size;
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+ op.params[0].value.b = genParam;
+
Execute(commandId, &op);
sOut.Deserialize(outMemory);
-
- sOut.Pull(pubKeyId);
- if (pubKeyId.size() != KM_KEY_ID_SIZE) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize public key ID");
- }
-
if (pubPwdExists) {
sOut.Pull(pubKeyTag);
}
- sOut.Pull(privKeyId);
- if (privKeyId.size() != KM_KEY_ID_SIZE) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize private key ID");
- }
-
if (privPwdExists) {
sOut.Pull(privKeyTag);
}
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag)
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
// 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,
pubPwdIv,
privPwd,
privPwdIv,
- pubKeyId,
pubKeyTag,
- privKeyId,
- privKeyTag);
+ privKeyTag,
+ hashPriv,
+ hashPub);
}
void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag)
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
// 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));
- sIn.Push(new TZSerializableBinary(base));
+ auto sIn = makeSerializer(prime, subprime, base);
GenerateAKey(CMD_GENERATE_DSA_KEYPAIR,
sIn,
pubPwdIv,
privPwd,
privPwdIv,
- pubKeyId,
pubKeyTag,
- privKeyId,
- privKeyTag);
+ privKeyTag,
+ hashPriv,
+ hashPub);
+}
+
+void TrustZoneContext::generateECKey(tz_ec ec,
+ const RawBuffer &pubPwd,
+ const RawBuffer &pubPwdIv,
+ const RawBuffer &privPwd,
+ const RawBuffer &privPwdIv,
+ RawBuffer &pubKeyTag,
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
+{
+ // command ID = CMD_GENERATE_EC_KEYPAIR
+ TZSerializer sIn;
+
+ GenerateAKey(CMD_GENERATE_EC_KEYPAIR,
+ sIn,
+ static_cast<uint32_t>(ec),
+ pubPwd,
+ pubPwdIv,
+ privPwd,
+ privPwdIv,
+ pubKeyTag,
+ privKeyTag,
+ hashPriv,
+ hashPub);
}
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;
+ if (algo == ALGO_RSA)
+ sIn = makeSerializer(data, pwd, keyId);
+ else
+ sIn = makeSerializer(data, pwd, iv, 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, false));
+ TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
- TEEC_Operation op;
- op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
op.params[0].value.a = 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 = 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.resize(outData->data_size);
- memcpy(out.data(), outData->data, outData->data_size);
+ sOut.Deserialize(outMemory);
+ sOut.Pull(out);
}
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);
- }
-
- ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
- }
+ auto sIn = makeSerializer(data, pwd, iv, keyId, aad, tagSizeBits);
+ 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, false));
+ 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,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
op.params[0].value.a = ALGO_AES_GCM;
- 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 = 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.resize(outData->data_size);
- memcpy(out.data(), outData->data, outData->data_size);
+ Execute(CMD_ENCRYPT, &op);
- if (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");
- }
+ auto sIn = makeSerializer(data, pwd, iv, keyId, aad, tagSizeBits, tag);
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
- ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
- }
+ TZSerializer sOut;
+ sOut.Push(new TZSerializableBinary(data.size()));
+ TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
- 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);
- }
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+ op.params[0].value.a = ALGO_AES_GCM;
- ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
- }
+ Execute(CMD_DECRYPT, &op);
- 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);
- }
+ sOut.Deserialize(outMemory);
+ sOut.Pull(out);
+}
- 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);
+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");
}
- ret = KM_ParamsSerializeTagData(input, tag.data(), tag.size());
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize tag data for TZ crypto operation: ", ret);
- }
+ auto sIn = makeSerializer(pwd, iv, keyId, aad, tagSizeBits);
+ 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,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
op.params[0].value.a = ALGO_AES_GCM;
- 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 = outMemory.Get();
- op.params[2].memref.offset = 0;
- op.params[2].memref.size = outMemory.Get()->size;
- Execute(CMD_DECRYPT, &op);
+ op.params[0].value.b = encrypt;
- 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);
- }
+ Execute(CMD_CIPHER_INIT, &op);
- KM_OutData* outData = nullptr;
- ret = KM_ParamsDeserializeOutData(output, &outData);
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
- }
+ 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_INOUT, 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;
+}
- out.resize(outData->data_size);
- memcpy(out.data(), outData->data, outData->data_size);
+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(MAX_GCM_TAG_SIZE, false));
+ 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,
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);
- }
+ auto sIn = makeSerializer(message, pwd, 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), false));
+ TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
- TEEC_Operation op;
- op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
op.params[0].value.a = algo;
op.params[0].value.b = hash;
- 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 = outMemory.Get();
- op.params[2].memref.offset = 0;
- 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) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
- }
+ Execute(CMD_SIGN, &op);
- 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,
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);
- }
+ auto sIn = makeSerializer(message, signature, pwd, 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,
- TEEC_NONE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
op.params[0].value.a = algo;
op.params[0].value.b = hash;
- op.params[1].memref.parent = inMemory.Get();
- op.params[1].memref.offset = 0;
- op.params[1].memref.size = inMemory.Get()->size;
+
Execute(CMD_VERIFY, &op);
int opRet = op.params[0].value.a;
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);
- }
+ auto sIn = makeSerializer(keyId);
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
- ret = KM_ParamsSerializeInputData(input, keyId.data(), keyId.size());
- if (ret) {
- ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key ID to destroy: ", ret);
- }
+ TEEC_Operation op = makeOp(TEEC_VALUE_OUTPUT, inMemory);
- TEEC_Operation op;
- op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
- TEEC_NONE, TEEC_NONE);
- op.params[1].memref.parent = inMemory.Get();
- op.params[1].memref.offset = 0;
- op.params[1].memref.size = inMemory.Get()->size;
Execute(CMD_DESTROY_KEY, &op);
}
const RawBuffer &pwd,
const RawBuffer &iv,
const uint32_t keySizeBits,
- const uint32_t pwdTagSizeBits,
- RawBuffer &dataId,
- RawBuffer &pwdTag)
+ RawBuffer &pwdTag,
+ const RawBuffer &hash)
{
// 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)
+ LogDebug("TrustZoneContext::importData data size = [" << data.size() << "]");
- TZSerializer sIn;
- sIn.Push(new TZSerializableFlag(dataType));
- sIn.Push(new TZSerializableBinary(data));
- sIn.Push(new TZSerializableFlag(keySizeBits));
- sIn.Push(new TZSerializableBinary(encData.iv));
- sIn.Push(new TZSerializableBinary(encData.tag));
-
- uint32_t pwd_flag = pwd.empty() ? 0 : 1;
- sIn.Push(new TZSerializableFlag(pwd_flag));
- if (pwd_flag)
- sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
+ auto sIn = makeSerializer(
+ dataType, data, keySizeBits, encData.iv, encData.tag, EncPwd{pwd, iv}, hash);
TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
sIn.Serialize(inMemory);
-
TZSerializer sOut;
- sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE));
- if (pwd_flag) {
- sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
+ if (!pwd.empty()) {
+ 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,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
- 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 = outMemory.Get();
- op.params[2].memref.offset = 0;
- op.params[2].memref.size = outMemory.Get()->size;
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
+ if (!pwd.empty())
+ op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
Execute(CMD_IMPORT_DATA, &op);
- sOut.Deserialize(outMemory);
- sOut.Pull(dataId);
- if (pwd_flag) {
+ if (!pwd.empty()) {
+ sOut.Deserialize(outMemory);
sOut.Pull(pwdTag);
}
- LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
+ LogDebug("Imported object ID is (hex): " << rawToHexString(hash));
+}
+
+void TrustZoneContext::importWrappedKey(const RawBuffer &wrappingKeyId,
+ 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(wrappingKeyId,
+ 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));
+}
+
+RawBuffer TrustZoneContext::exportWrappedKey(const RawBuffer &wrappingKeyId,
+ const Pwd &wrappingKeyPwd,
+ tz_algo_type algo,
+ const RawBuffer &iv,
+ const uint32_t ctrLenOrTagSizeBits,
+ const RawBuffer &aad,
+ const RawBuffer &keyToWrapId,
+ const Pwd &keyToWrapPwd)
+{
+ // command ID = CMD_EXPORT_WRAPPED_KEY
+ LogDebug("TrustZoneContext::exportWrappedKey");
+
+ auto sIn = makeSerializer(wrappingKeyId,
+ wrappingKeyPwd,
+ algo,
+ iv,
+ ctrLenOrTagSizeBits,
+ aad,
+ keyToWrapId,
+ keyToWrapPwd);
+
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
+
+ uint32_t data_size = 0;
+ GetDataSize(keyToWrapId, data_size);
+
+ LogDebug("GetData data_size = [" << data_size << "]");
+
+ // encrypted data may be longer
+ TZSerializer sOut;
+ sOut.Push(new TZSerializableBinary(data_size + KM_ENCRYPTION_OVERHEAD));
+ TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+ sOut.Serialize(outMemory);
+
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+
+ Execute(CMD_EXPORT_WRAPPED_KEY, &op);
+
+ sOut.Deserialize(outMemory);
+
+ RawBuffer wrappedKey;
+ sOut.Pull(wrappedKey);
+
+ return wrappedKey;
}
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;
- sIn.Push(new TZSerializableBinary(dataId));
-
+ auto sIn = makeSerializer(dataId);
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,
- TEEC_NONE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_OUTPUT, inMemory);
- op.params[1].memref.parent = inMemory.Get();
- op.params[1].memref.offset = 0;
- op.params[1].memref.size = inMemory.Get()->size;
Execute(CMD_GET_DATA_SIZE, &op);
dataSize = op.params[0].value.b;
}
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;
- sIn.Push(new TZSerializableBinary(dataId));
-
- uint32_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(),
- Params::DEFAULT_AES_GCM_TAG_LEN_BITS,
- pwd.getTag()));
- }
-
+ auto sIn = makeSerializer(dataId, pwd);
TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
sIn.Serialize(inMemory);
uint32_t data_size = 0;
GetDataSize(dataId, data_size);
+ LogDebug("GetData data_size = [" << data_size << "]");
+
TZSerializer sOut;
sOut.Push(new TZSerializableBinary(data_size));
TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
sOut.Serialize(outMemory);
- TEEC_Operation op;
- op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
- TEEC_MEMREF_WHOLE, TEEC_NONE);
- 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 = outMemory.Get();
- op.params[2].memref.offset = 0;
- op.params[2].memref.size = outMemory.Get()->size;
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
Execute(CMD_GET_DATA, &op);
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));
-
+ auto sIn = makeSerializer(dataId);
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,
- TEEC_NONE, TEEC_NONE);
+ TEEC_Operation op = makeOp(TEEC_VALUE_OUTPUT, inMemory);
- op.params[1].memref.parent = inMemory.Get();
- op.params[1].memref.offset = 0;
- op.params[1].memref.size = inMemory.Get()->size;
Execute(CMD_DESTROY_DATA, &op);
}
+TZSerializablePwdData* makeSerializablePwd(const Pwd &pwd)
+{
+ auto &tag = pwd.getTag();
+ return new TZSerializablePwdData(pwd.getPassword(), pwd.getIV(), tag.size() * 8, tag);
+}
+
+void TrustZoneContext::executeEcdh(const RawBuffer &prvKeyId,
+ const Pwd &prvKeyPwd,
+ const RawBuffer &pubX,
+ const RawBuffer &pubY,
+ const RawBuffer &secretPwdBuf,
+ const RawBuffer &secretPwdIV,
+ RawBuffer &secretTag,
+ const RawBuffer &secretHash)
+{
+ // command ID = CMD_DERIVE
+ LogDebug("TrustZoneContext::executeEcdh");
+
+ auto sIn = makeSerializer(
+ prvKeyId, prvKeyPwd, pubX, pubY, EncPwd{secretPwdBuf, secretPwdIV}, secretHash);
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
+
+ TZSerializer sOut;
+ if (!secretPwdBuf.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 (!secretPwdBuf.empty())
+ op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
+ op.params[0].value.a = ALGO_ECDH_DRV;
+
+ Execute(CMD_DERIVE, &op);
+
+ if (!secretPwdBuf.empty()) {
+ sOut.Deserialize(outMemory);
+ sOut.Pull(secretTag);
+ }
+
+ LogDebug("Derived object ID is (hex): " << rawToHexString(secretHash));
+}
+
+void TrustZoneContext::executeKbkdf(const RawBuffer& secretId,
+ const Pwd& secretPwd,
+ 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
+ LogDebug("TrustZoneContext::executeKbkdf");
+
+ auto sIn = makeSerializer(secretId,
+ secretPwd,
+ 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, &op);
+
+ if (!keyPwdBuf.empty()) {
+ sOut.Deserialize(outMemory);
+ sOut.Pull(keyTag);
+ }
+
+ LogDebug("Derived object ID is (hex): " << rawToHexString(keyHash));
+}
+
void TrustZoneContext::Initialize()
{
TEEC_Operation op;