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);
180 if (keyId.size() != KM_KEY_ID_SIZE) {
181 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key ID");
184 if (pwdTag.size() != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
185 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag");
189 void TrustZoneContext::GenerateAKey(tz_command commandId,
191 uint32_t keySizeBits,
192 const RawBuffer &pubPwd,
193 const RawBuffer &pubPwdIv,
194 const RawBuffer &privPwd,
195 const RawBuffer &privPwdIv,
197 RawBuffer &pubKeyTag,
198 RawBuffer &privKeyId,
199 RawBuffer &privKeyTag)
201 uint32_t pubTagSize = 0;
202 uint32_t privTagSize = 0;
204 uint32_t pubPwdExists = pubPwd.empty() ? 0 : 1;
205 sIn.Push(new TZSerializableFlag(pubPwdExists));
207 sIn.Push(new TZSerializablePwdData(pubPwd, pubPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
208 pubTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
210 uint32_t privPwdExists = privPwd.empty() ? 0 : 1;
211 sIn.Push(new TZSerializableFlag(privPwdExists));
213 sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
214 privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
217 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
218 sIn.Serialize(inMemory);
221 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
222 sOut.Push(new TZSerializableBinary(pubTagSize));
223 sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
224 sOut.Push(new TZSerializableBinary(privTagSize));
226 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
229 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
230 TEEC_MEMREF_WHOLE, TEEC_NONE);
231 op.params[0].value.b = keySizeBits;
232 op.params[1].memref.parent = inMemory.Get();
233 op.params[1].memref.offset = 0;
234 op.params[1].memref.size = inMemory.Get()->size;
235 op.params[2].memref.parent = outMemory.Get();
236 op.params[2].memref.offset = 0;
237 op.params[2].memref.size = outMemory.Get()->size;
238 Execute(commandId, &op);
240 sOut.Deserialize(outMemory);
243 if (pubKeyId.size() != KM_KEY_ID_SIZE) {
244 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize public key ID");
248 sOut.Pull(pubKeyTag);
251 sOut.Pull(privKeyId);
252 if (privKeyId.size() != KM_KEY_ID_SIZE) {
253 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize private key ID");
257 sOut.Pull(privKeyTag);
261 void TrustZoneContext::generateRSAKey(uint32_t keySizeBits,
262 const RawBuffer &pubPwd,
263 const RawBuffer &pubPwdIv,
264 const RawBuffer &privPwd,
265 const RawBuffer &privPwdIv,
267 RawBuffer &pubKeyTag,
268 RawBuffer &privKeyId,
269 RawBuffer &privKeyTag)
271 // command ID = CMD_GENERATE_RSA_KEYPAIR
274 GenerateAKey(CMD_GENERATE_RSA_KEYPAIR,
287 void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
288 const RawBuffer &prime,
289 const RawBuffer &subprime,
290 const RawBuffer &base,
291 const RawBuffer &pubPwd,
292 const RawBuffer &pubPwdIv,
293 const RawBuffer &privPwd,
294 const RawBuffer &privPwdIv,
296 RawBuffer &pubKeyTag,
297 RawBuffer &privKeyId,
298 RawBuffer &privKeyTag)
300 // command ID = CMD_GENERATE_DSA_KEYPAIR
302 sIn.Push(new TZSerializableBinary(prime));
303 sIn.Push(new TZSerializableBinary(subprime));
304 sIn.Push(new TZSerializableBinary(base));
306 GenerateAKey(CMD_GENERATE_DSA_KEYPAIR,
319 void TrustZoneContext::executeCrypt(tz_command cmd,
321 const RawBuffer &keyId,
324 const RawBuffer &data,
327 // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
328 if (keyId.size() != KM_KEY_ID_SIZE) {
329 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
330 + std::to_string(keyId.size()) + ")");
334 sIn.Push(new TZSerializableBinary(data));
335 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
336 sIn.Push(new TZSerializableFlag(pwd_flag));
338 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
340 pwd.getTag().size() * 8,
342 if (algo != ALGO_RSA)
343 sIn.Push(new TZSerializableBinary(iv));
344 sIn.Push(new TZSerializableBinary(keyId));
346 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
347 sIn.Serialize(inMemory);
349 // decrypt operation does not require padding
350 uint32_t outMemorySize = data.size();
351 if (cmd == CMD_ENCRYPT) {
352 if (algo == ALGO_RSA) {
353 // We don't know the key length
354 outMemorySize = MAX_KEY_SIZE.at(ALGO_RSA);
356 outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
361 sOut.Push(new TZSerializableBinary(outMemorySize));
362 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
365 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
366 TEEC_MEMREF_WHOLE, TEEC_NONE);
367 op.params[0].value.a = algo;
368 op.params[1].memref.parent = inMemory.Get();
369 op.params[1].memref.offset = 0;
370 op.params[1].memref.size = inMemory.Get()->size;
371 op.params[2].memref.parent = outMemory.Get();
372 op.params[2].memref.offset = 0;
373 op.params[2].memref.size = outMemory.Get()->size;
377 sOut.Deserialize(outMemory);
381 void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
385 const RawBuffer &aad,
386 const RawBuffer &data,
390 // command ID = CMD_ENCRYPT (from km_ta_defines.h)
391 if (keyId.size() != KM_KEY_ID_SIZE) {
392 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
396 sIn.Push(new TZSerializableBinary(data));
397 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
398 sIn.Push(new TZSerializableFlag(pwd_flag));
400 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
402 pwd.getTag().size() * 8,
404 sIn.Push(new TZSerializableBinary(iv));
405 sIn.Push(new TZSerializableBinary(keyId));
406 sIn.Push(new TZSerializableBinary(aad));
407 sIn.Push(new TZSerializableFlag(tagSizeBits));
409 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
410 sIn.Serialize(inMemory);
412 uint32_t outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
413 uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
416 sOut.Push(new TZSerializableBinary(outMemorySize));
417 sOut.Push(new TZSerializableBinary(tagSizeBytes));
418 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
421 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
422 TEEC_MEMREF_WHOLE, TEEC_NONE);
423 op.params[0].value.a = ALGO_AES_GCM;
424 op.params[1].memref.parent = inMemory.Get();
425 op.params[1].memref.offset = 0;
426 op.params[1].memref.size = inMemory.Get()->size;
427 op.params[2].memref.parent = outMemory.Get();
428 op.params[2].memref.offset = 0;
429 op.params[2].memref.size = outMemory.Get()->size;
431 Execute(CMD_ENCRYPT, &op);
433 sOut.Deserialize(outMemory);
438 void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
442 const RawBuffer &tag,
443 const RawBuffer &aad,
444 const RawBuffer &data,
447 // command ID = CMD_DECRYPT (from km_ta_defines.h)
448 if (keyId.size() != KM_KEY_ID_SIZE) {
449 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
453 sIn.Push(new TZSerializableBinary(data));
454 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
455 sIn.Push(new TZSerializableFlag(pwd_flag));
457 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
459 pwd.getTag().size() * 8,
461 sIn.Push(new TZSerializableBinary(iv));
462 sIn.Push(new TZSerializableBinary(keyId));
463 sIn.Push(new TZSerializableBinary(aad));
464 sIn.Push(new TZSerializableFlag(tagSizeBits));
465 sIn.Push(new TZSerializableBinary(tag));
467 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
468 sIn.Serialize(inMemory);
471 sOut.Push(new TZSerializableBinary(data.size()));
472 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
475 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
476 TEEC_MEMREF_WHOLE, TEEC_NONE);
477 op.params[0].value.a = ALGO_AES_GCM;
478 op.params[1].memref.parent = inMemory.Get();
479 op.params[1].memref.offset = 0;
480 op.params[1].memref.size = inMemory.Get()->size;
481 op.params[2].memref.parent = outMemory.Get();
482 op.params[2].memref.offset = 0;
483 op.params[2].memref.size = outMemory.Get()->size;
485 Execute(CMD_DECRYPT, &op);
487 sOut.Deserialize(outMemory);
491 void TrustZoneContext::executeSign(tz_algo_type algo,
493 const RawBuffer &keyId,
495 const RawBuffer &message,
496 RawBuffer &signature)
498 // command ID = CMD_SIGN (from km_ta_defines.h)
499 if (keyId.size() != KM_KEY_ID_SIZE) {
500 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
501 + std::to_string(keyId.size()) + ")");
505 sIn.Push(new TZSerializableBinary(message));
506 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
507 sIn.Push(new TZSerializableFlag(pwd_flag));
509 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
511 pwd.getTag().size() * 8,
513 sIn.Push(new TZSerializableBinary(keyId));
514 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
515 sIn.Serialize(inMemory);
518 sOut.Push(new TZSerializableBinary(MAX_KEY_SIZE.at(algo)));
519 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
522 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
523 TEEC_MEMREF_WHOLE, TEEC_NONE);
524 op.params[0].value.a = algo;
525 op.params[0].value.b = hash;
526 op.params[1].memref.parent = inMemory.Get();
527 op.params[1].memref.offset = 0;
528 op.params[1].memref.size = inMemory.Get()->size;
529 op.params[2].memref.parent = outMemory.Get();
530 op.params[2].memref.offset = 0;
531 op.params[2].memref.size = outMemory.Get()->size;
532 Execute(CMD_SIGN, &op);
534 sOut.Deserialize(outMemory);
535 sOut.Pull(signature);
538 int TrustZoneContext::executeVerify(tz_algo_type algo,
540 const RawBuffer &keyId,
542 const RawBuffer &message,
543 const RawBuffer &signature)
545 // command ID = CMD_VERIFY (from km_ta_defines.h)
546 if (keyId.size() != KM_KEY_ID_SIZE) {
547 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
548 + std::to_string(keyId.size()) + ")");
552 sIn.Push(new TZSerializableBinary(message));
553 sIn.Push(new TZSerializableBinary(signature));
554 int32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
555 sIn.Push(new TZSerializableFlag(pwd_flag));
557 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
559 pwd.getTag().size() * 8,
561 sIn.Push(new TZSerializableBinary(keyId));
562 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
563 sIn.Serialize(inMemory);
566 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
567 TEEC_NONE, TEEC_NONE);
568 op.params[0].value.a = algo;
569 op.params[0].value.b = hash;
570 op.params[1].memref.parent = inMemory.Get();
571 op.params[1].memref.offset = 0;
572 op.params[1].memref.size = inMemory.Get()->size;
573 Execute(CMD_VERIFY, &op);
575 int opRet = op.params[0].value.a;
578 return CKM_API_SUCCESS;
579 case KM_TA_ERROR_SIGNATURE:
580 LogWarning("Signature verification failed");
581 return CKM_API_ERROR_VERIFICATION_FAILED;
583 assert(false); // This condition should be checked inside Execute() function
584 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", opRet);
588 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
590 // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
591 if (keyId.size() != KM_KEY_ID_SIZE) {
592 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
596 sIn.Push(new TZSerializableBinary(keyId));
597 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
598 sIn.Serialize(inMemory);
601 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
602 TEEC_NONE, TEEC_NONE);
603 op.params[1].memref.parent = inMemory.Get();
604 op.params[1].memref.offset = 0;
605 op.params[1].memref.size = inMemory.Get()->size;
606 Execute(CMD_DESTROY_KEY, &op);
609 void TrustZoneContext::importData(
610 const uint32_t dataType,
611 const RawBuffer &data,
612 const Crypto::EncryptionParams &encData,
613 const RawBuffer &pwd,
615 const uint32_t keySizeBits,
616 const uint32_t pwdTagSizeBits,
620 // command ID = CMD_IMPORT_DATA
622 sIn.Push(new TZSerializableFlag(dataType));
623 sIn.Push(new TZSerializableBinary(data));
624 sIn.Push(new TZSerializableFlag(keySizeBits));
625 sIn.Push(new TZSerializableBinary(encData.iv));
626 sIn.Push(new TZSerializableBinary(encData.tag));
628 uint32_t pwd_flag = pwd.empty() ? 0 : 1;
629 sIn.Push(new TZSerializableFlag(pwd_flag));
631 sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
633 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
634 sIn.Serialize(inMemory);
638 sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE));
640 sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
643 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
646 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
647 TEEC_MEMREF_WHOLE, TEEC_NONE);
648 op.params[1].memref.parent = inMemory.Get();
649 op.params[1].memref.offset = 0;
650 op.params[1].memref.size = inMemory.Get()->size;
651 op.params[2].memref.parent = outMemory.Get();
652 op.params[2].memref.offset = 0;
653 op.params[2].memref.size = outMemory.Get()->size;
655 Execute(CMD_IMPORT_DATA, &op);
657 sOut.Deserialize(outMemory);
663 LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
666 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
668 // command ID = CMD_GET_DATA_SIZE
669 LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
672 sIn.Push(new TZSerializableBinary(dataId));
674 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
675 sIn.Serialize(inMemory);
678 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
679 TEEC_NONE, TEEC_NONE);
681 op.params[1].memref.parent = inMemory.Get();
682 op.params[1].memref.offset = 0;
683 op.params[1].memref.size = inMemory.Get()->size;
684 Execute(CMD_GET_DATA_SIZE, &op);
685 dataSize = op.params[0].value.b;
688 void TrustZoneContext::getData(const RawBuffer &dataId,
692 // command ID = CMD_GET_DATA
693 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
696 sIn.Push(new TZSerializableBinary(dataId));
698 uint32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
699 sIn.Push(new TZSerializableFlag(pwd_flag));
702 sIn.Push(new TZSerializablePwdData(pwd.getPassword(),
704 Params::DEFAULT_AES_GCM_TAG_LEN_BITS,
708 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
709 sIn.Serialize(inMemory);
711 uint32_t data_size = 0;
712 GetDataSize(dataId, data_size);
715 sOut.Push(new TZSerializableBinary(data_size));
716 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
717 sOut.Serialize(outMemory);
720 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
721 TEEC_MEMREF_WHOLE, TEEC_NONE);
722 op.params[1].memref.parent = inMemory.Get();
723 op.params[1].memref.offset = 0;
724 op.params[1].memref.size = inMemory.Get()->size;
725 op.params[2].memref.parent = outMemory.Get();
726 op.params[2].memref.offset = 0;
727 op.params[2].memref.size = outMemory.Get()->size;
729 Execute(CMD_GET_DATA, &op);
731 sOut.Deserialize(outMemory);
736 void TrustZoneContext::destroyData(const RawBuffer &dataId)
738 // command ID = CMD_DESTROY_DATA
739 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
741 sIn.Push(new TZSerializableBinary(dataId));
743 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
744 sIn.Serialize(inMemory);
747 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
748 TEEC_NONE, TEEC_NONE);
750 op.params[1].memref.parent = inMemory.Get();
751 op.params[1].memref.offset = 0;
752 op.params[1].memref.size = inMemory.Get()->size;
753 Execute(CMD_DESTROY_DATA, &op);
756 void TrustZoneContext::Initialize()
762 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
764 result = TEEC_InitializeContext(nullptr, &m_Context);
765 if (result != TEEC_SUCCESS) {
766 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize TEE context: ", result);
768 m_ContextInitialized = true;
770 result = TEEC_OpenSession(&m_Context, &m_Session, &KEY_MANAGER_TA_UUID, 0, nullptr, &op, &retOrigin);
771 if (result != TEEC_SUCCESS) {
772 ThrowErr(Exc::Crypto::InternalError, "Failed to open session to Key Manager TA: ", result);
774 m_SessionInitialized = true;
777 void TrustZoneContext::Destroy()
779 if (m_SessionInitialized) {
780 TEEC_CloseSession(&m_Session);
781 m_SessionInitialized = false;
784 if (m_ContextInitialized) {
785 TEEC_FinalizeContext(&m_Context);
786 m_ContextInitialized = false;
790 void TrustZoneContext::Reload()
796 void TrustZoneContext::Execute(tz_command commandID, TEEC_Operation* op)
798 uint32_t retOrigin = 0;
799 LogDebug("Executing TZ operation " << commandID);
801 TEEC_Result result = TEEC_InvokeCommand(&m_Session, static_cast<unsigned int>(commandID), op, &retOrigin);
802 if (result != TEEC_SUCCESS) {
804 case TEEC_ERROR_TARGET_DEAD:
806 ThrowErr(Exc::Crypto::InternalError, "TA panicked while executing command ",
807 static_cast<unsigned int>(commandID));
808 case TEEC_ERROR_BAD_PARAMETERS:
809 ThrowErr(Exc::Crypto::InputParam, "Incorrect parameters provided to TA");
811 ThrowErr(Exc::Crypto::InternalError, "TA failed to invoke command ",
812 static_cast<unsigned int>(commandID), " with error: ", std::hex,
813 static_cast<unsigned int>(result), " with origin: ", std::hex,
818 int ta_ret = op->params[0].value.a;
821 case KM_TA_ERROR_SIGNATURE:
823 case KM_TA_ERROR_AUTH_FAILED:
824 // Authentication cipher failed - notify with proper exception
825 ThrowErr(Exc::AuthenticationFailed, "Crypto operation authentication failed");
827 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", ta_ret);
831 } // namespace Internals
833 } // namespace Crypto