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>
35 #include <unordered_map>
44 // A little bit of extra memory to add to output buffers.
46 // We need this extra memory to output for padding purposes - after encryption
47 // we can resize the result memory back to its proper size according to
48 // whatever TA will return us.
49 const uint32_t CIPHER_EXTRA_PADDING_SIZE = 16;
51 // Identifier of our TA
52 const TEEC_UUID KEY_MANAGER_TA_UUID = KM_TA_UUID;
54 //raw to hex string conversion to print persistent storage data ID
55 static std::string rawToHexString(const RawBuffer &raw)
57 return hexDump<std::string>(raw);
61 * Maximum size for given key type in bytes according to key-manager-ta implementation.
62 * Note that they are greater than TEE Internal Core API v1.1.2.50 (Table 5-9) values.
64 const std::unordered_map<tz_algo_type, size_t> MAX_KEY_SIZE = {
65 { ALGO_RSA, 4096 / 8 },
66 { ALGO_RSA_SV, 4096 / 8 },
67 { ALGO_DSA_SV, 4096 / 8 }
70 } // anonymous namespace
72 TrustZoneContext::TrustZoneContext()
73 : m_ContextInitialized(false)
74 , m_SessionInitialized(false)
79 TrustZoneContext::~TrustZoneContext()
84 TrustZoneContext& TrustZoneContext::Instance()
86 static TrustZoneContext instance;
90 void TrustZoneContext::generateIV(RawBuffer& iv)
92 // command ID = CMD_GENERATE_IV
93 // IV generation is a simple call - no need to serialize data
94 // just provide the output buffer with size equal to iv.
95 uint32_t ivSize = Params::DEFAULT_AES_IV_LEN;
96 TrustZoneMemory ivMemory(m_Context, ivSize, TEEC_MEM_OUTPUT);
99 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
100 TEEC_NONE, TEEC_NONE);
101 op.params[1].memref.parent = ivMemory.Get();
102 op.params[1].memref.offset = 0;
103 op.params[1].memref.size = ivMemory.Get()->size;
104 Execute(CMD_GENERATE_IV, &op);
107 memcpy(iv.data(), ivMemory.Get()->buffer, ivMemory.Get()->size);
110 void TrustZoneContext::generateSKey(tz_algo_type algo,
111 uint32_t keySizeBits,
114 // command ID = CMD_GENERATE_KEY
116 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
118 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
121 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
122 TEEC_NONE, TEEC_NONE);
123 op.params[0].value.a = algo;
124 op.params[0].value.b = keySizeBits;
125 op.params[1].memref.parent = outMemory.Get();
126 op.params[1].memref.offset = 0;
127 op.params[1].memref.size = outMemory.Get()->size;
128 Execute(CMD_GENERATE_KEY, &op);
130 sOut.Deserialize(outMemory);
134 void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
135 const RawBuffer &pwd,
137 const uint32_t keySizeBits,
141 // command ID = CMD_GENERATE_KEY_PWD
143 sIn.Push(new TZSerializablePwdData(pwd, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
144 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
145 sIn.Serialize(inMemory);
148 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
149 sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
150 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
153 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
154 TEEC_MEMREF_WHOLE, TEEC_NONE);
155 op.params[0].value.a = algo;
156 op.params[0].value.b = keySizeBits;
157 op.params[1].memref.parent = inMemory.Get();
158 op.params[1].memref.offset = 0;
159 op.params[1].memref.size = inMemory.Get()->size;
160 op.params[2].memref.parent = outMemory.Get();
161 op.params[2].memref.offset = 0;
162 op.params[2].memref.size = outMemory.Get()->size;
163 Execute(CMD_GENERATE_KEY_PWD, &op);
165 sOut.Deserialize(outMemory);
170 void TrustZoneContext::GenerateAKey(tz_command commandId,
172 uint32_t keySizeBits,
173 const RawBuffer &pubPwd,
174 const RawBuffer &pubPwdIv,
175 const RawBuffer &privPwd,
176 const RawBuffer &privPwdIv,
178 RawBuffer &pubKeyTag,
179 RawBuffer &privKeyId,
180 RawBuffer &privKeyTag)
182 uint32_t pubTagSize = 0;
183 uint32_t privTagSize = 0;
185 uint32_t pubPwdExists = pubPwd.empty() ? 0 : 1;
186 sIn.Push(new TZSerializableFlag(pubPwdExists));
188 sIn.Push(new TZSerializablePwdData(pubPwd, pubPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
189 pubTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
191 uint32_t privPwdExists = privPwd.empty() ? 0 : 1;
192 sIn.Push(new TZSerializableFlag(privPwdExists));
194 sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
195 privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
198 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
199 sIn.Serialize(inMemory);
202 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
204 sOut.Push(new TZSerializableBinary(pubTagSize));
206 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
208 sOut.Push(new TZSerializableBinary(privTagSize));
211 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
214 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
215 TEEC_MEMREF_WHOLE, TEEC_NONE);
216 op.params[0].value.b = keySizeBits;
217 op.params[1].memref.parent = inMemory.Get();
218 op.params[1].memref.offset = 0;
219 op.params[1].memref.size = inMemory.Get()->size;
220 op.params[2].memref.parent = outMemory.Get();
221 op.params[2].memref.offset = 0;
222 op.params[2].memref.size = outMemory.Get()->size;
223 Execute(commandId, &op);
225 sOut.Deserialize(outMemory);
230 sOut.Pull(pubKeyTag);
233 sOut.Pull(privKeyId);
236 sOut.Pull(privKeyTag);
240 void TrustZoneContext::generateRSAKey(uint32_t keySizeBits,
241 const RawBuffer &pubPwd,
242 const RawBuffer &pubPwdIv,
243 const RawBuffer &privPwd,
244 const RawBuffer &privPwdIv,
246 RawBuffer &pubKeyTag,
247 RawBuffer &privKeyId,
248 RawBuffer &privKeyTag)
250 // command ID = CMD_GENERATE_RSA_KEYPAIR
253 GenerateAKey(CMD_GENERATE_RSA_KEYPAIR,
266 void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
267 const RawBuffer &prime,
268 const RawBuffer &subprime,
269 const RawBuffer &base,
270 const RawBuffer &pubPwd,
271 const RawBuffer &pubPwdIv,
272 const RawBuffer &privPwd,
273 const RawBuffer &privPwdIv,
275 RawBuffer &pubKeyTag,
276 RawBuffer &privKeyId,
277 RawBuffer &privKeyTag)
279 // command ID = CMD_GENERATE_DSA_KEYPAIR
281 sIn.Push(new TZSerializableBinary(prime));
282 sIn.Push(new TZSerializableBinary(subprime));
283 sIn.Push(new TZSerializableBinary(base));
285 GenerateAKey(CMD_GENERATE_DSA_KEYPAIR,
298 void TrustZoneContext::executeCrypt(tz_command cmd,
300 const RawBuffer &keyId,
303 const RawBuffer &data,
306 // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
307 if (keyId.size() != KM_KEY_ID_SIZE) {
308 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
309 + std::to_string(keyId.size()) + ")");
313 sIn.Push(new TZSerializableBinary(data));
314 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
315 sIn.Push(new TZSerializableFlag(pwd_flag));
317 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
319 pwd.getTag().size() * 8,
321 if (algo != ALGO_RSA)
322 sIn.Push(new TZSerializableBinary(iv));
323 sIn.Push(new TZSerializableBinary(keyId));
325 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
326 sIn.Serialize(inMemory);
328 // decrypt operation does not require padding
329 uint32_t outMemorySize = data.size();
330 if (cmd == CMD_ENCRYPT) {
331 if (algo == ALGO_RSA) {
332 // We don't know the key length
333 outMemorySize = MAX_KEY_SIZE.at(ALGO_RSA);
335 outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
340 sOut.Push(new TZSerializableBinary(outMemorySize, false));
341 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
344 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
345 TEEC_MEMREF_WHOLE, TEEC_NONE);
346 op.params[0].value.a = algo;
347 op.params[1].memref.parent = inMemory.Get();
348 op.params[1].memref.offset = 0;
349 op.params[1].memref.size = inMemory.Get()->size;
350 op.params[2].memref.parent = outMemory.Get();
351 op.params[2].memref.offset = 0;
352 op.params[2].memref.size = outMemory.Get()->size;
356 sOut.Deserialize(outMemory);
360 void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
364 const RawBuffer &aad,
365 const RawBuffer &data,
369 // command ID = CMD_ENCRYPT (from km_ta_defines.h)
370 if (keyId.size() != KM_KEY_ID_SIZE) {
371 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
375 sIn.Push(new TZSerializableBinary(data));
376 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
377 sIn.Push(new TZSerializableFlag(pwd_flag));
379 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
381 pwd.getTag().size() * 8,
383 sIn.Push(new TZSerializableBinary(iv));
384 sIn.Push(new TZSerializableBinary(keyId));
385 sIn.Push(new TZSerializableBinary(aad));
386 sIn.Push(new TZSerializableFlag(tagSizeBits));
388 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
389 sIn.Serialize(inMemory);
391 uint32_t outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
392 uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
395 sOut.Push(new TZSerializableBinary(outMemorySize, false));
396 sOut.Push(new TZSerializableBinary(tagSizeBytes));
397 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
400 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
401 TEEC_MEMREF_WHOLE, TEEC_NONE);
402 op.params[0].value.a = ALGO_AES_GCM;
403 op.params[1].memref.parent = inMemory.Get();
404 op.params[1].memref.offset = 0;
405 op.params[1].memref.size = inMemory.Get()->size;
406 op.params[2].memref.parent = outMemory.Get();
407 op.params[2].memref.offset = 0;
408 op.params[2].memref.size = outMemory.Get()->size;
410 Execute(CMD_ENCRYPT, &op);
412 sOut.Deserialize(outMemory);
417 void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
421 const RawBuffer &tag,
422 const RawBuffer &aad,
423 const RawBuffer &data,
426 // command ID = CMD_DECRYPT (from km_ta_defines.h)
427 if (keyId.size() != KM_KEY_ID_SIZE) {
428 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
432 sIn.Push(new TZSerializableBinary(data));
433 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
434 sIn.Push(new TZSerializableFlag(pwd_flag));
436 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
438 pwd.getTag().size() * 8,
440 sIn.Push(new TZSerializableBinary(iv));
441 sIn.Push(new TZSerializableBinary(keyId));
442 sIn.Push(new TZSerializableBinary(aad));
443 sIn.Push(new TZSerializableFlag(tagSizeBits));
444 sIn.Push(new TZSerializableBinary(tag));
446 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
447 sIn.Serialize(inMemory);
450 sOut.Push(new TZSerializableBinary(data.size()));
451 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
454 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
455 TEEC_MEMREF_WHOLE, TEEC_NONE);
456 op.params[0].value.a = ALGO_AES_GCM;
457 op.params[1].memref.parent = inMemory.Get();
458 op.params[1].memref.offset = 0;
459 op.params[1].memref.size = inMemory.Get()->size;
460 op.params[2].memref.parent = outMemory.Get();
461 op.params[2].memref.offset = 0;
462 op.params[2].memref.size = outMemory.Get()->size;
464 Execute(CMD_DECRYPT, &op);
466 sOut.Deserialize(outMemory);
470 void TrustZoneContext::executeSign(tz_algo_type algo,
472 const RawBuffer &keyId,
474 const RawBuffer &message,
475 RawBuffer &signature)
477 // command ID = CMD_SIGN (from km_ta_defines.h)
478 if (keyId.size() != KM_KEY_ID_SIZE) {
479 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
480 + std::to_string(keyId.size()) + ")");
484 sIn.Push(new TZSerializableBinary(message));
485 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
486 sIn.Push(new TZSerializableFlag(pwd_flag));
488 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
490 pwd.getTag().size() * 8,
492 sIn.Push(new TZSerializableBinary(keyId));
493 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
494 sIn.Serialize(inMemory);
497 sOut.Push(new TZSerializableBinary(MAX_KEY_SIZE.at(algo), false));
498 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
501 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
502 TEEC_MEMREF_WHOLE, TEEC_NONE);
503 op.params[0].value.a = algo;
504 op.params[0].value.b = hash;
505 op.params[1].memref.parent = inMemory.Get();
506 op.params[1].memref.offset = 0;
507 op.params[1].memref.size = inMemory.Get()->size;
508 op.params[2].memref.parent = outMemory.Get();
509 op.params[2].memref.offset = 0;
510 op.params[2].memref.size = outMemory.Get()->size;
511 Execute(CMD_SIGN, &op);
513 sOut.Deserialize(outMemory);
514 sOut.Pull(signature);
517 int TrustZoneContext::executeVerify(tz_algo_type algo,
519 const RawBuffer &keyId,
521 const RawBuffer &message,
522 const RawBuffer &signature)
524 // command ID = CMD_VERIFY (from km_ta_defines.h)
525 if (keyId.size() != KM_KEY_ID_SIZE) {
526 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
527 + std::to_string(keyId.size()) + ")");
531 sIn.Push(new TZSerializableBinary(message));
532 sIn.Push(new TZSerializableBinary(signature));
533 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
534 sIn.Push(new TZSerializableFlag(pwd_flag));
536 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
538 pwd.getTag().size() * 8,
540 sIn.Push(new TZSerializableBinary(keyId));
541 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
542 sIn.Serialize(inMemory);
545 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
546 TEEC_NONE, TEEC_NONE);
547 op.params[0].value.a = algo;
548 op.params[0].value.b = hash;
549 op.params[1].memref.parent = inMemory.Get();
550 op.params[1].memref.offset = 0;
551 op.params[1].memref.size = inMemory.Get()->size;
552 Execute(CMD_VERIFY, &op);
554 int opRet = op.params[0].value.a;
557 return CKM_API_SUCCESS;
558 case KM_TA_ERROR_SIGNATURE:
559 LogWarning("Signature verification failed");
560 return CKM_API_ERROR_VERIFICATION_FAILED;
562 assert(false); // This condition should be checked inside Execute() function
563 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", opRet);
567 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
569 // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
570 if (keyId.size() != KM_KEY_ID_SIZE) {
571 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
575 sIn.Push(new TZSerializableBinary(keyId));
576 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
577 sIn.Serialize(inMemory);
580 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
581 TEEC_NONE, TEEC_NONE);
582 op.params[1].memref.parent = inMemory.Get();
583 op.params[1].memref.offset = 0;
584 op.params[1].memref.size = inMemory.Get()->size;
585 Execute(CMD_DESTROY_KEY, &op);
588 void TrustZoneContext::importData(
589 const uint32_t dataType,
590 const RawBuffer &data,
591 const Crypto::EncryptionParams &encData,
592 const RawBuffer &pwd,
594 const uint32_t keySizeBits,
595 const uint32_t pwdTagSizeBits,
599 // command ID = CMD_IMPORT_DATA
601 sIn.Push(new TZSerializableFlag(dataType));
602 sIn.Push(new TZSerializableBinary(data));
603 sIn.Push(new TZSerializableFlag(keySizeBits));
604 sIn.Push(new TZSerializableBinary(encData.iv));
605 sIn.Push(new TZSerializableBinary(encData.tag));
607 uint32_t pwd_flag = pwd.empty() ? 0 : 1;
608 sIn.Push(new TZSerializableFlag(pwd_flag));
610 sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
612 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
613 sIn.Serialize(inMemory);
617 sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE));
619 sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
622 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
625 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
626 TEEC_MEMREF_WHOLE, TEEC_NONE);
627 op.params[1].memref.parent = inMemory.Get();
628 op.params[1].memref.offset = 0;
629 op.params[1].memref.size = inMemory.Get()->size;
630 op.params[2].memref.parent = outMemory.Get();
631 op.params[2].memref.offset = 0;
632 op.params[2].memref.size = outMemory.Get()->size;
634 Execute(CMD_IMPORT_DATA, &op);
636 sOut.Deserialize(outMemory);
642 LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
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);
694 sOut.Push(new TZSerializableBinary(data_size));
695 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
696 sOut.Serialize(outMemory);
699 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
700 TEEC_MEMREF_WHOLE, TEEC_NONE);
701 op.params[1].memref.parent = inMemory.Get();
702 op.params[1].memref.offset = 0;
703 op.params[1].memref.size = inMemory.Get()->size;
704 op.params[2].memref.parent = outMemory.Get();
705 op.params[2].memref.offset = 0;
706 op.params[2].memref.size = outMemory.Get()->size;
708 Execute(CMD_GET_DATA, &op);
710 sOut.Deserialize(outMemory);
715 void TrustZoneContext::destroyData(const RawBuffer &dataId)
717 // command ID = CMD_DESTROY_DATA
718 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
720 sIn.Push(new TZSerializableBinary(dataId));
722 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
723 sIn.Serialize(inMemory);
726 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
727 TEEC_NONE, TEEC_NONE);
729 op.params[1].memref.parent = inMemory.Get();
730 op.params[1].memref.offset = 0;
731 op.params[1].memref.size = inMemory.Get()->size;
732 Execute(CMD_DESTROY_DATA, &op);
735 void TrustZoneContext::Initialize()
741 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
743 result = TEEC_InitializeContext(nullptr, &m_Context);
744 if (result != TEEC_SUCCESS) {
745 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize TEE context: ", result);
747 m_ContextInitialized = true;
749 result = TEEC_OpenSession(&m_Context, &m_Session, &KEY_MANAGER_TA_UUID, 0, nullptr, &op, &retOrigin);
750 if (result != TEEC_SUCCESS) {
751 ThrowErr(Exc::Crypto::InternalError, "Failed to open session to Key Manager TA: ", result);
753 m_SessionInitialized = true;
756 void TrustZoneContext::Destroy()
758 if (m_SessionInitialized) {
759 TEEC_CloseSession(&m_Session);
760 m_SessionInitialized = false;
763 if (m_ContextInitialized) {
764 TEEC_FinalizeContext(&m_Context);
765 m_ContextInitialized = false;
769 void TrustZoneContext::Reload()
775 void TrustZoneContext::Execute(tz_command commandID, TEEC_Operation* op)
777 uint32_t retOrigin = 0;
778 LogDebug("Executing TZ operation " << commandID);
780 TEEC_Result result = TEEC_InvokeCommand(&m_Session, static_cast<unsigned int>(commandID), op, &retOrigin);
781 if (result != TEEC_SUCCESS) {
783 case TEEC_ERROR_TARGET_DEAD:
785 ThrowErr(Exc::Crypto::InternalError, "TA panicked while executing command ",
786 static_cast<unsigned int>(commandID));
787 case TEEC_ERROR_BAD_PARAMETERS:
788 ThrowErr(Exc::Crypto::InputParam, "Incorrect parameters provided to TA");
790 ThrowErr(Exc::Crypto::InternalError, "TA failed to invoke command ",
791 static_cast<unsigned int>(commandID), " with error: ", std::hex,
792 static_cast<unsigned int>(result), " with origin: ", std::hex,
797 int ta_ret = op->params[0].value.a;
800 case KM_TA_ERROR_SIGNATURE:
802 case KM_TA_ERROR_AUTH_FAILED:
803 // Authentication cipher failed - notify with proper exception
804 ThrowErr(Exc::AuthenticationFailed, "Crypto operation authentication failed");
806 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", ta_ret);
810 } // namespace Internals
812 } // namespace Crypto