2 * Copyright (c) 2017 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 * @file tz-context.cpp
18 * @author Lukasz Kostyra (l.kostyra@samsung.com)
22 #include <tz-backend/tz-context.h>
23 #include <tz-backend/tz-memory.h>
24 #include <generic-backend/exception.h>
25 #include <generic-backend/crypto-params.h>
26 #include <generic-backend/encryption-params.h>
27 #include <dpl/log/log.h>
29 #include <km_serialization.h>
30 #include <km_ta_defines.h>
37 #include <unordered_map>
46 // A little bit of extra memory to add to output buffers.
48 // We need this extra memory to output for padding purposes - after encryption
49 // we can resize the result memory back to its proper size according to
50 // whatever TA will return us.
51 const uint32_t CIPHER_EXTRA_PADDING_SIZE = 16;
53 // Identifier of our TA
54 const TEEC_UUID KEY_MANAGER_TA_UUID = KM_TA_UUID;
56 //raw to hex string conversion to print persistent storage data ID
57 static std::string rawToHexString(const RawBuffer &raw)
63 snprintf(buf, sizeof(buf), "%02x", (e & 0xff));
64 dump.push_back(buf[0]);
65 dump.push_back(buf[1]);
72 * Maximum size for given key type in bytes according to key-manager-ta implementation.
73 * Note that they are greater than TEE Internal Core API v1.1.2.50 (Table 5-9) values.
75 const std::unordered_map<tz_algo_type, size_t> MAX_KEY_SIZE = {
76 { ALGO_RSA, 4096 / 8 },
77 { ALGO_RSA_SV, 4096 / 8 },
78 { ALGO_DSA_SV, 4096 / 8 }
81 void DeserializeKeyID(TrustZoneMemory &mem, RawBuffer &id)
83 LogDebug("Deserializing key ID");
85 KM_SymmetricInput* output = nullptr;
86 int ret = KM_ParamsDeserializationInit(mem.Get()->buffer, mem.Get()->size, &output);
88 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize key ID data deserialization: ", ret);
91 KM_OutData* outData = nullptr;
92 ret = KM_ParamsDeserializeOutData(output, &outData);
94 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize key ID data: ", ret);
97 if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
98 ThrowErr(Exc::Crypto::InternalError, "Deserialized invalid key ID");
101 // data_size should contain how much memory we actually took for our cipher operation
102 id.resize(outData->data_size);
103 memcpy(id.data(), outData->data, outData->data_size);
106 } // anonymous namespace
108 TrustZoneContext::TrustZoneContext()
109 : m_ContextInitialized(false)
110 , m_SessionInitialized(false)
115 TrustZoneContext::~TrustZoneContext()
120 TrustZoneContext& TrustZoneContext::Instance()
122 static TrustZoneContext instance;
126 void TrustZoneContext::generateIV(RawBuffer& iv)
128 // command ID = CMD_GENERATE_IV
130 // TEEC_Operation layout:
132 // [1].memref.buffer - output
133 // [1].memref.size - output size
135 // [0].value.a - return code
137 // IV generation is a simple call - no need to serialize data
138 // just provide the output buffer with size equal to iv.
139 uint32_t ivSize = Params::DEFAULT_AES_IV_LEN;
140 TrustZoneMemory ivMemory(m_Context, ivSize, TEEC_MEM_OUTPUT);
143 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
144 TEEC_NONE, TEEC_NONE);
145 op.params[1].memref.parent = ivMemory.Get();
146 op.params[1].memref.offset = 0;
147 op.params[1].memref.size = ivMemory.Get()->size;
148 Execute(CMD_GENERATE_IV, &op);
151 memcpy(iv.data(), ivMemory.Get()->buffer, ivMemory.Get()->size);
154 void TrustZoneContext::generateSKey(tz_algo_type algo,
155 uint32_t keySizeBits,
158 // command ID = CMD_GENERATE_KEY
160 // TEEC_Operation layout:
162 // [0].value.a - key type
163 // [0].value.b - key bit size
165 // [0].value.a - return code
166 // [1].memref - serialized key reference
168 KM_BufferSizeDesc bufSize;
170 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
171 bufSize.out_size = KM_KEY_ID_SIZE;
172 uint32_t keyMemorySize = KM_CalcBufferSize(bufSize);
173 TrustZoneMemory keyMemory(m_Context, keyMemorySize, TEEC_MEM_OUTPUT);
176 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
177 TEEC_NONE, TEEC_NONE);
178 op.params[0].value.a = algo;
179 op.params[0].value.b = keySizeBits;
180 op.params[1].memref.parent = keyMemory.Get();
181 op.params[1].memref.offset = 0;
182 op.params[1].memref.size = keyMemorySize;
183 Execute(CMD_GENERATE_KEY, &op);
185 DeserializeKeyID(keyMemory, keyId);
188 void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
189 const RawBuffer &pwd,
191 const uint32_t keySizeBits,
195 // command ID = CMD_GENERATE_KEY_PWD
197 // TEEC_Operation layout:
199 // [0].value.a - key type
200 // [0].value.b - key size in bits
201 // [1].memref - input (seralized pwd/iv for pbkdf2)
203 // [0].value.a - return code
204 // [2].memref - serialized key reference ID
206 KM_BufferSizeDesc bufSize;
208 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
209 bufSize.with_pwd_data = true;
210 bufSize.pwd_size = static_cast<uint32_t>(pwd.size());
211 bufSize.pwd_iv_size = static_cast<uint32_t>(iv.size());
212 uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
213 TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
215 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
216 bufSize.out_size = KM_KEY_ID_SIZE;
217 bufSize.tag_size = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
218 uint32_t keyMemorySize = KM_CalcBufferSize(bufSize);
219 TrustZoneMemory keyMemory(m_Context, keyMemorySize, TEEC_MEM_OUTPUT);
221 KM_SymmetricInput* input = nullptr;
222 int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
224 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
227 ret = KM_ParamsSerializePwdData(input, pwd.data(), pwd.size(), iv.data(), iv.size(),
228 nullptr, 0, Params::DERIVED_KEY_LENGTH_BITS,
229 Params::DERIVED_KEY_ITERATIONS, bufSize.tag_size * 8);
231 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
235 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
236 TEEC_MEMREF_WHOLE, TEEC_NONE);
237 op.params[0].value.a = algo;
238 op.params[0].value.b = keySizeBits;
239 op.params[1].memref.parent = inMemory.Get();
240 op.params[1].memref.offset = 0;
241 op.params[1].memref.size = inMemory.Get()->size;
242 op.params[2].memref.parent = keyMemory.Get();
243 op.params[2].memref.offset = 0;
244 op.params[2].memref.size = keyMemory.Get()->size;
245 Execute(CMD_GENERATE_KEY_PWD, &op);
247 DeserializeKeyID(keyMemory, keyId);
249 KM_SymmetricInput* output = nullptr;
250 ret = KM_ParamsDeserializationInit(keyMemory.Get()->buffer, keyMemory.Get()->size, &output);
252 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize deserialization for generated key ID");
255 KM_OutData* outData = nullptr;
256 ret = KM_ParamsDeserializeOutData(output, &outData);
258 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize generated key ID");
261 KM_TagData* tagData = nullptr;
262 ret = KM_ParamsDeserializeTagData(output, &tagData);
264 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize key's tag");
267 if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
268 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key ID");
271 if (tagData == nullptr || tagData->data_size != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
272 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag");
275 keyId.resize(KM_KEY_ID_SIZE);
276 memcpy(keyId.data(), outData->data, KM_KEY_ID_SIZE);
278 pwdTag.resize(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
279 memcpy(pwdTag.data(), tagData->data, Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
282 void TrustZoneContext::GenerateAKey(tz_command commandId,
284 uint32_t keySizeBits,
285 const RawBuffer &pubPwd,
286 const RawBuffer &pubPwdIv,
287 const RawBuffer &privPwd,
288 const RawBuffer &privPwdIv,
290 RawBuffer &pubKeyTag,
291 RawBuffer &privKeyId,
292 RawBuffer &privKeyTag)
294 uint32_t pubTagSize = 0;
295 uint32_t privTagSize = 0;
297 uint32_t pubPwdExists = pubPwd.empty() ? 0 : 1;
298 sIn.Push(new TZSerializableFlag(pubPwdExists));
300 sIn.Push(new TZSerializablePwdData(pubPwd, pubPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
301 pubTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
303 uint32_t privPwdExists = privPwd.empty() ? 0 : 1;
304 sIn.Push(new TZSerializableFlag(privPwdExists));
306 sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
307 privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
310 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
311 sIn.Serialize(inMemory);
314 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
315 sOut.Push(new TZSerializableBinary(pubTagSize));
316 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
317 sOut.Push(new TZSerializableBinary(privTagSize));
319 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
322 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
323 TEEC_MEMREF_WHOLE, TEEC_NONE);
324 op.params[0].value.b = keySizeBits;
325 op.params[1].memref.parent = inMemory.Get();
326 op.params[1].memref.offset = 0;
327 op.params[1].memref.size = inMemory.Get()->size;
328 op.params[2].memref.parent = outMemory.Get();
329 op.params[2].memref.offset = 0;
330 op.params[2].memref.size = outMemory.Get()->size;
331 Execute(commandId, &op);
333 sOut.Deserialize(outMemory);
336 if (pubKeyId.size() != KM_KEY_ID_SIZE) {
337 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize public key ID");
341 sOut.Pull(pubKeyTag);
344 sOut.Pull(privKeyId);
345 if (privKeyId.size() != KM_KEY_ID_SIZE) {
346 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize private key ID");
350 sOut.Pull(privKeyTag);
354 void TrustZoneContext::generateRSAKey(uint32_t keySizeBits,
355 const RawBuffer &pubPwd,
356 const RawBuffer &pubPwdIv,
357 const RawBuffer &privPwd,
358 const RawBuffer &privPwdIv,
360 RawBuffer &pubKeyTag,
361 RawBuffer &privKeyId,
362 RawBuffer &privKeyTag)
364 // command ID = CMD_GENERATE_RSA_KEYPAIR
366 // TEEC_Operation layout:
368 // [0].value.b - key bit size
369 // [1].memref - reference to serialized buffer:
370 // flag marking the public key password presence,
371 // public key password data if the flag above is not 0,
372 // flag marking the private key password presence,
373 // public key private data if the flag above is not 0,
375 // [0].value.a - return code
378 // public key tag if password was present,
380 // private key tag if password was present,
384 GenerateAKey(CMD_GENERATE_RSA_KEYPAIR,
397 void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
398 const RawBuffer &prime,
399 const RawBuffer &subprime,
400 const RawBuffer &base,
401 const RawBuffer &pubPwd,
402 const RawBuffer &pubPwdIv,
403 const RawBuffer &privPwd,
404 const RawBuffer &privPwdIv,
406 RawBuffer &pubKeyTag,
407 RawBuffer &privKeyId,
408 RawBuffer &privKeyTag)
410 // command ID = CMD_GENERATE_DSA_KEYPAIR
412 // TEEC_Operation layout:
414 // [0].value.b - key bit size
415 // [1].memref - reference to serialized buffer:
416 // prime, subprime, base,
417 // flag marking the public key password presence,
418 // public key password data if the flag above is not 0,
419 // flag marking the private key password presence,
420 // public key private data if the flag above is not 0,
422 // [0].value.a - return code
425 // public key tag if password was present,
427 // private key tag if password was present,
430 sIn.Push(new TZSerializableBinary(prime));
431 sIn.Push(new TZSerializableBinary(subprime));
432 sIn.Push(new TZSerializableBinary(base));
434 GenerateAKey(CMD_GENERATE_DSA_KEYPAIR,
447 void TrustZoneContext::executeCrypt(tz_command cmd,
449 const RawBuffer &keyId,
452 const RawBuffer &data,
455 // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
457 // TEEC_Operation layout:
459 // [0].value.a - keyid
460 // [0].value.b - algo
461 // [1].memref - input data (serialized key/input)
463 // [0].value.a - return code
464 // [2].memref - serialized output buffer
466 if (keyId.size() != KM_KEY_ID_SIZE) {
467 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
468 + std::to_string(keyId.size()) + ")");
471 KM_BufferSizeDesc bufSize;
473 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
474 bufSize.input_size = static_cast<uint32_t>(data.size());
475 bufSize.with_pwd_data = true;
476 bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
477 bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
478 bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
479 bufSize.iv_size = static_cast<uint32_t>(iv.size());
480 bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
481 uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
482 TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
484 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
486 // decrypt operation does not require padding
487 bufSize.out_size = static_cast<uint32_t>(data.size());
488 if (cmd == CMD_ENCRYPT) {
489 if (algo == ALGO_RSA) {
490 // We don't know the key length
491 bufSize.out_size = MAX_KEY_SIZE.at(ALGO_RSA);
493 bufSize.out_size = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
496 uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
497 TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
499 KM_SymmetricInput* input = nullptr;
500 int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
502 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
505 ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
507 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
510 uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
511 ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
512 pwd.getIV().data(), pwd.getIV().size(),
513 pwd.getTag().data(), pwd.getTag().size(),
514 Params::DERIVED_KEY_LENGTH_BITS,
515 Params::DERIVED_KEY_ITERATIONS,
518 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
521 ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
523 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
526 ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
528 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
532 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
533 TEEC_MEMREF_WHOLE, TEEC_NONE);
534 op.params[0].value.a = algo;
535 op.params[1].memref.parent = inMemory.Get();
536 op.params[1].memref.offset = 0;
537 op.params[1].memref.size = inMemory.Get()->size;
538 op.params[2].memref.parent = outMemory.Get();
539 op.params[2].memref.offset = 0;
540 op.params[2].memref.size = outMemory.Get()->size;
543 KM_SymmetricInput* output = nullptr;
544 ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
546 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
549 KM_OutData* outData = nullptr;
550 ret = KM_ParamsDeserializeOutData(output, &outData);
552 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
555 // data_size should contain how much memory we actually took for our cipher operation
558 out.resize(outData->data_size);
559 memcpy(out.data(), outData->data, outData->data_size);
563 void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
567 const RawBuffer &aad,
568 const RawBuffer &data,
572 // command ID = CMD_ENCRYPT (from km_ta_defines.h)
574 // TEEC_Operation layout:
576 // [0].value.a - keyid
577 // [0].value.b - algo
578 // [1].memref - input data (serialized key/input/iv/aad)
580 // [0].value.a - return code
581 // [2].memref - output
583 if (keyId.size() != KM_KEY_ID_SIZE) {
584 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
587 uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
588 KM_BufferSizeDesc bufSize;
590 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
591 bufSize.input_size = static_cast<uint32_t>(data.size());
592 bufSize.with_pwd_data = true;
593 bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
594 bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
595 bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
596 bufSize.iv_size = static_cast<uint32_t>(iv.size());
597 bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
598 bufSize.with_ae_data = true;
599 bufSize.aad_size = static_cast<uint32_t>(aad.size());
600 uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
601 TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
603 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
604 bufSize.out_size = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
605 bufSize.tag_size = static_cast<uint32_t>(tagSizeBytes);
606 uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
607 TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
609 KM_SymmetricInput* input = nullptr;
610 int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
612 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
615 ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
617 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
620 uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
621 ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
622 pwd.getIV().data(), pwd.getIV().size(),
623 pwd.getTag().data(), pwd.getTag().size(),
624 Params::DERIVED_KEY_LENGTH_BITS,
625 Params::DERIVED_KEY_ITERATIONS,
628 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
631 ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
633 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
636 ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
638 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
641 ret = KM_ParamsSerializeAEData(input, tagSizeBits, 0, aad.data(), aad.size());
643 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize auth data for TZ crypto operation: ", ret);
647 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
648 TEEC_MEMREF_WHOLE, TEEC_NONE);
649 op.params[0].value.a = ALGO_AES_GCM;
650 op.params[1].memref.parent = inMemory.Get();
651 op.params[1].memref.offset = 0;
652 op.params[1].memref.size = inMemory.Get()->size;
653 op.params[2].memref.parent = outMemory.Get();
654 op.params[2].memref.offset = 0;
655 op.params[2].memref.size = outMemory.Get()->size;
656 Execute(CMD_ENCRYPT, &op);
658 KM_SymmetricInput* output = nullptr;
659 ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
661 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
664 KM_OutData* outData = nullptr;
665 ret = KM_ParamsDeserializeOutData(output, &outData);
667 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
670 KM_TagData* tagData = nullptr;
671 ret = KM_ParamsDeserializeTagData(output, &tagData);
673 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize tag data: ", ret);
678 out.resize(outData->data_size);
679 memcpy(out.data(), outData->data, outData->data_size);
683 if (tagData && tagData->data_size) {
684 tag.resize(tagData->data_size);
685 memcpy(tag.data(), tagData->data, tagData->data_size);
689 void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
693 const RawBuffer &tag,
694 const RawBuffer &aad,
695 const RawBuffer &data,
698 // command ID = CMD_DECRYPT (from km_ta_defines.h)
700 // TEEC_Operation layout:
702 // [0].value.a - keyid
703 // [0].value.b - algo
704 // [1].memref - input data (serialized key/input/iv/tag/aad)
706 // [0].value.a - output size
707 // [2].memref - output (decrypted data)
709 if (keyId.size() != KM_KEY_ID_SIZE) {
710 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
713 KM_BufferSizeDesc bufSize;
715 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
716 bufSize.input_size = static_cast<uint32_t>(data.size());
717 bufSize.with_pwd_data = true;
718 bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
719 bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
720 bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
721 bufSize.iv_size = static_cast<uint32_t>(iv.size());
722 bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
723 bufSize.with_ae_data = true;
724 bufSize.aad_size = static_cast<uint32_t>(aad.size());
725 bufSize.tag_size = static_cast<uint32_t>(tag.size());
726 uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
727 TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
729 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
730 bufSize.out_size = static_cast<uint32_t>(data.size());
731 uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
732 TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
734 KM_SymmetricInput* input = nullptr;
735 int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
737 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
740 ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
742 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
745 uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
746 ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
747 pwd.getIV().data(), pwd.getIV().size(),
748 pwd.getTag().data(), pwd.getTag().size(),
749 Params::DERIVED_KEY_LENGTH_BITS,
750 Params::DERIVED_KEY_ITERATIONS,
753 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
756 ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
758 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
761 ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
763 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
766 ret = KM_ParamsSerializeAEData(input, tagSizeBits, 0, aad.data(), aad.size());
768 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize auth data for TZ crypto operation: ", ret);
771 ret = KM_ParamsSerializeTagData(input, tag.data(), tag.size());
773 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize tag data for TZ crypto operation: ", ret);
777 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
778 TEEC_MEMREF_WHOLE, TEEC_NONE);
779 op.params[0].value.a = ALGO_AES_GCM;
780 op.params[1].memref.parent = inMemory.Get();
781 op.params[1].memref.offset = 0;
782 op.params[1].memref.size = inMemory.Get()->size;
783 op.params[2].memref.parent = outMemory.Get();
784 op.params[2].memref.offset = 0;
785 op.params[2].memref.size = outMemory.Get()->size;
786 Execute(CMD_DECRYPT, &op);
788 KM_SymmetricInput* output = nullptr;
789 ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
791 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
794 KM_OutData* outData = nullptr;
795 ret = KM_ParamsDeserializeOutData(output, &outData);
797 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
802 out.resize(outData->data_size);
803 memcpy(out.data(), outData->data, outData->data_size);
807 void TrustZoneContext::executeSign(tz_algo_type algo,
809 const RawBuffer &keyId,
811 const RawBuffer &message,
812 RawBuffer &signature)
814 // command ID = CMD_SIGN (from km_ta_defines.h)
816 // TEEC_Operation layout:
818 // [0].value.a - algorithm type (tz_algo_type)
819 // [0].value.b - hash type (tz_hash_type)
820 // [1].memref - reference to serialized buffer:
821 // KM_ParamsSerializeInputData with data to sign
822 // KM_ParamsSerializeKeyId with key id
824 // [0].value.a - return code
825 // [2].memref - reference to serialized buffer:
826 // KM_ParamsSerializeOutData with signature data
828 if (keyId.size() != KM_KEY_ID_SIZE) {
829 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
830 + std::to_string(keyId.size()) + ")");
833 KM_BufferSizeDesc bufSize;
835 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
836 bufSize.input_size = static_cast<uint32_t>(message.size());
837 bufSize.with_pwd_data = true;
838 bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
839 bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
840 bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
841 bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
842 uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
843 TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
845 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
846 bufSize.out_size = MAX_KEY_SIZE.at(algo);
847 uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
848 TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
850 KM_SymmetricInput* input = nullptr;
851 int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
853 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ sign operations");
856 ret = KM_ParamsSerializeInputData(input, message.data(), message.size());
858 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ sign operation: ", ret);
861 uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
862 ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
863 pwd.getIV().data(), pwd.getIV().size(),
864 pwd.getTag().data(), pwd.getTag().size(),
865 Params::DERIVED_KEY_LENGTH_BITS,
866 Params::DERIVED_KEY_ITERATIONS,
869 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ sign operation: ", ret);
872 ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
874 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ sign operation: ", ret);
878 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
879 TEEC_MEMREF_WHOLE, TEEC_NONE);
880 op.params[0].value.a = algo;
881 op.params[0].value.b = hash;
882 op.params[1].memref.parent = inMemory.Get();
883 op.params[1].memref.offset = 0;
884 op.params[1].memref.size = inMemory.Get()->size;
885 op.params[2].memref.parent = outMemory.Get();
886 op.params[2].memref.offset = 0;
887 op.params[2].memref.size = outMemory.Get()->size;
888 Execute(CMD_SIGN, &op);
890 KM_SymmetricInput* output = nullptr;
891 ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
893 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
896 KM_OutData* outData = nullptr;
897 ret = KM_ParamsDeserializeOutData(output, &outData);
898 if (ret || !outData || outData->data_size == 0) {
899 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
902 signature.resize(outData->data_size);
903 memcpy(signature.data(), outData->data, outData->data_size);
906 int TrustZoneContext::executeVerify(tz_algo_type algo,
908 const RawBuffer &keyId,
910 const RawBuffer &message,
911 const RawBuffer &signature)
913 // command ID = CMD_VERIFY (from km_ta_defines.h)
915 // TEEC_Operation layout:
917 // [0].value.a - algorithm type (tz_algo_type)
918 // [0].value.b - hash type (tz_hash_type)
919 // [1].memref - reference to serialized buffer:
920 // KM_ParamsSerializeInputData with verify data (signature hidden in Tag data)
921 // KM_ParamsSerializeKeyId with key id
923 // [0].value.a - return code
925 if (keyId.size() != KM_KEY_ID_SIZE) {
926 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
927 + std::to_string(keyId.size()) + ")");
930 KM_BufferSizeDesc bufSize;
932 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
933 bufSize.input_size = static_cast<uint32_t>(message.size());
934 bufSize.with_pwd_data = true;
935 bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
936 bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
937 bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
938 bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
939 bufSize.tag_size = static_cast<uint32_t>(signature.size());
940 uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
941 TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
943 KM_SymmetricInput* input = nullptr;
944 int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
946 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ sign operations");
949 ret = KM_ParamsSerializeInputData(input, message.data(), message.size());
951 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ sign operation: ", ret);
954 uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
955 ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
956 pwd.getIV().data(), pwd.getIV().size(),
957 pwd.getTag().data(), pwd.getTag().size(),
958 Params::DERIVED_KEY_LENGTH_BITS,
959 Params::DERIVED_KEY_ITERATIONS,
962 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ sign operation: ", ret);
965 ret = KM_ParamsSerializeKeyId(input, keyId.data(), keyId.size());
967 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ sign operation: ", ret);
970 ret = KM_ParamsSerializeTagData(input, signature.data(), signature.size());
972 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize signature data for TZ sign operation: ", ret);
976 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
977 TEEC_NONE, TEEC_NONE);
978 op.params[0].value.a = algo;
979 op.params[0].value.b = hash;
980 op.params[1].memref.parent = inMemory.Get();
981 op.params[1].memref.offset = 0;
982 op.params[1].memref.size = inMemory.Get()->size;
983 Execute(CMD_VERIFY, &op);
985 int opRet = op.params[0].value.a;
988 return CKM_API_SUCCESS;
989 case KM_TA_ERROR_SIGNATURE:
990 LogWarning("Signature verification failed");
991 return CKM_API_ERROR_VERIFICATION_FAILED;
993 assert(false); // This condition should be checked inside Execute() function
994 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", opRet);
998 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
1000 // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
1002 // TEEC_Operation layout:
1004 // [1].memref - input data (serialized key ID)
1006 // [0].value.a - return code
1008 if (keyId.size() != KM_KEY_ID_SIZE) {
1009 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
1012 KM_BufferSizeDesc bufSize;
1014 memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
1015 bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
1016 uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
1017 TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
1019 KM_SymmetricInput* input = nullptr;
1020 int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
1022 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization: ", ret);
1025 ret = KM_ParamsSerializeInputData(input, keyId.data(), keyId.size());
1027 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key ID to destroy: ", ret);
1031 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
1032 TEEC_NONE, TEEC_NONE);
1033 op.params[1].memref.parent = inMemory.Get();
1034 op.params[1].memref.offset = 0;
1035 op.params[1].memref.size = inMemory.Get()->size;
1036 Execute(CMD_DESTROY_KEY, &op);
1039 void TrustZoneContext::importData(
1040 const uint32_t dataType,
1041 const RawBuffer &data,
1042 const Crypto::EncryptionParams &encData,
1043 const RawBuffer &pwd,
1044 const RawBuffer &iv,
1045 const uint32_t keySizeBits,
1046 const uint32_t pwdTagSizeBits,
1050 // command ID = CMD_IMPORT_DATA
1052 // [1].memref - reference to serialized buffer:
1053 // uint32_t dataType contains information about type stored as binary data
1054 // KM_BinaryData with binary data
1055 // uint32_t binary/key size in bits
1056 // KM_BinaryData IV for data decryption with built in key
1057 // KM_BinaryData TAG for data decryption with built in key
1058 // uint32_t boolean value - true if password is provided
1059 // KM_PwdData with password (optional)
1061 // [0].value.a - return code
1062 // [2].memref - reference to serialized buffer:
1063 // KM_BinaryData with data id
1064 // KM_BinaryData with tag id (optional, if password was provided)
1067 sIn.Push(new TZSerializableFlag(dataType));
1068 sIn.Push(new TZSerializableBinary(data));
1069 sIn.Push(new TZSerializableFlag(keySizeBits));
1070 sIn.Push(new TZSerializableBinary(encData.iv));
1071 sIn.Push(new TZSerializableBinary(encData.tag));
1073 uint32_t pwd_flag = pwd.empty() ? 0 : 1;
1074 sIn.Push(new TZSerializableFlag(pwd_flag));
1076 sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
1078 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
1079 sIn.Serialize(inMemory);
1083 sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE));
1085 sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
1088 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
1091 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
1092 TEEC_MEMREF_WHOLE, TEEC_NONE);
1093 op.params[1].memref.parent = inMemory.Get();
1094 op.params[1].memref.offset = 0;
1095 op.params[1].memref.size = inMemory.Get()->size;
1096 op.params[2].memref.parent = outMemory.Get();
1097 op.params[2].memref.offset = 0;
1098 op.params[2].memref.size = outMemory.Get()->size;
1100 Execute(CMD_IMPORT_DATA, &op);
1102 sOut.Deserialize(outMemory);
1108 LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
1111 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
1113 // command ID = CMD_GET_DATA_SIZE
1114 // TA will decrypt data with password if provided
1116 // [1].memref - reference to serialized buffer:
1117 // KM_BinaryData with object ID
1119 // [0].value.a - return code
1120 // [0].value.b - size of buffer to be passed from CA
1121 LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
1124 sIn.Push(new TZSerializableBinary(dataId));
1126 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
1127 sIn.Serialize(inMemory);
1130 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
1131 TEEC_NONE, TEEC_NONE);
1133 op.params[1].memref.parent = inMemory.Get();
1134 op.params[1].memref.offset = 0;
1135 op.params[1].memref.size = inMemory.Get()->size;
1136 Execute(CMD_GET_DATA_SIZE, &op);
1137 dataSize = op.params[0].value.b;
1140 void TrustZoneContext::getData(const RawBuffer &dataId,
1144 // command ID = CMD_GET_DATA
1145 // TA will decrypt data with password if provided
1147 // [1].memref - reference to serialized buffer:
1148 // KM_BinaryData with object ID
1149 // uint32_t boolean value - true if password is provided
1150 // KM_PwdData with password (optional)
1152 // [0].value.a - return code
1153 // [2].memref - reference to serialized buffer:
1154 // KM_BinaryData with binary data
1155 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
1158 sIn.Push(new TZSerializableBinary(dataId));
1160 uint32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
1161 sIn.Push(new TZSerializableFlag(pwd_flag));
1164 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
1166 Params::DEFAULT_AES_GCM_TAG_LEN_BITS,
1170 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
1171 sIn.Serialize(inMemory);
1173 uint32_t data_size = 0;
1174 GetDataSize(dataId, data_size);
1177 sOut.Push(new TZSerializableBinary(data_size));
1178 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
1179 sOut.Serialize(outMemory);
1182 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
1183 TEEC_MEMREF_WHOLE, TEEC_NONE);
1184 op.params[1].memref.parent = inMemory.Get();
1185 op.params[1].memref.offset = 0;
1186 op.params[1].memref.size = inMemory.Get()->size;
1187 op.params[2].memref.parent = outMemory.Get();
1188 op.params[2].memref.offset = 0;
1189 op.params[2].memref.size = outMemory.Get()->size;
1191 Execute(CMD_GET_DATA, &op);
1193 sOut.Deserialize(outMemory);
1198 void TrustZoneContext::destroyData(const RawBuffer &dataId)
1200 // command ID = CMD_DESTROY_DATA
1201 // TEEC_Operation parameters layout:
1203 // [1].memref - reference to serialized buffer:
1204 // KM_BinaryData with object ID
1206 // [0].value.a - return code
1207 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
1209 sIn.Push(new TZSerializableBinary(dataId));
1211 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
1212 sIn.Serialize(inMemory);
1215 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
1216 TEEC_NONE, TEEC_NONE);
1218 op.params[1].memref.parent = inMemory.Get();
1219 op.params[1].memref.offset = 0;
1220 op.params[1].memref.size = inMemory.Get()->size;
1221 Execute(CMD_DESTROY_DATA, &op);
1224 void TrustZoneContext::Initialize()
1230 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
1232 result = TEEC_InitializeContext(nullptr, &m_Context);
1233 if (result != TEEC_SUCCESS) {
1234 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize TEE context: ", result);
1236 m_ContextInitialized = true;
1238 result = TEEC_OpenSession(&m_Context, &m_Session, &KEY_MANAGER_TA_UUID, 0, nullptr, &op, &retOrigin);
1239 if (result != TEEC_SUCCESS) {
1240 ThrowErr(Exc::Crypto::InternalError, "Failed to open session to Key Manager TA: ", result);
1242 m_SessionInitialized = true;
1245 void TrustZoneContext::Destroy()
1247 if (m_SessionInitialized) {
1248 TEEC_CloseSession(&m_Session);
1249 m_SessionInitialized = false;
1252 if (m_ContextInitialized) {
1253 TEEC_FinalizeContext(&m_Context);
1254 m_ContextInitialized = false;
1258 void TrustZoneContext::Reload()
1264 void TrustZoneContext::Execute(tz_command commandID, TEEC_Operation* op)
1266 uint32_t retOrigin = 0;
1267 LogDebug("Executing TZ operation " << commandID);
1269 TEEC_Result result = TEEC_InvokeCommand(&m_Session, static_cast<unsigned int>(commandID), op, &retOrigin);
1270 if (result != TEEC_SUCCESS) {
1272 case TEEC_ERROR_TARGET_DEAD:
1274 ThrowErr(Exc::Crypto::InternalError, "TA panicked while executing command ",
1275 static_cast<unsigned int>(commandID));
1276 case TEEC_ERROR_BAD_PARAMETERS:
1277 ThrowErr(Exc::Crypto::InputParam, "Incorrect parameters provided to TA");
1279 ThrowErr(Exc::Crypto::InternalError, "TA failed to invoke command ",
1280 static_cast<unsigned int>(commandID), " with error: ", std::hex,
1281 static_cast<unsigned int>(result), " with origin: ", std::hex,
1286 int ta_ret = op->params[0].value.a;
1289 case KM_TA_ERROR_SIGNATURE:
1291 case KM_TA_ERROR_AUTH_FAILED:
1292 // Authentication cipher failed - notify with proper exception
1293 ThrowErr(Exc::AuthenticationFailed, "Crypto operation authentication failed");
1295 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", ta_ret);
1299 } // namespace Internals
1301 } // namespace Crypto