// 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;
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 {
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,
TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
- op.params[0].value.b = keySizeBits;
+ op.params[0].value.b = genParam;
Execute(commandId, &op);
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,
tz_algo_type algo,
const RawBuffer &keyId,
sOut.Pull(out);
}
+uint32_t TrustZoneContext::initGcmCipher(uint32_t encrypt,
+ const RawBuffer &keyId,
+ const Pwd &pwd,
+ const RawBuffer &iv,
+ int tagSizeBits,
+ const RawBuffer &aad)
+{
+ // command ID = CMD_CIPHER_INIT (from km_ta_defines.h)
+ if (keyId.size() != KM_KEY_ID_SIZE) {
+ ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
+ }
+
+ auto sIn = makeSerializer(pwd, iv, keyId, aad, tagSizeBits);
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
+
+ TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
+ op.params[0].value.a = ALGO_AES_GCM;
+ op.params[0].value.b = encrypt;
+
+ Execute(CMD_CIPHER_INIT, &op);
+
+ return op.params[0].value.b;
+}
+
+void TrustZoneContext::addGcmAAD(uint32_t opId,
+ const RawBuffer &aad)
+{
+ // command ID = CMD_CIPHER_INIT_AAD (from km_ta_defines.h)
+ auto sIn = makeSerializer(aad);
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
+
+ TEEC_Operation op = makeOp(TEEC_VALUE_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;
+}
+
+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,
tz_hash_type hash,
const RawBuffer &keyId,
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
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;