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 }
73 const RawBuffer &password;
78 void push(TZSerializer& ser, const T& value)
80 ser.Push(new TZSerializableFlag(static_cast<uint32_t>(value)));
84 void push<RawBuffer>(TZSerializer& ser, const RawBuffer& value)
86 ser.Push(new TZSerializableBinary(value));
90 void push<Pwd>(TZSerializer& ser, const Pwd& value)
92 int32_t pwd_flag = value.getPassword().empty() ? 0 : 1;
93 ser.Push(new TZSerializableFlag(pwd_flag));
95 ser.Push(new TZSerializablePwdData(value.getPassword(),
97 value.getTag().size() * 8,
102 void push<EncPwd>(TZSerializer& ser, const EncPwd& value)
104 int32_t pwd_flag = value.password.empty() ? 0 : 1;
105 ser.Push(new TZSerializableFlag(pwd_flag));
107 ser.Push(new TZSerializablePwdData(value.password,
109 Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
112 template <typename T, typename ...Args>
113 void push(TZSerializer& ser, const T& first, const Args&... args)
116 push<Args...>(ser, args...);
119 template <typename ...Args>
120 TZSerializer makeSerializer(const Args&... args)
123 push<Args...>(ser, args...);
127 } // anonymous namespace
129 TrustZoneContext::TrustZoneContext()
130 : m_ContextInitialized(false)
131 , m_SessionInitialized(false)
136 TrustZoneContext::~TrustZoneContext()
141 TrustZoneContext& TrustZoneContext::Instance()
143 static TrustZoneContext instance;
147 TEEC_Operation makeOp(uint32_t value, TrustZoneMemory& mem1)
151 op.paramTypes = TEEC_PARAM_TYPES(value, TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE);
153 op.params[1].memref.parent = mem1.Get();
154 op.params[1].memref.offset = 0;
155 op.params[1].memref.size = mem1.Get()->size;
159 TEEC_Operation makeOp(uint32_t value, TrustZoneMemory& mem1, TrustZoneMemory& mem2)
161 TEEC_Operation op = makeOp(value, mem1);
163 op.paramTypes = TEEC_PARAM_TYPES(value, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE);
165 op.params[2].memref.parent = mem2.Get();
166 op.params[2].memref.offset = 0;
167 op.params[2].memref.size = mem2.Get()->size;
172 void TrustZoneContext::generateIV(RawBuffer& iv)
174 // command ID = CMD_GENERATE_IV
175 // IV generation is a simple call - no need to serialize data
176 // just provide the output buffer with size equal to iv.
177 uint32_t ivSize = Params::DEFAULT_AES_IV_LEN;
178 TrustZoneMemory ivMemory(m_Context, ivSize, TEEC_MEM_OUTPUT);
180 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, ivMemory);
182 Execute(CMD_GENERATE_IV, &op);
185 memcpy(iv.data(), ivMemory.Get()->buffer, ivMemory.Get()->size);
188 void TrustZoneContext::generateSKey(tz_algo_type algo,
189 uint32_t keySizeBits,
190 const RawBuffer &hash)
192 // command ID = CMD_GENERATE_KEY
193 auto sIn = makeSerializer(hash);
194 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
195 sIn.Serialize(inMemory);
197 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
198 op.params[0].value.a = algo;
199 op.params[0].value.b = keySizeBits;
201 Execute(CMD_GENERATE_KEY, &op);
204 void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
205 const RawBuffer &pwd,
207 const uint32_t keySizeBits,
209 const RawBuffer &hash)
211 // command ID = CMD_GENERATE_KEY_PWD
213 sIn.Push(new TZSerializablePwdData(pwd, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
214 sIn.Push(new TZSerializableBinary(hash));
215 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
216 sIn.Serialize(inMemory);
219 sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
220 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
222 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
223 op.params[0].value.a = algo;
224 op.params[0].value.b = keySizeBits;
226 Execute(CMD_GENERATE_KEY_PWD, &op);
228 sOut.Deserialize(outMemory);
231 if (pwdTag.size() != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
232 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag");
236 void TrustZoneContext::GenerateAKey(tz_command commandId,
238 uint32_t genParam, // key size in bits or EC type
239 const RawBuffer &pubPwd,
240 const RawBuffer &pubPwdIv,
241 const RawBuffer &privPwd,
242 const RawBuffer &privPwdIv,
243 RawBuffer &pubKeyTag,
244 RawBuffer &privKeyTag,
245 const RawBuffer &hashPriv,
246 const RawBuffer &hashPub)
248 uint32_t pubTagSize = 0;
249 uint32_t privTagSize = 0;
250 uint32_t pubPwdExists = pubPwd.empty() ? 0 : 1;
252 pubTagSize = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
254 uint32_t privPwdExists = privPwd.empty() ? 0 : 1;
256 privTagSize = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
259 push(sIn, EncPwd{pubPwd, pubPwdIv}, EncPwd{privPwd, privPwdIv}, hashPriv, hashPub);
260 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
261 sIn.Serialize(inMemory);
264 sOut.Push(new TZSerializableBinary(pubTagSize));
265 sOut.Push(new TZSerializableBinary(privTagSize));
267 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
269 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
270 op.params[0].value.b = genParam;
272 Execute(commandId, &op);
274 sOut.Deserialize(outMemory);
276 sOut.Pull(pubKeyTag);
280 sOut.Pull(privKeyTag);
284 void TrustZoneContext::generateRSAKey(uint32_t keySizeBits,
285 const RawBuffer &pubPwd,
286 const RawBuffer &pubPwdIv,
287 const RawBuffer &privPwd,
288 const RawBuffer &privPwdIv,
289 RawBuffer &pubKeyTag,
290 RawBuffer &privKeyTag,
291 const RawBuffer &hashPriv,
292 const RawBuffer &hashPub)
294 // command ID = CMD_GENERATE_RSA_KEYPAIR
297 GenerateAKey(CMD_GENERATE_RSA_KEYPAIR,
310 void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
311 const RawBuffer &prime,
312 const RawBuffer &subprime,
313 const RawBuffer &base,
314 const RawBuffer &pubPwd,
315 const RawBuffer &pubPwdIv,
316 const RawBuffer &privPwd,
317 const RawBuffer &privPwdIv,
318 RawBuffer &pubKeyTag,
319 RawBuffer &privKeyTag,
320 const RawBuffer &hashPriv,
321 const RawBuffer &hashPub)
323 // command ID = CMD_GENERATE_DSA_KEYPAIR
324 auto sIn = makeSerializer(prime, subprime, base);
326 GenerateAKey(CMD_GENERATE_DSA_KEYPAIR,
339 void TrustZoneContext::generateECKey(tz_ec ec,
340 const RawBuffer &pubPwd,
341 const RawBuffer &pubPwdIv,
342 const RawBuffer &privPwd,
343 const RawBuffer &privPwdIv,
344 RawBuffer &pubKeyTag,
345 RawBuffer &privKeyTag,
346 const RawBuffer &hashPriv,
347 const RawBuffer &hashPub)
349 // command ID = CMD_GENERATE_EC_KEYPAIR
352 GenerateAKey(CMD_GENERATE_EC_KEYPAIR,
354 static_cast<uint32_t>(ec),
365 void TrustZoneContext::executeCrypt(tz_command cmd,
367 const RawBuffer &keyId,
370 const RawBuffer &data,
373 // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
374 if (keyId.size() != KM_KEY_ID_SIZE) {
375 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
376 + std::to_string(keyId.size()) + ")");
380 if (algo == ALGO_RSA)
381 sIn = makeSerializer(data, pwd, keyId);
383 sIn = makeSerializer(data, pwd, iv, keyId);
385 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
386 sIn.Serialize(inMemory);
388 // decrypt operation does not require padding
389 uint32_t outMemorySize = data.size();
390 if (cmd == CMD_ENCRYPT) {
391 if (algo == ALGO_RSA) {
392 // We don't know the key length
393 outMemorySize = MAX_KEY_SIZE.at(ALGO_RSA);
395 outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
400 sOut.Push(new TZSerializableBinary(outMemorySize, false));
401 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
403 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
404 op.params[0].value.a = algo;
408 sOut.Deserialize(outMemory);
412 void TrustZoneContext::executeEncryptAE(const RawBuffer &keyId,
416 const RawBuffer &aad,
417 const RawBuffer &data,
421 // command ID = CMD_ENCRYPT (from km_ta_defines.h)
422 if (keyId.size() != KM_KEY_ID_SIZE) {
423 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
426 auto sIn = makeSerializer(data, pwd, iv, keyId, aad, tagSizeBits);
427 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
428 sIn.Serialize(inMemory);
430 uint32_t outMemorySize = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
431 uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
434 sOut.Push(new TZSerializableBinary(outMemorySize, false));
435 sOut.Push(new TZSerializableBinary(tagSizeBytes));
436 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
438 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
439 op.params[0].value.a = ALGO_AES_GCM;
441 Execute(CMD_ENCRYPT, &op);
443 sOut.Deserialize(outMemory);
448 void TrustZoneContext::executeDecryptAE(const RawBuffer &keyId,
452 const RawBuffer &tag,
453 const RawBuffer &aad,
454 const RawBuffer &data,
457 // command ID = CMD_DECRYPT (from km_ta_defines.h)
458 if (keyId.size() != KM_KEY_ID_SIZE) {
459 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
462 auto sIn = makeSerializer(data, pwd, iv, keyId, aad, tagSizeBits, tag);
463 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
464 sIn.Serialize(inMemory);
467 sOut.Push(new TZSerializableBinary(data.size()));
468 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
470 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
471 op.params[0].value.a = ALGO_AES_GCM;
473 Execute(CMD_DECRYPT, &op);
475 sOut.Deserialize(outMemory);
479 void TrustZoneContext::executeSign(tz_algo_type algo,
481 const RawBuffer &keyId,
483 const RawBuffer &message,
484 RawBuffer &signature)
486 // command ID = CMD_SIGN (from km_ta_defines.h)
487 if (keyId.size() != KM_KEY_ID_SIZE) {
488 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
489 + std::to_string(keyId.size()) + ")");
492 auto sIn = makeSerializer(message, pwd, 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);
500 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
501 op.params[0].value.a = algo;
502 op.params[0].value.b = hash;
504 Execute(CMD_SIGN, &op);
506 sOut.Deserialize(outMemory);
507 sOut.Pull(signature);
510 int TrustZoneContext::executeVerify(tz_algo_type algo,
512 const RawBuffer &keyId,
514 const RawBuffer &message,
515 const RawBuffer &signature)
517 // command ID = CMD_VERIFY (from km_ta_defines.h)
518 if (keyId.size() != KM_KEY_ID_SIZE) {
519 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
520 + std::to_string(keyId.size()) + ")");
523 auto sIn = makeSerializer(message, signature, pwd, keyId);
524 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
525 sIn.Serialize(inMemory);
527 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
528 op.params[0].value.a = algo;
529 op.params[0].value.b = hash;
531 Execute(CMD_VERIFY, &op);
533 int opRet = op.params[0].value.a;
536 return CKM_API_SUCCESS;
537 case KM_TA_ERROR_SIGNATURE:
538 LogWarning("Signature verification failed");
539 return CKM_API_ERROR_VERIFICATION_FAILED;
541 assert(false); // This condition should be checked inside Execute() function
542 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", opRet);
546 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
548 // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
549 if (keyId.size() != KM_KEY_ID_SIZE) {
550 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
553 auto sIn = makeSerializer(keyId);
554 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
555 sIn.Serialize(inMemory);
557 TEEC_Operation op = makeOp(TEEC_VALUE_OUTPUT, inMemory);
559 Execute(CMD_DESTROY_KEY, &op);
562 void TrustZoneContext::importData(
563 const uint32_t dataType,
564 const RawBuffer &data,
565 const Crypto::EncryptionParams &encData,
566 const RawBuffer &pwd,
568 const uint32_t keySizeBits,
570 const RawBuffer &hash)
572 // command ID = CMD_IMPORT_DATA
573 LogDebug("TrustZoneContext::importData data size = [" << data.size() << "]");
575 auto sIn = makeSerializer(
576 dataType, data, keySizeBits, encData.iv, encData.tag, EncPwd{pwd, iv}, hash);
578 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
579 sIn.Serialize(inMemory);
583 sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
586 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
588 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
590 op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
592 Execute(CMD_IMPORT_DATA, &op);
595 sOut.Deserialize(outMemory);
599 LogDebug("Imported object ID is (hex): " << rawToHexString(hash));
602 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
604 // command ID = CMD_GET_DATA_SIZE
605 LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
607 auto sIn = makeSerializer(dataId);
608 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
609 sIn.Serialize(inMemory);
611 TEEC_Operation op = makeOp(TEEC_VALUE_OUTPUT, inMemory);
613 Execute(CMD_GET_DATA_SIZE, &op);
614 dataSize = op.params[0].value.b;
617 void TrustZoneContext::getData(const RawBuffer &dataId,
621 // command ID = CMD_GET_DATA
622 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
624 auto sIn = makeSerializer(dataId, pwd);
625 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
626 sIn.Serialize(inMemory);
628 uint32_t data_size = 0;
629 GetDataSize(dataId, data_size);
631 LogDebug("GetData data_size = [" << data_size << "]");
634 sOut.Push(new TZSerializableBinary(data_size));
635 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
636 sOut.Serialize(outMemory);
638 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
640 Execute(CMD_GET_DATA, &op);
642 sOut.Deserialize(outMemory);
647 void TrustZoneContext::destroyData(const RawBuffer &dataId)
649 // command ID = CMD_DESTROY_DATA
650 LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
651 auto sIn = makeSerializer(dataId);
652 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
653 sIn.Serialize(inMemory);
655 TEEC_Operation op = makeOp(TEEC_VALUE_OUTPUT, inMemory);
657 Execute(CMD_DESTROY_DATA, &op);
660 TZSerializablePwdData* makeSerializablePwd(const Pwd &pwd)
662 auto &tag = pwd.getTag();
663 return new TZSerializablePwdData(pwd.getPassword(), pwd.getIV(), tag.size() * 8, tag);
666 void TrustZoneContext::executeEcdh(const RawBuffer &prvKeyId,
667 const Pwd &prvKeyPwd,
668 const RawBuffer &pubX,
669 const RawBuffer &pubY,
670 const RawBuffer &secretPwdBuf,
671 const RawBuffer &secretPwdIV,
672 RawBuffer &secretTag,
673 const RawBuffer &secretHash)
675 // command ID = CMD_DERIVE
676 LogDebug("TrustZoneContext::executeEcdh");
678 auto sIn = makeSerializer(
679 prvKeyId, prvKeyPwd, pubX, pubY, EncPwd{secretPwdBuf, secretPwdIV}, secretHash);
680 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
681 sIn.Serialize(inMemory);
684 if (!secretPwdBuf.empty()) {
685 sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
688 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
690 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
691 if (!secretPwdBuf.empty())
692 op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
693 op.params[0].value.a = ALGO_ECDH_DRV;
695 Execute(CMD_DERIVE, &op);
697 if (!secretPwdBuf.empty()) {
698 sOut.Deserialize(outMemory);
699 sOut.Pull(secretTag);
702 LogDebug("Derived object ID is (hex): " << rawToHexString(secretHash));
705 void TrustZoneContext::executeKbkdf(const RawBuffer& secret,
708 KbkdfCounterLocation location,
712 const RawBuffer &keyPwdBuf,
713 const RawBuffer &keyPwdIV,
715 const RawBuffer &keyHash)
717 // command ID = CMD_DERIVE
718 LogDebug("TrustZoneContext::executeKbkdf");
720 auto sIn = makeSerializer(
721 secret, prf, mode, location, rlen, llen, noSeparator, EncPwd{keyPwdBuf, keyPwdIV}, keyHash);
722 TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
723 sIn.Serialize(inMemory);
726 if (!keyPwdBuf.empty()) {
727 sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
730 TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
732 TEEC_Operation op = makeOp(TEEC_VALUE_INOUT, inMemory);
733 if (!keyPwdBuf.empty())
734 op = makeOp(TEEC_VALUE_INOUT, inMemory, outMemory);
735 op.params[0].value.a = ALGO_KBKDF_DRV;
737 Execute(CMD_DERIVE, &op);
739 if (!keyPwdBuf.empty()) {
740 sOut.Deserialize(outMemory);
744 LogDebug("Derived object ID is (hex): " << rawToHexString(keyHash));
747 void TrustZoneContext::Initialize()
753 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
755 result = TEEC_InitializeContext(nullptr, &m_Context);
756 if (result != TEEC_SUCCESS) {
757 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize TEE context: ", result);
759 m_ContextInitialized = true;
761 result = TEEC_OpenSession(&m_Context, &m_Session, &KEY_MANAGER_TA_UUID, 0, nullptr, &op, &retOrigin);
762 if (result != TEEC_SUCCESS) {
763 ThrowErr(Exc::Crypto::InternalError, "Failed to open session to Key Manager TA: ", result);
765 m_SessionInitialized = true;
768 void TrustZoneContext::Destroy()
770 if (m_SessionInitialized) {
771 TEEC_CloseSession(&m_Session);
772 m_SessionInitialized = false;
775 if (m_ContextInitialized) {
776 TEEC_FinalizeContext(&m_Context);
777 m_ContextInitialized = false;
781 void TrustZoneContext::Reload()
787 void TrustZoneContext::Execute(tz_command commandID, TEEC_Operation* op)
789 uint32_t retOrigin = 0;
790 LogDebug("Executing TZ operation " << commandID);
792 TEEC_Result result = TEEC_InvokeCommand(&m_Session, static_cast<unsigned int>(commandID), op, &retOrigin);
793 if (result != TEEC_SUCCESS) {
795 case TEEC_ERROR_TARGET_DEAD:
797 ThrowErr(Exc::Crypto::InternalError, "TA panicked while executing command ",
798 static_cast<unsigned int>(commandID));
799 case TEEC_ERROR_BAD_PARAMETERS:
800 ThrowErr(Exc::Crypto::InputParam, "Incorrect parameters provided to TA");
802 ThrowErr(Exc::Crypto::InternalError, "TA failed to invoke command ",
803 static_cast<unsigned int>(commandID), " with error: ", std::hex,
804 static_cast<unsigned int>(result), " with origin: ", std::hex,
809 int ta_ret = op->params[0].value.a;
812 case KM_TA_ERROR_SIGNATURE:
814 case KM_TA_ERROR_AUTH_FAILED:
815 // Authentication cipher failed - notify with proper exception
816 ThrowErr(Exc::AuthenticationFailed, "Crypto operation authentication failed");
818 ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", ta_ret);
822 } // namespace Internals
824 } // namespace Crypto