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 } // anonymous namespace
83 TrustZoneContext::TrustZoneContext()
84 : m_ContextInitialized(false)
85 , m_SessionInitialized(false)
90 TrustZoneContext::~TrustZoneContext()
95 TrustZoneContext& TrustZoneContext::Instance()
97 static TrustZoneContext instance;
101 void TrustZoneContext::generateIV(RawBuffer& iv)
103 // command ID = CMD_GENERATE_IV
104 // IV generation is a simple call - no need to serialize data
105 // just provide the output buffer with size equal to iv.
106 uint32_t ivSize = Params::DEFAULT_AES_IV_LEN;
107 TrustZoneMemory ivMemory(m_Context, ivSize, TEEC_MEM_OUTPUT);
110 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
111 TEEC_NONE, TEEC_NONE);
112 op.params[1].memref.parent = ivMemory.Get();
113 op.params[1].memref.offset = 0;
114 op.params[1].memref.size = ivMemory.Get()->size;
115 Execute(CMD_GENERATE_IV, &op);
118 memcpy(iv.data(), ivMemory.Get()->buffer, ivMemory.Get()->size);
121 void TrustZoneContext::generateSKey(tz_algo_type algo,
122 uint32_t keySizeBits,
125 // command ID = CMD_GENERATE_KEY
127 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
129 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
132 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
133 TEEC_NONE, TEEC_NONE);
134 op.params[0].value.a = algo;
135 op.params[0].value.b = keySizeBits;
136 op.params[1].memref.parent = outMemory.Get();
137 op.params[1].memref.offset = 0;
138 op.params[1].memref.size = outMemory.Get()->size;
139 Execute(CMD_GENERATE_KEY, &op);
141 sOut.Deserialize(outMemory);
145 void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
146 const RawBuffer &pwd,
148 const uint32_t keySizeBits,
152 // command ID = CMD_GENERATE_KEY_PWD
154 sIn.Push(new TZSerializablePwdData(pwd, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
155 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
156 sIn.Serialize(inMemory);
159 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
160 sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
161 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
164 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
165 TEEC_MEMREF_WHOLE, TEEC_NONE);
166 op.params[0].value.a = algo;
167 op.params[0].value.b = keySizeBits;
168 op.params[1].memref.parent = inMemory.Get();
169 op.params[1].memref.offset = 0;
170 op.params[1].memref.size = inMemory.Get()->size;
171 op.params[2].memref.parent = outMemory.Get();
172 op.params[2].memref.offset = 0;
173 op.params[2].memref.size = outMemory.Get()->size;
174 Execute(CMD_GENERATE_KEY_PWD, &op);
176 sOut.Deserialize(outMemory);
181 void TrustZoneContext::GenerateAKey(tz_command commandId,
183 uint32_t keySizeBits,
184 const RawBuffer &pubPwd,
185 const RawBuffer &pubPwdIv,
186 const RawBuffer &privPwd,
187 const RawBuffer &privPwdIv,
189 RawBuffer &pubKeyTag,
190 RawBuffer &privKeyId,
191 RawBuffer &privKeyTag)
193 uint32_t pubTagSize = 0;
194 uint32_t privTagSize = 0;
196 uint32_t pubPwdExists = pubPwd.empty() ? 0 : 1;
197 sIn.Push(new TZSerializableFlag(pubPwdExists));
199 sIn.Push(new TZSerializablePwdData(pubPwd, pubPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
200 pubTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
202 uint32_t privPwdExists = privPwd.empty() ? 0 : 1;
203 sIn.Push(new TZSerializableFlag(privPwdExists));
205 sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
206 privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
209 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
210 sIn.Serialize(inMemory);
213 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
215 sOut.Push(new TZSerializableBinary(pubTagSize));
217 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
219 sOut.Push(new TZSerializableBinary(privTagSize));
222 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
225 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
226 TEEC_MEMREF_WHOLE, TEEC_NONE);
227 op.params[0].value.b = keySizeBits;
228 op.params[1].memref.parent = inMemory.Get();
229 op.params[1].memref.offset = 0;
230 op.params[1].memref.size = inMemory.Get()->size;
231 op.params[2].memref.parent = outMemory.Get();
232 op.params[2].memref.offset = 0;
233 op.params[2].memref.size = outMemory.Get()->size;
234 Execute(commandId, &op);
236 sOut.Deserialize(outMemory);
241 sOut.Pull(pubKeyTag);
244 sOut.Pull(privKeyId);
247 sOut.Pull(privKeyTag);
251 void TrustZoneContext::generateRSAKey(uint32_t keySizeBits,
252 const RawBuffer &pubPwd,
253 const RawBuffer &pubPwdIv,
254 const RawBuffer &privPwd,
255 const RawBuffer &privPwdIv,
257 RawBuffer &pubKeyTag,
258 RawBuffer &privKeyId,
259 RawBuffer &privKeyTag)
261 // command ID = CMD_GENERATE_RSA_KEYPAIR
264 GenerateAKey(CMD_GENERATE_RSA_KEYPAIR,
277 void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
278 const RawBuffer &prime,
279 const RawBuffer &subprime,
280 const RawBuffer &base,
281 const RawBuffer &pubPwd,
282 const RawBuffer &pubPwdIv,
283 const RawBuffer &privPwd,
284 const RawBuffer &privPwdIv,
286 RawBuffer &pubKeyTag,
287 RawBuffer &privKeyId,
288 RawBuffer &privKeyTag)
290 // command ID = CMD_GENERATE_DSA_KEYPAIR
292 sIn.Push(new TZSerializableBinary(prime));
293 sIn.Push(new TZSerializableBinary(subprime));
294 sIn.Push(new TZSerializableBinary(base));
296 GenerateAKey(CMD_GENERATE_DSA_KEYPAIR,
309 void TrustZoneContext::executeCrypt(tz_command cmd,
311 const RawBuffer &keyId,
314 const RawBuffer &data,
317 // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
318 if (keyId.size() != KM_KEY_ID_SIZE) {
319 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
320 + std::to_string(keyId.size()) + ")");
324 sIn.Push(new TZSerializableBinary(data));
325 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
326 sIn.Push(new TZSerializableFlag(pwd_flag));
328 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
330 pwd.getTag().size() * 8,
332 if (algo != ALGO_RSA)
333 sIn.Push(new TZSerializableBinary(iv));
334 sIn.Push(new TZSerializableBinary(keyId));
336 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
337 sIn.Serialize(inMemory);
339 // decrypt operation does not require padding
340 uint32_t outMemorySize = data.size();
341 if (cmd == CMD_ENCRYPT) {
342 if (algo == ALGO_RSA) {
343 // We don't know the key length
344 outMemorySize = MAX_KEY_SIZE.at(ALGO_RSA);
346 outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
351 sOut.Push(new TZSerializableBinary(outMemorySize, false));
352 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
355 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
356 TEEC_MEMREF_WHOLE, TEEC_NONE);
357 op.params[0].value.a = algo;
358 op.params[1].memref.parent = inMemory.Get();
359 op.params[1].memref.offset = 0;
360 op.params[1].memref.size = inMemory.Get()->size;
361 op.params[2].memref.parent = outMemory.Get();
362 op.params[2].memref.offset = 0;
363 op.params[2].memref.size = outMemory.Get()->size;
367 sOut.Deserialize(outMemory);
371 void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
375 const RawBuffer &aad,
376 const RawBuffer &data,
380 // command ID = CMD_ENCRYPT (from km_ta_defines.h)
381 if (keyId.size() != KM_KEY_ID_SIZE) {
382 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
386 sIn.Push(new TZSerializableBinary(data));
387 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
388 sIn.Push(new TZSerializableFlag(pwd_flag));
390 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
392 pwd.getTag().size() * 8,
394 sIn.Push(new TZSerializableBinary(iv));
395 sIn.Push(new TZSerializableBinary(keyId));
396 sIn.Push(new TZSerializableBinary(aad));
397 sIn.Push(new TZSerializableFlag(tagSizeBits));
399 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
400 sIn.Serialize(inMemory);
402 uint32_t outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
403 uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
406 sOut.Push(new TZSerializableBinary(outMemorySize, false));
407 sOut.Push(new TZSerializableBinary(tagSizeBytes));
408 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
411 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
412 TEEC_MEMREF_WHOLE, TEEC_NONE);
413 op.params[0].value.a = ALGO_AES_GCM;
414 op.params[1].memref.parent = inMemory.Get();
415 op.params[1].memref.offset = 0;
416 op.params[1].memref.size = inMemory.Get()->size;
417 op.params[2].memref.parent = outMemory.Get();
418 op.params[2].memref.offset = 0;
419 op.params[2].memref.size = outMemory.Get()->size;
421 Execute(CMD_ENCRYPT, &op);
423 sOut.Deserialize(outMemory);
428 void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
432 const RawBuffer &tag,
433 const RawBuffer &aad,
434 const RawBuffer &data,
437 // command ID = CMD_DECRYPT (from km_ta_defines.h)
438 if (keyId.size() != KM_KEY_ID_SIZE) {
439 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
443 sIn.Push(new TZSerializableBinary(data));
444 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
445 sIn.Push(new TZSerializableFlag(pwd_flag));
447 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
449 pwd.getTag().size() * 8,
451 sIn.Push(new TZSerializableBinary(iv));
452 sIn.Push(new TZSerializableBinary(keyId));
453 sIn.Push(new TZSerializableBinary(aad));
454 sIn.Push(new TZSerializableFlag(tagSizeBits));
455 sIn.Push(new TZSerializableBinary(tag));
457 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
458 sIn.Serialize(inMemory);
461 sOut.Push(new TZSerializableBinary(data.size()));
462 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
465 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
466 TEEC_MEMREF_WHOLE, TEEC_NONE);
467 op.params[0].value.a = ALGO_AES_GCM;
468 op.params[1].memref.parent = inMemory.Get();
469 op.params[1].memref.offset = 0;
470 op.params[1].memref.size = inMemory.Get()->size;
471 op.params[2].memref.parent = outMemory.Get();
472 op.params[2].memref.offset = 0;
473 op.params[2].memref.size = outMemory.Get()->size;
475 Execute(CMD_DECRYPT, &op);
477 sOut.Deserialize(outMemory);
481 void TrustZoneContext::executeSign(tz_algo_type algo,
483 const RawBuffer &keyId,
485 const RawBuffer &message,
486 RawBuffer &signature)
488 // command ID = CMD_SIGN (from km_ta_defines.h)
489 if (keyId.size() != KM_KEY_ID_SIZE) {
490 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
491 + std::to_string(keyId.size()) + ")");
495 sIn.Push(new TZSerializableBinary(message));
496 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
497 sIn.Push(new TZSerializableFlag(pwd_flag));
499 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
501 pwd.getTag().size() * 8,
503 sIn.Push(new TZSerializableBinary(keyId));
504 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
505 sIn.Serialize(inMemory);
508 sOut.Push(new TZSerializableBinary(MAX_KEY_SIZE.at(algo), false));
509 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
512 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
513 TEEC_MEMREF_WHOLE, TEEC_NONE);
514 op.params[0].value.a = algo;
515 op.params[0].value.b = hash;
516 op.params[1].memref.parent = inMemory.Get();
517 op.params[1].memref.offset = 0;
518 op.params[1].memref.size = inMemory.Get()->size;
519 op.params[2].memref.parent = outMemory.Get();
520 op.params[2].memref.offset = 0;
521 op.params[2].memref.size = outMemory.Get()->size;
522 Execute(CMD_SIGN, &op);
524 sOut.Deserialize(outMemory);
525 sOut.Pull(signature);
528 int TrustZoneContext::executeVerify(tz_algo_type algo,
530 const RawBuffer &keyId,
532 const RawBuffer &message,
533 const RawBuffer &signature)
535 // command ID = CMD_VERIFY (from km_ta_defines.h)
536 if (keyId.size() != KM_KEY_ID_SIZE) {
537 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
538 + std::to_string(keyId.size()) + ")");
542 sIn.Push(new TZSerializableBinary(message));
543 sIn.Push(new TZSerializableBinary(signature));
544 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
545 sIn.Push(new TZSerializableFlag(pwd_flag));
547 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
549 pwd.getTag().size() * 8,
551 sIn.Push(new TZSerializableBinary(keyId));
552 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
553 sIn.Serialize(inMemory);
556 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
557 TEEC_NONE, TEEC_NONE);
558 op.params[0].value.a = algo;
559 op.params[0].value.b = hash;
560 op.params[1].memref.parent = inMemory.Get();
561 op.params[1].memref.offset = 0;
562 op.params[1].memref.size = inMemory.Get()->size;
563 Execute(CMD_VERIFY, &op);
565 int opRet = op.params[0].value.a;
568 return CKM_API_SUCCESS;
569 case KM_TA_ERROR_SIGNATURE:
570 LogWarning("Signature verification failed");
571 return CKM_API_ERROR_VERIFICATION_FAILED;
573 assert(false); // This condition should be checked inside Execute() function
574 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", opRet);
578 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
580 // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
581 if (keyId.size() != KM_KEY_ID_SIZE) {
582 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
586 sIn.Push(new TZSerializableBinary(keyId));
587 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
588 sIn.Serialize(inMemory);
591 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
592 TEEC_NONE, TEEC_NONE);
593 op.params[1].memref.parent = inMemory.Get();
594 op.params[1].memref.offset = 0;
595 op.params[1].memref.size = inMemory.Get()->size;
596 Execute(CMD_DESTROY_KEY, &op);
599 void TrustZoneContext::importData(
600 const uint32_t dataType,
601 const RawBuffer &data,
602 const Crypto::EncryptionParams &encData,
603 const RawBuffer &pwd,
605 const uint32_t keySizeBits,
606 const uint32_t pwdTagSizeBits,
610 // command ID = CMD_IMPORT_DATA
612 sIn.Push(new TZSerializableFlag(dataType));
613 sIn.Push(new TZSerializableBinary(data));
614 sIn.Push(new TZSerializableFlag(keySizeBits));
615 sIn.Push(new TZSerializableBinary(encData.iv));
616 sIn.Push(new TZSerializableBinary(encData.tag));
618 uint32_t pwd_flag = pwd.empty() ? 0 : 1;
619 sIn.Push(new TZSerializableFlag(pwd_flag));
621 sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
623 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
624 sIn.Serialize(inMemory);
628 sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE));
630 sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
633 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
636 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
637 TEEC_MEMREF_WHOLE, TEEC_NONE);
638 op.params[1].memref.parent = inMemory.Get();
639 op.params[1].memref.offset = 0;
640 op.params[1].memref.size = inMemory.Get()->size;
641 op.params[2].memref.parent = outMemory.Get();
642 op.params[2].memref.offset = 0;
643 op.params[2].memref.size = outMemory.Get()->size;
645 Execute(CMD_IMPORT_DATA, &op);
647 sOut.Deserialize(outMemory);
653 LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
656 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
658 // command ID = CMD_GET_DATA_SIZE
659 LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
662 sIn.Push(new TZSerializableBinary(dataId));
664 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
665 sIn.Serialize(inMemory);
668 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
669 TEEC_NONE, TEEC_NONE);
671 op.params[1].memref.parent = inMemory.Get();
672 op.params[1].memref.offset = 0;
673 op.params[1].memref.size = inMemory.Get()->size;
674 Execute(CMD_GET_DATA_SIZE, &op);
675 dataSize = op.params[0].value.b;
678 void TrustZoneContext::getData(const RawBuffer &dataId,
682 // command ID = CMD_GET_DATA
683 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
686 sIn.Push(new TZSerializableBinary(dataId));
688 uint32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
689 sIn.Push(new TZSerializableFlag(pwd_flag));
692 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
694 Params::DEFAULT_AES_GCM_TAG_LEN_BITS,
698 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
699 sIn.Serialize(inMemory);
701 uint32_t data_size = 0;
702 GetDataSize(dataId, data_size);
705 sOut.Push(new TZSerializableBinary(data_size));
706 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
707 sOut.Serialize(outMemory);
710 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
711 TEEC_MEMREF_WHOLE, TEEC_NONE);
712 op.params[1].memref.parent = inMemory.Get();
713 op.params[1].memref.offset = 0;
714 op.params[1].memref.size = inMemory.Get()->size;
715 op.params[2].memref.parent = outMemory.Get();
716 op.params[2].memref.offset = 0;
717 op.params[2].memref.size = outMemory.Get()->size;
719 Execute(CMD_GET_DATA, &op);
721 sOut.Deserialize(outMemory);
726 void TrustZoneContext::destroyData(const RawBuffer &dataId)
728 // command ID = CMD_DESTROY_DATA
729 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
731 sIn.Push(new TZSerializableBinary(dataId));
733 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
734 sIn.Serialize(inMemory);
737 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
738 TEEC_NONE, TEEC_NONE);
740 op.params[1].memref.parent = inMemory.Get();
741 op.params[1].memref.offset = 0;
742 op.params[1].memref.size = inMemory.Get()->size;
743 Execute(CMD_DESTROY_DATA, &op);
746 void TrustZoneContext::Initialize()
752 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
754 result = TEEC_InitializeContext(nullptr, &m_Context);
755 if (result != TEEC_SUCCESS) {
756 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize TEE context: ", result);
758 m_ContextInitialized = true;
760 result = TEEC_OpenSession(&m_Context, &m_Session, &KEY_MANAGER_TA_UUID, 0, nullptr, &op, &retOrigin);
761 if (result != TEEC_SUCCESS) {
762 ThrowErr(Exc::Crypto::InternalError, "Failed to open session to Key Manager TA: ", result);
764 m_SessionInitialized = true;
767 void TrustZoneContext::Destroy()
769 if (m_SessionInitialized) {
770 TEEC_CloseSession(&m_Session);
771 m_SessionInitialized = false;
774 if (m_ContextInitialized) {
775 TEEC_FinalizeContext(&m_Context);
776 m_ContextInitialized = false;
780 void TrustZoneContext::Reload()
786 void TrustZoneContext::Execute(tz_command commandID, TEEC_Operation* op)
788 uint32_t retOrigin = 0;
789 LogDebug("Executing TZ operation " << commandID);
791 TEEC_Result result = TEEC_InvokeCommand(&m_Session, static_cast<unsigned int>(commandID), op, &retOrigin);
792 if (result != TEEC_SUCCESS) {
794 case TEEC_ERROR_TARGET_DEAD:
796 ThrowErr(Exc::Crypto::InternalError, "TA panicked while executing command ",
797 static_cast<unsigned int>(commandID));
798 case TEEC_ERROR_BAD_PARAMETERS:
799 ThrowErr(Exc::Crypto::InputParam, "Incorrect parameters provided to TA");
801 ThrowErr(Exc::Crypto::InternalError, "TA failed to invoke command ",
802 static_cast<unsigned int>(commandID), " with error: ", std::hex,
803 static_cast<unsigned int>(result), " with origin: ", std::hex,
808 int ta_ret = op->params[0].value.a;
811 case KM_TA_ERROR_SIGNATURE:
813 case KM_TA_ERROR_AUTH_FAILED:
814 // Authentication cipher failed - notify with proper exception
815 ThrowErr(Exc::AuthenticationFailed, "Crypto operation authentication failed");
817 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", ta_ret);
821 } // namespace Internals
823 } // namespace Crypto