2 * Copyright (c) 2017-2021 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 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
24 #include <tz-backend/tz-context.h>
25 #include <tz-backend/tz-memory.h>
26 #include <generic-backend/exception.h>
27 #include <generic-backend/crypto-params.h>
28 #include <generic-backend/encryption-params.h>
29 #include <dpl/log/log.h>
31 #include <km_serialization.h>
32 #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)
59 return hexDump<std::string>(raw);
63 * Maximum size for given key type in bytes according to key-manager-ta implementation.
64 * Note that they are greater than TEE Internal Core API v1.1.2.50 (Table 5-9) values.
66 const std::unordered_map<tz_algo_type, size_t> MAX_KEY_SIZE = {
67 { ALGO_RSA, 4096 / 8 },
68 { ALGO_RSA_SV, 4096 / 8 },
69 { ALGO_DSA_SV, 4096 / 8 }
72 } // anonymous namespace
74 TrustZoneContext::TrustZoneContext()
75 : m_ContextInitialized(false)
76 , m_SessionInitialized(false)
81 TrustZoneContext::~TrustZoneContext()
86 TrustZoneContext& TrustZoneContext::Instance()
88 static TrustZoneContext instance;
92 void TrustZoneContext::generateIV(RawBuffer& iv)
94 // command ID = CMD_GENERATE_IV
95 // IV generation is a simple call - no need to serialize data
96 // just provide the output buffer with size equal to iv.
97 uint32_t ivSize = Params::DEFAULT_AES_IV_LEN;
98 TrustZoneMemory ivMemory(m_Context, ivSize, TEEC_MEM_OUTPUT);
101 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
102 TEEC_NONE, TEEC_NONE);
103 op.params[1].memref.parent = ivMemory.Get();
104 op.params[1].memref.offset = 0;
105 op.params[1].memref.size = ivMemory.Get()->size;
106 Execute(CMD_GENERATE_IV, &op);
109 memcpy(iv.data(), ivMemory.Get()->buffer, ivMemory.Get()->size);
112 void TrustZoneContext::generateSKey(tz_algo_type algo,
113 uint32_t keySizeBits,
114 const RawBuffer &hash)
116 // command ID = CMD_GENERATE_KEY
118 sIn.Push(new TZSerializableBinary(hash));
119 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
120 sIn.Serialize(inMemory);
123 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
124 TEEC_NONE, TEEC_NONE);
125 op.params[0].value.a = algo;
126 op.params[0].value.b = keySizeBits;
127 op.params[1].memref.parent = inMemory.Get();
128 op.params[1].memref.offset = 0;
129 op.params[1].memref.size = inMemory.Get()->size;
130 Execute(CMD_GENERATE_KEY, &op);
133 void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
134 const RawBuffer &pwd,
136 const uint32_t keySizeBits,
138 const RawBuffer &hash)
140 // command ID = CMD_GENERATE_KEY_PWD
142 sIn.Push(new TZSerializablePwdData(pwd, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
143 sIn.Push(new TZSerializableBinary(hash));
144 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
145 sIn.Serialize(inMemory);
148 sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
149 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
152 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
153 TEEC_MEMREF_WHOLE, TEEC_NONE);
154 op.params[0].value.a = algo;
155 op.params[0].value.b = keySizeBits;
156 op.params[1].memref.parent = inMemory.Get();
157 op.params[1].memref.offset = 0;
158 op.params[1].memref.size = inMemory.Get()->size;
159 op.params[2].memref.parent = outMemory.Get();
160 op.params[2].memref.offset = 0;
161 op.params[2].memref.size = outMemory.Get()->size;
162 Execute(CMD_GENERATE_KEY_PWD, &op);
164 sOut.Deserialize(outMemory);
167 if (pwdTag.size() != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
168 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag");
172 void TrustZoneContext::GenerateAKey(tz_command commandId,
174 uint32_t keySizeBits,
175 const RawBuffer &pubPwd,
176 const RawBuffer &pubPwdIv,
177 const RawBuffer &privPwd,
178 const RawBuffer &privPwdIv,
179 RawBuffer &pubKeyTag,
180 RawBuffer &privKeyTag,
181 const RawBuffer &hashPriv,
182 const RawBuffer &hashPub)
184 uint32_t pubTagSize = 0;
185 uint32_t privTagSize = 0;
187 uint32_t pubPwdExists = pubPwd.empty() ? 0 : 1;
188 sIn.Push(new TZSerializableFlag(pubPwdExists));
190 sIn.Push(new TZSerializablePwdData(pubPwd, pubPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
191 pubTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
193 uint32_t privPwdExists = privPwd.empty() ? 0 : 1;
194 sIn.Push(new TZSerializableFlag(privPwdExists));
196 sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
197 privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
199 sIn.Push(new TZSerializableBinary(hashPriv));
200 sIn.Push(new TZSerializableBinary(hashPub));
201 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
202 sIn.Serialize(inMemory);
205 sOut.Push(new TZSerializableBinary(pubTagSize));
206 sOut.Push(new TZSerializableBinary(privTagSize));
208 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
211 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
212 TEEC_MEMREF_WHOLE, TEEC_NONE);
213 op.params[0].value.b = keySizeBits;
214 op.params[1].memref.parent = inMemory.Get();
215 op.params[1].memref.offset = 0;
216 op.params[1].memref.size = inMemory.Get()->size;
217 op.params[2].memref.parent = outMemory.Get();
218 op.params[2].memref.offset = 0;
219 op.params[2].memref.size = outMemory.Get()->size;
220 Execute(commandId, &op);
222 sOut.Deserialize(outMemory);
224 sOut.Pull(pubKeyTag);
228 sOut.Pull(privKeyTag);
232 void TrustZoneContext::generateRSAKey(uint32_t keySizeBits,
233 const RawBuffer &pubPwd,
234 const RawBuffer &pubPwdIv,
235 const RawBuffer &privPwd,
236 const RawBuffer &privPwdIv,
237 RawBuffer &pubKeyTag,
238 RawBuffer &privKeyTag,
239 const RawBuffer &hashPriv,
240 const RawBuffer &hashPub)
242 // command ID = CMD_GENERATE_RSA_KEYPAIR
245 GenerateAKey(CMD_GENERATE_RSA_KEYPAIR,
258 void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
259 const RawBuffer &prime,
260 const RawBuffer &subprime,
261 const RawBuffer &base,
262 const RawBuffer &pubPwd,
263 const RawBuffer &pubPwdIv,
264 const RawBuffer &privPwd,
265 const RawBuffer &privPwdIv,
266 RawBuffer &pubKeyTag,
267 RawBuffer &privKeyTag,
268 const RawBuffer &hashPriv,
269 const RawBuffer &hashPub)
271 // command ID = CMD_GENERATE_DSA_KEYPAIR
273 sIn.Push(new TZSerializableBinary(prime));
274 sIn.Push(new TZSerializableBinary(subprime));
275 sIn.Push(new TZSerializableBinary(base));
277 GenerateAKey(CMD_GENERATE_DSA_KEYPAIR,
290 void TrustZoneContext::executeCrypt(tz_command cmd,
292 const RawBuffer &keyId,
295 const RawBuffer &data,
298 // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
299 if (keyId.size() != KM_KEY_ID_SIZE) {
300 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
301 + std::to_string(keyId.size()) + ")");
305 sIn.Push(new TZSerializableBinary(data));
306 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
307 sIn.Push(new TZSerializableFlag(pwd_flag));
309 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
311 pwd.getTag().size() * 8,
313 if (algo != ALGO_RSA)
314 sIn.Push(new TZSerializableBinary(iv));
315 sIn.Push(new TZSerializableBinary(keyId));
317 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
318 sIn.Serialize(inMemory);
320 // decrypt operation does not require padding
321 uint32_t outMemorySize = data.size();
322 if (cmd == CMD_ENCRYPT) {
323 if (algo == ALGO_RSA) {
324 // We don't know the key length
325 outMemorySize = MAX_KEY_SIZE.at(ALGO_RSA);
327 outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
332 sOut.Push(new TZSerializableBinary(outMemorySize, false));
333 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
336 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
337 TEEC_MEMREF_WHOLE, TEEC_NONE);
338 op.params[0].value.a = algo;
339 op.params[1].memref.parent = inMemory.Get();
340 op.params[1].memref.offset = 0;
341 op.params[1].memref.size = inMemory.Get()->size;
342 op.params[2].memref.parent = outMemory.Get();
343 op.params[2].memref.offset = 0;
344 op.params[2].memref.size = outMemory.Get()->size;
348 sOut.Deserialize(outMemory);
352 void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
356 const RawBuffer &aad,
357 const RawBuffer &data,
361 // command ID = CMD_ENCRYPT (from km_ta_defines.h)
362 if (keyId.size() != KM_KEY_ID_SIZE) {
363 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
367 sIn.Push(new TZSerializableBinary(data));
368 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
369 sIn.Push(new TZSerializableFlag(pwd_flag));
371 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
373 pwd.getTag().size() * 8,
375 sIn.Push(new TZSerializableBinary(iv));
376 sIn.Push(new TZSerializableBinary(keyId));
377 sIn.Push(new TZSerializableBinary(aad));
378 sIn.Push(new TZSerializableFlag(tagSizeBits));
380 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
381 sIn.Serialize(inMemory);
383 uint32_t outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
384 uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
387 sOut.Push(new TZSerializableBinary(outMemorySize, false));
388 sOut.Push(new TZSerializableBinary(tagSizeBytes));
389 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
392 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
393 TEEC_MEMREF_WHOLE, TEEC_NONE);
394 op.params[0].value.a = ALGO_AES_GCM;
395 op.params[1].memref.parent = inMemory.Get();
396 op.params[1].memref.offset = 0;
397 op.params[1].memref.size = inMemory.Get()->size;
398 op.params[2].memref.parent = outMemory.Get();
399 op.params[2].memref.offset = 0;
400 op.params[2].memref.size = outMemory.Get()->size;
402 Execute(CMD_ENCRYPT, &op);
404 sOut.Deserialize(outMemory);
409 void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
413 const RawBuffer &tag,
414 const RawBuffer &aad,
415 const RawBuffer &data,
418 // command ID = CMD_DECRYPT (from km_ta_defines.h)
419 if (keyId.size() != KM_KEY_ID_SIZE) {
420 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
424 sIn.Push(new TZSerializableBinary(data));
425 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
426 sIn.Push(new TZSerializableFlag(pwd_flag));
428 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
430 pwd.getTag().size() * 8,
432 sIn.Push(new TZSerializableBinary(iv));
433 sIn.Push(new TZSerializableBinary(keyId));
434 sIn.Push(new TZSerializableBinary(aad));
435 sIn.Push(new TZSerializableFlag(tagSizeBits));
436 sIn.Push(new TZSerializableBinary(tag));
438 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
439 sIn.Serialize(inMemory);
442 sOut.Push(new TZSerializableBinary(data.size()));
443 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
446 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
447 TEEC_MEMREF_WHOLE, TEEC_NONE);
448 op.params[0].value.a = ALGO_AES_GCM;
449 op.params[1].memref.parent = inMemory.Get();
450 op.params[1].memref.offset = 0;
451 op.params[1].memref.size = inMemory.Get()->size;
452 op.params[2].memref.parent = outMemory.Get();
453 op.params[2].memref.offset = 0;
454 op.params[2].memref.size = outMemory.Get()->size;
456 Execute(CMD_DECRYPT, &op);
458 sOut.Deserialize(outMemory);
462 void TrustZoneContext::executeSign(tz_algo_type algo,
464 const RawBuffer &keyId,
466 const RawBuffer &message,
467 RawBuffer &signature)
469 // command ID = CMD_SIGN (from km_ta_defines.h)
470 if (keyId.size() != KM_KEY_ID_SIZE) {
471 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
472 + std::to_string(keyId.size()) + ")");
476 sIn.Push(new TZSerializableBinary(message));
477 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
478 sIn.Push(new TZSerializableFlag(pwd_flag));
480 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
482 pwd.getTag().size() * 8,
484 sIn.Push(new TZSerializableBinary(keyId));
485 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
486 sIn.Serialize(inMemory);
489 sOut.Push(new TZSerializableBinary(MAX_KEY_SIZE.at(algo), false));
490 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
493 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
494 TEEC_MEMREF_WHOLE, TEEC_NONE);
495 op.params[0].value.a = algo;
496 op.params[0].value.b = hash;
497 op.params[1].memref.parent = inMemory.Get();
498 op.params[1].memref.offset = 0;
499 op.params[1].memref.size = inMemory.Get()->size;
500 op.params[2].memref.parent = outMemory.Get();
501 op.params[2].memref.offset = 0;
502 op.params[2].memref.size = outMemory.Get()->size;
503 Execute(CMD_SIGN, &op);
505 sOut.Deserialize(outMemory);
506 sOut.Pull(signature);
509 int TrustZoneContext::executeVerify(tz_algo_type algo,
511 const RawBuffer &keyId,
513 const RawBuffer &message,
514 const RawBuffer &signature)
516 // command ID = CMD_VERIFY (from km_ta_defines.h)
517 if (keyId.size() != KM_KEY_ID_SIZE) {
518 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
519 + std::to_string(keyId.size()) + ")");
523 sIn.Push(new TZSerializableBinary(message));
524 sIn.Push(new TZSerializableBinary(signature));
525 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
526 sIn.Push(new TZSerializableFlag(pwd_flag));
528 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
530 pwd.getTag().size() * 8,
532 sIn.Push(new TZSerializableBinary(keyId));
533 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
534 sIn.Serialize(inMemory);
537 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
538 TEEC_NONE, TEEC_NONE);
539 op.params[0].value.a = algo;
540 op.params[0].value.b = hash;
541 op.params[1].memref.parent = inMemory.Get();
542 op.params[1].memref.offset = 0;
543 op.params[1].memref.size = inMemory.Get()->size;
544 Execute(CMD_VERIFY, &op);
546 int opRet = op.params[0].value.a;
549 return CKM_API_SUCCESS;
550 case KM_TA_ERROR_SIGNATURE:
551 LogWarning("Signature verification failed");
552 return CKM_API_ERROR_VERIFICATION_FAILED;
554 assert(false); // This condition should be checked inside Execute() function
555 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", opRet);
559 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
561 // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
562 if (keyId.size() != KM_KEY_ID_SIZE) {
563 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
567 sIn.Push(new TZSerializableBinary(keyId));
568 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
569 sIn.Serialize(inMemory);
572 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
573 TEEC_NONE, TEEC_NONE);
574 op.params[1].memref.parent = inMemory.Get();
575 op.params[1].memref.offset = 0;
576 op.params[1].memref.size = inMemory.Get()->size;
577 Execute(CMD_DESTROY_KEY, &op);
580 void TrustZoneContext::importData(
581 const uint32_t dataType,
582 const RawBuffer &data,
583 const Crypto::EncryptionParams &encData,
584 const RawBuffer &pwd,
586 const uint32_t keySizeBits,
587 const uint32_t pwdTagSizeBits,
589 const RawBuffer &hash)
591 // command ID = CMD_IMPORT_DATA
592 LogDebug("TrustZoneContext::importData data size = [" << data.size() << "]");
594 sIn.Push(new TZSerializableFlag(dataType));
595 sIn.Push(new TZSerializableBinary(data));
596 sIn.Push(new TZSerializableFlag(keySizeBits));
597 sIn.Push(new TZSerializableBinary(encData.iv));
598 sIn.Push(new TZSerializableBinary(encData.tag));
600 uint32_t pwd_flag = pwd.empty() ? 0 : 1;
601 sIn.Push(new TZSerializableFlag(pwd_flag));
603 sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
605 sIn.Push(new TZSerializableBinary(hash));
607 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
608 sIn.Serialize(inMemory);
613 sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
616 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
620 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
621 TEEC_MEMREF_WHOLE, TEEC_NONE);
624 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
625 TEEC_NONE, TEEC_NONE);
628 op.params[1].memref.parent = inMemory.Get();
629 op.params[1].memref.offset = 0;
630 op.params[1].memref.size = inMemory.Get()->size;
631 op.params[2].memref.parent = outMemory.Get();
632 op.params[2].memref.offset = 0;
633 op.params[2].memref.size = outMemory.Get()->size;
635 Execute(CMD_IMPORT_DATA, &op);
638 sOut.Deserialize(outMemory);
642 LogDebug("Imported object ID is (hex): " << rawToHexString(hash));
645 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
647 // command ID = CMD_GET_DATA_SIZE
648 LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
651 sIn.Push(new TZSerializableBinary(dataId));
653 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
654 sIn.Serialize(inMemory);
657 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
658 TEEC_NONE, TEEC_NONE);
660 op.params[1].memref.parent = inMemory.Get();
661 op.params[1].memref.offset = 0;
662 op.params[1].memref.size = inMemory.Get()->size;
663 Execute(CMD_GET_DATA_SIZE, &op);
664 dataSize = op.params[0].value.b;
667 void TrustZoneContext::getData(const RawBuffer &dataId,
671 // command ID = CMD_GET_DATA
672 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
675 sIn.Push(new TZSerializableBinary(dataId));
677 uint32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
678 sIn.Push(new TZSerializableFlag(pwd_flag));
681 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
683 Params::DEFAULT_AES_GCM_TAG_LEN_BITS,
687 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
688 sIn.Serialize(inMemory);
690 uint32_t data_size = 0;
691 GetDataSize(dataId, data_size);
693 LogDebug("GetData data_size = [" << data_size << "]");
696 sOut.Push(new TZSerializableBinary(data_size));
697 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
698 sOut.Serialize(outMemory);
701 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
702 TEEC_MEMREF_WHOLE, TEEC_NONE);
703 op.params[1].memref.parent = inMemory.Get();
704 op.params[1].memref.offset = 0;
705 op.params[1].memref.size = inMemory.Get()->size;
706 op.params[2].memref.parent = outMemory.Get();
707 op.params[2].memref.offset = 0;
708 op.params[2].memref.size = outMemory.Get()->size;
710 Execute(CMD_GET_DATA, &op);
712 sOut.Deserialize(outMemory);
717 void TrustZoneContext::destroyData(const RawBuffer &dataId)
719 // command ID = CMD_DESTROY_DATA
720 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
722 sIn.Push(new TZSerializableBinary(dataId));
724 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
725 sIn.Serialize(inMemory);
728 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
729 TEEC_NONE, TEEC_NONE);
731 op.params[1].memref.parent = inMemory.Get();
732 op.params[1].memref.offset = 0;
733 op.params[1].memref.size = inMemory.Get()->size;
734 Execute(CMD_DESTROY_DATA, &op);
737 void TrustZoneContext::Initialize()
743 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
745 result = TEEC_InitializeContext(nullptr, &m_Context);
746 if (result != TEEC_SUCCESS) {
747 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize TEE context: ", result);
749 m_ContextInitialized = true;
751 result = TEEC_OpenSession(&m_Context, &m_Session, &KEY_MANAGER_TA_UUID, 0, nullptr, &op, &retOrigin);
752 if (result != TEEC_SUCCESS) {
753 ThrowErr(Exc::Crypto::InternalError, "Failed to open session to Key Manager TA: ", result);
755 m_SessionInitialized = true;
758 void TrustZoneContext::Destroy()
760 if (m_SessionInitialized) {
761 TEEC_CloseSession(&m_Session);
762 m_SessionInitialized = false;
765 if (m_ContextInitialized) {
766 TEEC_FinalizeContext(&m_Context);
767 m_ContextInitialized = false;
771 void TrustZoneContext::Reload()
777 void TrustZoneContext::Execute(tz_command commandID, TEEC_Operation* op)
779 uint32_t retOrigin = 0;
780 LogDebug("Executing TZ operation " << commandID);
782 TEEC_Result result = TEEC_InvokeCommand(&m_Session, static_cast<unsigned int>(commandID), op, &retOrigin);
783 if (result != TEEC_SUCCESS) {
785 case TEEC_ERROR_TARGET_DEAD:
787 ThrowErr(Exc::Crypto::InternalError, "TA panicked while executing command ",
788 static_cast<unsigned int>(commandID));
789 case TEEC_ERROR_BAD_PARAMETERS:
790 ThrowErr(Exc::Crypto::InputParam, "Incorrect parameters provided to TA");
792 ThrowErr(Exc::Crypto::InternalError, "TA failed to invoke command ",
793 static_cast<unsigned int>(commandID), " with error: ", std::hex,
794 static_cast<unsigned int>(result), " with origin: ", std::hex,
799 int ta_ret = op->params[0].value.a;
802 case KM_TA_ERROR_SIGNATURE:
804 case KM_TA_ERROR_AUTH_FAILED:
805 // Authentication cipher failed - notify with proper exception
806 ThrowErr(Exc::AuthenticationFailed, "Crypto operation authentication failed");
808 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", ta_ret);
812 } // namespace Internals
814 } // namespace Crypto