+void TrustZoneContext::executeSign(tz_algo_type algo,
+ tz_hash_type hash,
+ const RawBuffer &keyId,
+ const Pwd &pwd,
+ const RawBuffer &message,
+ 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);
+ }
+
+ 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);
+ }
+
+ TEEC_Operation op;
+ op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
+ TEEC_MEMREF_WHOLE, TEEC_NONE);
+ 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);
+ }
+
+ signature.resize(outData->data_size);
+ memcpy(signature.data(), outData->data, outData->data_size);
+}
+
+int TrustZoneContext::executeVerify(tz_algo_type algo,
+ tz_hash_type hash,
+ const RawBuffer &keyId,
+ const Pwd &pwd,
+ const RawBuffer &message,
+ 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);
+ }
+
+ 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 = 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;
+ switch (opRet) {
+ case KM_TA_SUCCESS:
+ return CKM_API_SUCCESS;
+ case KM_TA_ERROR_SIGNATURE:
+ LogWarning("Signature verification failed");
+ return CKM_API_ERROR_VERIFICATION_FAILED;
+ default:
+ assert(false); // This condition should be checked inside Execute() function
+ ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", opRet);
+ }
+}
+