Some TZ backend fixes.
[platform/core/security/key-manager.git] / src / manager / crypto / tz-backend / tz-context.cpp
1 /*
2  *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16 /*
17  * @file       tz-context.cpp
18  * @author     Lukasz Kostyra (l.kostyra@samsung.com)
19  * @version    1.0
20  */
21
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>
28
29 #include <km_serialization.h>
30 #include <km_ta_defines.h>
31
32 #include <cstdint>
33 #include <cstring>
34
35 namespace CKM {
36 namespace Crypto {
37 namespace TZ {
38 namespace Internals {
39
40 namespace {
41
42 // A little bit of extra memory to add to output buffers.
43 //
44 // We need this extra memory to output for padding purposes - after encryption
45 // we can resize the result memory back to its proper size according to
46 // whatever TA will return us.
47 const uint32_t CIPHER_EXTRA_PADDING_SIZE = 16;
48
49 // Identifier of our TA
50 const TEEC_UUID KEY_MANAGER_TA_UUID = KM_TA_UUID;
51
52 //raw to hex string conversion to print persistent storage data ID
53 static std::string rawToHexString(const RawBuffer &raw)
54 {
55         std::string dump;
56
57         for (auto &e : raw) {
58                 char buf[3];
59                 snprintf(buf, sizeof(buf), "%02x", (e & 0xff));
60                 dump.push_back(buf[0]);
61                 dump.push_back(buf[1]);
62         }
63
64         return dump;
65 }
66
67 } // anonymous namespace
68
69 TrustZoneContext::TrustZoneContext()
70         : m_ContextInitialized(false)
71         , m_SessionInitialized(false)
72 {
73         Initialize();
74 }
75
76 TrustZoneContext::~TrustZoneContext()
77 {
78         Destroy();
79 }
80
81 TrustZoneContext& TrustZoneContext::Instance()
82 {
83         static TrustZoneContext instance;
84         return instance;
85 }
86
87 void TrustZoneContext::generateIV(RawBuffer& iv)
88 {
89         // command ID = CMD_GENERATE_IV
90         //
91         // TEEC_Operation layout:
92         // params:
93         //   [1].memref.buffer - output
94         //   [1].memref.size - output size
95         // output:
96         //   [0].value.a - return code
97
98         // IV generation is a simple call - no need to serialize data
99         // just provide the output buffer with size equal to iv.
100         uint32_t ivSize = Params::DEFAULT_AES_IV_LEN;
101         TrustZoneMemory ivMemory(m_Context, ivSize, TEEC_MEM_OUTPUT);
102
103         TEEC_Operation op;
104         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
105                                                                         TEEC_NONE, TEEC_NONE);
106         op.params[1].memref.parent = ivMemory.Get();
107         op.params[1].memref.offset = 0;
108         op.params[1].memref.size = ivMemory.Get()->size;
109         Execute(CMD_GENERATE_IV, &op);
110
111         iv.resize(ivSize);
112         memcpy(iv.data(), ivMemory.Get()->buffer, ivMemory.Get()->size);
113 }
114
115 void TrustZoneContext::generateSKey(tz_algo_type algo,
116                                                                         uint32_t keySizeBits,
117                                                                         RawBuffer &keyId)
118 {
119         // command ID = CMD_GENERATE_KEY
120         //
121         // TEEC_Operation layout:
122         // params:
123         //   [0].value.a - key type
124         //   [0].value.b - key bit size
125         // output:
126         //   [0].value.a - return code
127         //   [1].memref - serialized key reference
128
129         KM_BufferSizeDesc bufSize;
130
131         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
132         bufSize.out_size = KM_KEY_ID_SIZE;
133         uint32_t keyMemorySize = KM_CalcBufferSize(bufSize);
134         TrustZoneMemory keyMemory(m_Context, keyMemorySize, TEEC_MEM_OUTPUT);
135
136         TEEC_Operation op;
137         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
138                                                                         TEEC_NONE, TEEC_NONE);
139         op.params[0].value.a = algo;
140         op.params[0].value.b = keySizeBits;
141         op.params[1].memref.parent = keyMemory.Get();
142         op.params[1].memref.offset = 0;
143         op.params[1].memref.size = keyMemorySize;
144         Execute(CMD_GENERATE_KEY, &op);
145
146         KM_SymmetricInput* output = nullptr;
147         int ret = KM_ParamsDeserializationInit(keyMemory.Get()->buffer, keyMemory.Get()->size, &output);
148         if (ret) {
149                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize deserialization for generated key ID");
150         }
151
152         KM_OutData* outData = nullptr;
153         ret = KM_ParamsDeserializeOutData(output, &outData);
154         if (ret) {
155                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize generated key ID");
156         }
157
158         if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
159                 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key ID");
160         }
161
162         keyId.resize(KM_KEY_ID_SIZE);
163         memcpy(keyId.data(), outData->data, KM_KEY_ID_SIZE);
164 }
165
166 void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
167                                                                         const RawBuffer &pwd,
168                                                                         const RawBuffer &iv,
169                                                                         const uint32_t keySizeBits,
170                                                                         RawBuffer &keyId,
171                                                                         RawBuffer &pwdTag)
172 {
173         // command ID = CMD_GENERATE_KEY_PWD
174         //
175         // TEEC_Operation layout:
176         // params:
177         //   [0].value.a - key type
178         //   [0].value.b - key size in bits
179         //   [1].memref  - input (seralized pwd/iv for pbkdf2)
180         // output:
181         //   [0].value.a - return code
182         //   [2].memref - serialized key reference ID
183
184         KM_BufferSizeDesc bufSize;
185
186         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
187         bufSize.with_pwd_data = true;
188         bufSize.pwd_size = static_cast<uint32_t>(pwd.size());
189         bufSize.pwd_iv_size = static_cast<uint32_t>(iv.size());
190         uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
191         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
192
193         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
194         bufSize.out_size = KM_KEY_ID_SIZE;
195         bufSize.tag_size = Params::DEFAULT_AES_GCM_TAG_LEN_BYTES;
196         uint32_t keyMemorySize = KM_CalcBufferSize(bufSize);
197         TrustZoneMemory keyMemory(m_Context, keyMemorySize, TEEC_MEM_OUTPUT);
198
199         KM_SymmetricInput* input = nullptr;
200         int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
201         if (ret) {
202                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
203         }
204
205         ret = KM_ParamsSerializePwdData(input, pwd.data(), pwd.size(), iv.data(), iv.size(),
206                                                                         nullptr, 0, Params::DERIVED_KEY_LENGTH_BITS,
207                                                                         Params::DERIVED_KEY_ITERATIONS, bufSize.tag_size * 8);
208         if (ret) {
209                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
210         }
211
212         TEEC_Operation op;
213         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
214                                                                         TEEC_MEMREF_WHOLE, TEEC_NONE);
215         op.params[0].value.a = algo;
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 = keyMemory.Get();
221         op.params[2].memref.offset = 0;
222         op.params[2].memref.size = keyMemory.Get()->size;
223         Execute(CMD_GENERATE_KEY_PWD, &op);
224
225         KM_SymmetricInput* output = nullptr;
226         ret = KM_ParamsDeserializationInit(keyMemory.Get()->buffer, keyMemory.Get()->size, &output);
227         if (ret) {
228                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize deserialization for generated key ID");
229         }
230
231         KM_OutData* outData = nullptr;
232         ret = KM_ParamsDeserializeOutData(output, &outData);
233         if (ret) {
234                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize generated key ID");
235         }
236
237         KM_TagData* tagData = nullptr;
238         ret = KM_ParamsDeserializeTagData(output, &tagData);
239         if (ret) {
240                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize key's tag");
241         }
242
243         if (outData == nullptr || outData->data_size != KM_KEY_ID_SIZE) {
244                 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key ID");
245         }
246
247         if (tagData == nullptr || tagData->data_size != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
248                 ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag");
249         }
250
251         keyId.resize(KM_KEY_ID_SIZE);
252         memcpy(keyId.data(), outData->data, KM_KEY_ID_SIZE);
253
254         pwdTag.resize(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
255         memcpy(pwdTag.data(), tagData->data, Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
256 }
257
258 void TrustZoneContext::executeCrypt(tz_command cmd,
259                                                                         tz_algo_type algo,
260                                                                         const RawBuffer &key,
261                                                                         const Pwd &pwd,
262                                                                         const RawBuffer &iv,
263                                                                         const RawBuffer &data,
264                                                                         RawBuffer &out)
265 {
266         // command IDs = CMD_ENCRYPT, CMD_DECRYPT (from km_ta_defines.h)
267         //
268         // TEEC_Operation layout:
269         // params:
270         //   [0].value.a - keyid
271         //   [0].value.b - algo
272         //   [1].memref - input data (serialized key/input)
273         // returned:
274         //   [0].value.a - return code
275         //   [2].memref - serialized output buffer
276
277         if (key.size() != KM_KEY_ID_SIZE) {
278                 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer (size = "
279                         + std::to_string(key.size()) + ")");
280         }
281
282         KM_BufferSizeDesc bufSize;
283
284         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
285         bufSize.input_size = static_cast<uint32_t>(data.size());
286         bufSize.with_pwd_data = true;
287         bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
288         bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
289         bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
290         bufSize.iv_size = static_cast<uint32_t>(iv.size());
291         bufSize.key_id_size = static_cast<uint32_t>(key.size());
292         uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
293         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
294
295         // decrypt operation does not require padding
296         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
297         bufSize.out_size = static_cast<uint32_t>((cmd == CMD_ENCRYPT) ?
298                                                         data.size() + CIPHER_EXTRA_PADDING_SIZE :
299                                                         data.size());
300         uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
301         TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
302
303         KM_SymmetricInput* input = nullptr;
304         int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
305         if (ret) {
306                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
307         }
308
309         ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
310         if (ret) {
311                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
312         }
313
314         uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
315         ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
316                                                                         pwd.getIV().data(), pwd.getIV().size(),
317                                                                         pwd.getTag().data(), pwd.getTag().size(),
318                                                                         Params::DERIVED_KEY_LENGTH_BITS,
319                                                                         Params::DERIVED_KEY_ITERATIONS,
320                                                                         pwdTagSizeBits);
321         if (ret) {
322                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
323         }
324
325         ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
326         if (ret) {
327                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
328         }
329
330         ret = KM_ParamsSerializeKeyId(input, key.data(), key.size());
331         if (ret) {
332                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
333         }
334
335         TEEC_Operation op;
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;
345         Execute(cmd, &op);
346
347         KM_SymmetricInput* output = nullptr;
348         ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
349         if (ret) {
350                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
351         }
352
353         KM_OutData* outData = nullptr;
354         ret = KM_ParamsDeserializeOutData(output, &outData);
355         if (ret) {
356                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
357         }
358
359         // data_size should contain how much memory we actually took for our cipher operation
360         out.resize(outData->data_size);
361         memcpy(out.data(), outData->data, outData->data_size);
362 }
363
364 void TrustZoneContext::executeEncryptAE(const RawBuffer &key,
365                                                                                 const Pwd &pwd,
366                                                                                 const RawBuffer &iv,
367                                                                                 int tagSizeBits,
368                                                                                 const RawBuffer &aad,
369                                                                                 const RawBuffer &data,
370                                                                                 RawBuffer &out,
371                                                                                 RawBuffer &tag)
372 {
373         // command ID = CMD_ENCRYPT (from km_ta_defines.h)
374         //
375         // TEEC_Operation layout:
376         // params:
377         //   [0].value.a - keyid
378         //   [0].value.b - algo
379         //   [1].memref - input data (serialized key/input/iv/aad)
380         // returned:
381         //   [0].value.a - return code
382         //   [2].memref - output
383
384         if (key.size() != KM_KEY_ID_SIZE) {
385                 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
386         }
387
388         uint32_t tagSizeBytes = (tagSizeBits + 7) / 8;
389         KM_BufferSizeDesc bufSize;
390
391         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
392         bufSize.input_size = static_cast<uint32_t>(data.size());
393         bufSize.with_pwd_data = true;
394         bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
395         bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
396         bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
397         bufSize.iv_size = static_cast<uint32_t>(iv.size());
398         bufSize.key_id_size = static_cast<uint32_t>(key.size());
399         bufSize.with_ae_data = true;
400         bufSize.aad_size = static_cast<uint32_t>(aad.size());
401         uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
402         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
403
404         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
405         bufSize.out_size = static_cast<uint32_t>(data.size() + CIPHER_EXTRA_PADDING_SIZE);
406         bufSize.tag_size = static_cast<uint32_t>(tagSizeBytes);
407         uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
408         TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
409
410         KM_SymmetricInput* input = nullptr;
411         int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
412         if (ret) {
413                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
414         }
415
416         ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
417         if (ret) {
418                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
419         }
420
421         uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
422         ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
423                                                                         pwd.getIV().data(), pwd.getIV().size(),
424                                                                         pwd.getTag().data(), pwd.getTag().size(),
425                                                                         Params::DERIVED_KEY_LENGTH_BITS,
426                                                                         Params::DERIVED_KEY_ITERATIONS,
427                                                                         pwdTagSizeBits);
428         if (ret) {
429                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
430         }
431
432         ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
433         if (ret) {
434                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
435         }
436
437         ret = KM_ParamsSerializeKeyId(input, key.data(), key.size());
438         if (ret) {
439                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
440         }
441
442         ret = KM_ParamsSerializeAEData(input, tagSizeBits, 0, aad.data(), aad.size());
443         if (ret) {
444                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize auth data for TZ crypto operation: ", ret);
445         }
446
447         TEEC_Operation op;
448         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
449                                                                         TEEC_MEMREF_WHOLE, TEEC_NONE);
450         op.params[0].value.a = ALGO_AES_GCM;
451         op.params[1].memref.parent = inMemory.Get();
452         op.params[1].memref.offset = 0;
453         op.params[1].memref.size = inMemory.Get()->size;
454         op.params[2].memref.parent = outMemory.Get();
455         op.params[2].memref.offset = 0;
456         op.params[2].memref.size = outMemory.Get()->size;
457         Execute(CMD_ENCRYPT, &op);
458
459         KM_SymmetricInput* output = nullptr;
460         ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
461         if (ret) {
462                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
463         }
464
465         KM_OutData* outData = nullptr;
466         ret = KM_ParamsDeserializeOutData(output, &outData);
467         if (ret) {
468                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
469         }
470
471         KM_TagData* tagData = nullptr;
472         ret = KM_ParamsDeserializeTagData(output, &tagData);
473         if (ret) {
474                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize tag data: ", ret);
475         }
476
477         out.resize(outData->data_size);
478         memcpy(out.data(), outData->data, outData->data_size);
479
480         if (tagData->data_size) {
481                 tag.resize(tagData->data_size);
482                 memcpy(tag.data(), tagData->data, tagData->data_size);
483         }
484 }
485
486 void TrustZoneContext::executeDecryptAE(const RawBuffer &key,
487                                                                                 const Pwd &pwd,
488                                                                                 const RawBuffer &iv,
489                                                                                 int tagSizeBits,
490                                                                                 const RawBuffer &tag,
491                                                                                 const RawBuffer &aad,
492                                                                                 const RawBuffer &data,
493                                                                                 RawBuffer &out)
494 {
495         // command ID = CMD_DECRYPT (from km_ta_defines.h)
496         //
497         // TEEC_Operation layout:
498         // params:
499         //   [0].value.a - keyid
500         //   [0].value.b - algo
501         //   [1].memref - input data (serialized key/input/iv/tag/aad)
502         // returned:
503         //   [0].value.a - output size
504         //   [2].memref - output (decrypted data)
505
506         if (key.size() != KM_KEY_ID_SIZE) {
507                 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
508         }
509
510         KM_BufferSizeDesc bufSize;
511
512         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
513         bufSize.input_size = static_cast<uint32_t>(data.size());
514         bufSize.with_pwd_data = true;
515         bufSize.pwd_size = static_cast<uint32_t>(pwd.getPassword().size());
516         bufSize.pwd_iv_size = static_cast<uint32_t>(pwd.getIV().size());
517         bufSize.pwd_tag_size = static_cast<uint32_t>(pwd.getTag().size());
518         bufSize.iv_size = static_cast<uint32_t>(iv.size());
519         bufSize.key_id_size = static_cast<uint32_t>(key.size());
520         bufSize.with_ae_data = true;
521         bufSize.aad_size = static_cast<uint32_t>(aad.size());
522         bufSize.tag_size = static_cast<uint32_t>(tag.size());
523         uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
524         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
525
526         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
527         bufSize.out_size = static_cast<uint32_t>(data.size());
528         uint32_t outMemorySize = KM_CalcBufferSize(bufSize);
529         TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
530
531         KM_SymmetricInput* input = nullptr;
532         int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
533         if (ret) {
534                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization for TZ crypto operations");
535         }
536
537         ret = KM_ParamsSerializeInputData(input, data.data(), data.size());
538         if (ret) {
539                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize input data for TZ crypto operation: ", ret);
540         }
541
542         uint32_t pwdTagSizeBits = pwd.getTag().size() * 8;
543         ret = KM_ParamsSerializePwdData(input, pwd.getPassword().data(), pwd.getPassword().size(),
544                                                                         pwd.getIV().data(), pwd.getIV().size(),
545                                                                         pwd.getTag().data(), pwd.getTag().size(),
546                                                                         Params::DERIVED_KEY_LENGTH_BITS,
547                                                                         Params::DERIVED_KEY_ITERATIONS,
548                                                                         pwdTagSizeBits);
549         if (ret) {
550                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize password data for TZ crypto operation: ", ret);
551         }
552
553         ret = KM_ParamsSerializeIVData(input, iv.data(), iv.size());
554         if (ret) {
555                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize IV data for TZ crypto operation: ", ret);
556         }
557
558         ret = KM_ParamsSerializeKeyId(input, key.data(), key.size());
559         if (ret) {
560                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key id data for TZ crypto operation: ", ret);
561         }
562
563         ret = KM_ParamsSerializeAEData(input, tagSizeBits, 0, aad.data(), aad.size());
564         if (ret) {
565                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize auth data for TZ crypto operation: ", ret);
566         }
567
568         ret = KM_ParamsSerializeTagData(input, tag.data(), tag.size());
569         if (ret) {
570                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize tag data for TZ crypto operation: ", ret);
571         }
572
573         TEEC_Operation op;
574         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
575                                                                         TEEC_MEMREF_WHOLE, TEEC_NONE);
576         op.params[0].value.a = ALGO_AES_GCM;
577         op.params[1].memref.parent = inMemory.Get();
578         op.params[1].memref.offset = 0;
579         op.params[1].memref.size = inMemory.Get()->size;
580         op.params[2].memref.parent = outMemory.Get();
581         op.params[2].memref.offset = 0;
582         op.params[2].memref.size = outMemory.Get()->size;
583         Execute(CMD_DECRYPT, &op);
584
585         KM_SymmetricInput* output = nullptr;
586         ret = KM_ParamsDeserializationInit(outMemory.Get()->buffer, outMemory.Get()->size, &output);
587         if (ret) {
588                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize output data deserialization: ", ret);
589         }
590
591         KM_OutData* outData = nullptr;
592         ret = KM_ParamsDeserializeOutData(output, &outData);
593         if (ret) {
594                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize output data: ", ret);
595         }
596
597         out.resize(outData->data_size);
598         memcpy(out.data(), outData->data, outData->data_size);
599 }
600
601 void TrustZoneContext::executeDestroy(const RawBuffer &keyId)
602 {
603         // command ID = CMD_DESTROY_KEY (from km_ta_defines.h)
604         //
605         // TEEC_Operation layout:
606         // input params:
607         //   [1].memref - input data (serialized key ID)
608         // output params:
609         //   [0].value.a - return code
610
611         if (keyId.size() != KM_KEY_ID_SIZE) {
612                 ThrowErr(Exc::Crypto::InternalError, "TZ Backend received incorrect key buffer");
613         }
614
615         KM_BufferSizeDesc bufSize;
616
617         memset(&bufSize, 0, sizeof(KM_BufferSizeDesc));
618         bufSize.key_id_size = static_cast<uint32_t>(keyId.size());
619         uint32_t inMemorySize = KM_CalcBufferSize(bufSize);
620         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
621
622         KM_SymmetricInput* input = nullptr;
623         int ret = KM_ParamsSerializationInit(inMemory.Get()->buffer, inMemory.Get()->size, &input);
624         if (ret) {
625                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize data serialization: ", ret);
626         }
627
628         ret = KM_ParamsSerializeInputData(input, keyId.data(), keyId.size());
629         if (ret) {
630                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize key ID to destroy: ", ret);
631         }
632
633         TEEC_Operation op;
634         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
635                                                                         TEEC_NONE, TEEC_NONE);
636         op.params[1].memref.parent = inMemory.Get();
637         op.params[1].memref.offset = 0;
638         op.params[1].memref.size = inMemory.Get()->size;
639         Execute(CMD_DESTROY_KEY, &op);
640 }
641
642 void TrustZoneContext::importData(
643                                 const uint32_t dataType,
644                                 const RawBuffer &data,
645                                 const Crypto::EncryptionParams &encData,
646                                 const RawBuffer &pwd,
647                                 const RawBuffer &iv,
648                                 const uint32_t keySizeBits,
649                                 const uint32_t pwdTagSizeBits,
650                                 RawBuffer &dataId,
651                                 RawBuffer &pwdTag)
652 {
653         // command ID = CMD_IMPORT_DATA
654         // input:
655         //    [1].memref  - reference to serialized buffer:
656         //        uint32_t dataType contains information about type stored as binary data
657         //        KM_BinaryData with binary data
658         //        uint32_t binary/key size in bits
659         //        KM_BinaryData IV for data decryption with built in key
660         //        KM_BinaryData TAG for data decryption with built in key
661         //        uint32_t boolean value - true if password is provided
662         //        KM_PwdData with password (optional)
663         // Output:
664         //    [0].value.a - return code
665         //    [2].memref  - reference to serialized buffer:
666         //        KM_BinaryData with data id
667         //        KM_BinaryData with tag id (optional, if password was provided)
668         uint32_t inMemorySize = 0;
669
670         // place for dataType
671         inMemorySize += KM_SizeOfFlag();
672
673         KM_BinaryData ta_data;
674         ta_data.data_size = static_cast<uint32_t>(data.size());
675         ta_data.data = const_cast<unsigned char *>(data.data());
676         inMemorySize += KM_SizeOfBinaryData(&ta_data);
677
678         uint32_t keySizeBits_flags = static_cast<uint32_t>(keySizeBits);
679         inMemorySize += KM_SizeOfFlag();
680
681         KM_BinaryData ta_data_enc_iv;
682         ta_data_enc_iv.data_size = static_cast<uint32_t>(encData.iv.size());
683         ta_data_enc_iv.data = const_cast<unsigned char *>(encData.iv.data());
684         inMemorySize += KM_SizeOfBinaryData(&ta_data_enc_iv);
685
686         KM_BinaryData ta_data_enc_tag;
687         ta_data_enc_tag.data_size = static_cast<uint32_t>(encData.tag.size());
688         ta_data_enc_tag.data = const_cast<unsigned char *>(encData.tag.data());
689         inMemorySize += KM_SizeOfBinaryData(&ta_data_enc_tag);
690
691         uint32_t pwd_flag = pwd.empty() ? 0 : 1;
692         inMemorySize += KM_SizeOfFlag();
693
694         KM_PwdData kmPwdData;
695         if (pwd_flag) {
696                 memset(&kmPwdData, 0, sizeof(KM_PwdData));
697                 kmPwdData.pwd = const_cast<unsigned char *>(pwd.data());
698                 kmPwdData.pwd_size = pwd.size();
699                 kmPwdData.iv = const_cast<unsigned char *>(iv.data());
700                 kmPwdData.iv_size = iv.size();
701                 kmPwdData.tag = NULL;
702                 kmPwdData.tag_size = 0;
703                 kmPwdData.derive_len_bits = Params::DERIVED_KEY_LENGTH_BITS;
704                 kmPwdData.it_count = Params::DERIVED_KEY_ITERATIONS;
705                 kmPwdData.tag_len_bits = pwdTagSizeBits;
706
707                 inMemorySize += KM_SizeOfPwdData(&kmPwdData);
708         }
709
710         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
711         void *inMemoryPtr = inMemory.Get()->buffer;
712
713         int ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, dataType);
714         if (ret){
715                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
716         }
717
718         ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &ta_data);
719         if (ret) {
720                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
721         }
722
723         ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, keySizeBits_flags);
724         if (ret) {
725                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
726         }
727
728         ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &ta_data_enc_iv);
729         if (ret) {
730                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
731         }
732
733         ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &ta_data_enc_tag);
734         if (ret) {
735                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
736         }
737
738         ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, pwd_flag);
739         if (ret) {
740                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
741         }
742
743         if (pwd_flag) {
744                 ret = KM_SerializePwdData(&inMemoryPtr, &inMemorySize, &kmPwdData);
745                 if (ret) {
746                         ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
747                 }
748         }
749
750         KM_BinaryData kmDataId;
751         KM_BinaryData kmTag;
752         memset(&kmDataId, 0, sizeof(KM_BinaryData));
753         memset(&kmTag, 0, sizeof(KM_BinaryData));
754         kmDataId.data_size = KM_DATA_ID_SIZE;
755         uint32_t outMemorySize = KM_SizeOfBinaryData(&kmDataId);
756         if (pwd_flag) {
757                 kmTag.data_size = pwdTagSizeBits / 8;
758                 outMemorySize += KM_SizeOfBinaryData(&kmTag);
759         }
760
761         TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
762         void *outMemoryPtr = outMemory.Get()->buffer;
763
764         TEEC_Operation op;
765         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
766                                                                         TEEC_MEMREF_WHOLE, TEEC_NONE);
767         op.params[1].memref.parent = inMemory.Get();
768         op.params[1].memref.offset = 0;
769         op.params[1].memref.size = inMemory.Get()->size;
770         op.params[2].memref.parent = outMemory.Get();
771         op.params[2].memref.offset = 0;
772         op.params[2].memref.size = outMemory.Get()->size;
773
774         Execute(CMD_IMPORT_DATA, &op);
775
776         ret = KM_DeserializeBinaryData(&outMemoryPtr, &outMemorySize, &kmDataId);
777         if (ret) {
778                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize data, ret: ", ret);
779         }
780         dataId.resize(kmDataId.data_size);
781         memcpy(dataId.data(), kmDataId.data, kmDataId.data_size);
782         if (pwd_flag) {
783                 ret = KM_DeserializeBinaryData(&outMemoryPtr, &outMemorySize, &kmTag);
784                 if (ret) {
785                         ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize data, ret: ", ret);
786                 }
787                 pwdTag.resize(kmTag.data_size);
788                 memcpy(pwdTag.data(), kmTag.data, kmTag.data_size);
789         }
790
791         LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
792 }
793
794 void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
795 {
796         // command ID = CMD_GET_DATA_SIZE
797         // TA will decrypt data with password if provided
798         // Parameters:
799         //    [1].memref  - reference to serialized buffer:
800         //        KM_BinaryData with object ID
801         // Output:
802         //    [0].value.a - return code
803         //    [0].value.b - size of buffer to be passed from CA
804         LogDebug("Object ID (passed to CMD_GET_DATA_SIZE) is (hex): " << rawToHexString(dataId));
805         KM_BinaryData kmDataId;
806         kmDataId.data_size = static_cast<uint32_t>(dataId.size());
807         kmDataId.data = const_cast<unsigned char *>(dataId.data());
808         uint32_t inMemorySize = KM_SizeOfBinaryData(&kmDataId);
809         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
810         void *inMemoryPtr = inMemory.Get()->buffer;
811         int ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &kmDataId);
812         if (ret) {
813                 ThrowErr(Exc::Crypto::InternalError, "Failed to deserialize data, ret: ", ret);
814         }
815         TEEC_Operation op;
816         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
817                                                                         TEEC_NONE, TEEC_NONE);
818
819         op.params[1].memref.parent = inMemory.Get();
820         op.params[1].memref.offset = 0;
821         op.params[1].memref.size = inMemory.Get()->size;
822         Execute(CMD_GET_DATA_SIZE, &op);
823         dataSize = op.params[0].value.b;
824 }
825
826 void TrustZoneContext::getData(const RawBuffer &dataId,
827                          const Pwd &pwd,
828                          RawBuffer &data)
829 {
830         // command ID = CMD_GET_DATA
831         // TA will decrypt data with password if provided
832         // Parameters:
833         //    [1].memref  - reference to serialized buffer:
834         //        KM_BinaryData with object ID
835         //        uint32_t boolean value - true if password is provided
836         //        KM_PwdData with password (optional)
837         // Output:
838         //    [0].value.a - return code
839         //    [2].memref  - reference to serialized buffer:
840         //        KM_BinaryData with binary data
841         LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
842         uint32_t data_size = 0;
843         GetDataSize(dataId, data_size);
844
845         KM_BinaryData kmDataId;
846         kmDataId.data_size = static_cast<uint32_t>(dataId.size());
847         kmDataId.data = const_cast<unsigned char *>(dataId.data());
848         uint32_t inMemorySize = KM_SizeOfBinaryData(&kmDataId) + KM_SizeOfFlag();
849         uint32_t pwd_flag = pwd.getPassword().empty() ? 0 : 1;
850         uint32_t pwdTagSizeBits = Params::DEFAULT_AES_GCM_TAG_LEN_BITS;
851
852         KM_PwdData kmPwdData;
853         if (pwd_flag) {
854                 memset(&kmPwdData, 0, sizeof(KM_PwdData));
855                 kmPwdData.pwd = const_cast<unsigned char *>(pwd.getPassword().data());
856                 kmPwdData.pwd_size = pwd.getPassword().size();
857                 kmPwdData.iv = const_cast<unsigned char *>(pwd.getIV().data());
858                 kmPwdData.iv_size = pwd.getIV().size();
859                 kmPwdData.tag = const_cast<unsigned char *>(pwd.getTag().data());
860                 kmPwdData.tag_size = pwd.getTag().size();
861                 kmPwdData.derive_len_bits = Params::DERIVED_KEY_LENGTH_BITS;
862                 kmPwdData.it_count = Params::DERIVED_KEY_ITERATIONS;
863                 kmPwdData.tag_len_bits = pwdTagSizeBits;
864
865                 inMemorySize += KM_SizeOfPwdData(&kmPwdData);
866         }
867
868         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
869         void *inMemoryPtr = inMemory.Get()->buffer;
870
871         int ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &kmDataId);
872         if (ret) {
873                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
874         }
875         ret = KM_SerializeFlag(&inMemoryPtr, &inMemorySize, pwd_flag);
876         if (ret) {
877                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
878         }
879         if (pwd_flag) {
880                 ret = KM_SerializePwdData(&inMemoryPtr, &inMemorySize, &kmPwdData);
881                 if (ret) {
882                         ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
883                 }
884         }
885
886         KM_BinaryData kmExtractedData;
887         memset(&kmExtractedData, 0, sizeof(KM_BinaryData));
888         kmExtractedData.data_size = data_size;
889
890         uint32_t outMemorySize = KM_SizeOfBinaryData(&kmExtractedData);
891         uint32_t outMemorySize2 = outMemorySize;
892
893         TrustZoneMemory outMemory(m_Context, outMemorySize, TEEC_MEM_OUTPUT);
894         void *outMemoryPtr = outMemory.Get()->buffer;
895         void *outMemoryPtr2 = outMemory.Get()->buffer;
896
897         // requesting size is saved in this buffer
898         ret = KM_SerializeBinaryData(&outMemoryPtr2, &outMemorySize2, &kmExtractedData);
899         if (ret) {
900                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
901         }
902
903         TEEC_Operation op;
904         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
905                                                                         TEEC_MEMREF_WHOLE, TEEC_NONE);
906         op.params[1].memref.parent = inMemory.Get();
907         op.params[1].memref.offset = 0;
908         op.params[1].memref.size = inMemory.Get()->size;
909         op.params[2].memref.parent = outMemory.Get();
910         op.params[2].memref.offset = 0;
911         op.params[2].memref.size = outMemory.Get()->size;
912
913         Execute(CMD_GET_DATA, &op);
914
915         ret = KM_DeserializeBinaryData(&outMemoryPtr, &outMemorySize, &kmExtractedData);
916         if (ret) {
917                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
918         }
919
920         data.resize(kmExtractedData.data_size);
921         memcpy(data.data(), kmExtractedData.data, kmExtractedData.data_size);
922 }
923
924
925 void TrustZoneContext::destroyData(const RawBuffer &dataId)
926 {
927         //      command ID = CMD_DESTROY_DATA
928         //  TEEC_Operation parameters layout:
929         //      input:
930         //     [1].memref  - reference to serialized buffer:
931         //         KM_BinaryData with object ID
932         //  output:
933         //     [0].value.a - return code
934         LogDebug("Object ID (passed to CMD_GET_DATA) is (hex): " << rawToHexString(dataId));
935         KM_BinaryData kmDataId;
936         kmDataId.data_size = static_cast<uint32_t>(dataId.size());
937         kmDataId.data = const_cast<unsigned char *>(dataId.data());
938         uint32_t inMemorySize = KM_SizeOfBinaryData(&kmDataId);
939         TrustZoneMemory inMemory(m_Context, inMemorySize, TEEC_MEM_INPUT);
940         void *inMemoryPtr = inMemory.Get()->buffer;
941
942         int ret = KM_SerializeBinaryData(&inMemoryPtr, &inMemorySize, &kmDataId);
943
944         if (ret) {
945                 ThrowErr(Exc::Crypto::InternalError, "Failed to serialize data, ret: ", ret);
946         }
947
948         TEEC_Operation op;
949         op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_MEMREF_WHOLE,
950                                                                         TEEC_NONE, TEEC_NONE);
951
952         op.params[1].memref.parent = inMemory.Get();
953         op.params[1].memref.offset = 0;
954         op.params[1].memref.size = inMemory.Get()->size;
955         Execute(CMD_DESTROY_DATA, &op);
956 }
957
958 void TrustZoneContext::Initialize()
959 {
960         TEEC_Operation op;
961         TEEC_Result result;
962         uint32_t retOrigin;
963
964         op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
965
966         result = TEEC_InitializeContext(nullptr, &m_Context);
967         if (result != TEEC_SUCCESS) {
968                 ThrowErr(Exc::Crypto::InternalError, "Failed to initialize TEE context: ", result);
969         }
970         m_ContextInitialized = true;
971
972         result = TEEC_OpenSession(&m_Context, &m_Session, &KEY_MANAGER_TA_UUID, 0, nullptr, &op, &retOrigin);
973         if (result != TEEC_SUCCESS) {
974                 ThrowErr(Exc::Crypto::InternalError, "Failed to open session to Key Manager TA: ", result);
975         }
976         m_SessionInitialized = true;
977 }
978
979 void TrustZoneContext::Destroy()
980 {
981         if (m_SessionInitialized) {
982                 TEEC_CloseSession(&m_Session);
983                 m_SessionInitialized = false;
984         }
985
986         if (m_ContextInitialized) {
987                 TEEC_FinalizeContext(&m_Context);
988                 m_ContextInitialized = false;
989         }
990 }
991
992 void TrustZoneContext::Reload()
993 {
994         Destroy();
995         Initialize();
996 }
997
998 void TrustZoneContext::Execute(tz_command commandID, TEEC_Operation* op)
999 {
1000         uint32_t retOrigin = 0;
1001         LogDebug("Executing TZ operation " << commandID);
1002
1003         TEEC_Result result = TEEC_InvokeCommand(&m_Session, static_cast<unsigned int>(commandID), op, &retOrigin);
1004         if (result != TEEC_SUCCESS) {
1005                 switch (result) {
1006                 case TEEC_ERROR_TARGET_DEAD:
1007                         Reload();
1008                         ThrowErr(Exc::Crypto::InternalError, "TA panicked while executing command ",
1009                                         static_cast<unsigned int>(commandID));
1010                 case TEEC_ERROR_BAD_PARAMETERS:
1011                         ThrowErr(Exc::Crypto::InputParam, "Incorrect parameters provided to TA");
1012                 default:
1013                         ThrowErr(Exc::Crypto::InternalError, "TA failed to invoke command ",
1014                                         static_cast<unsigned int>(commandID), " with error: ", std::hex,
1015                                         static_cast<unsigned int>(result), " with origin: ", std::hex,
1016                                         retOrigin);
1017                 }
1018         }
1019
1020         int ta_ret = op->params[0].value.a;
1021         if (ta_ret != KM_TA_SUCCESS) {
1022                 switch (ta_ret) {
1023                 case KM_TA_ERROR_AUTH_FAILED:
1024                         // Authentication cipher failed - notify with proper exception
1025                         ThrowErr(Exc::AuthenticationFailed, "Crypto operation authentication failed");
1026                 default:
1027                         ThrowErr(Exc::Crypto::InternalError, "Unknown TA error during operation: ", ta_ret);
1028                 }
1029         }
1030 }
1031
1032 } // namespace Internals
1033 } // namespace TZ
1034 } // namespace Crypto
1035 } // namespace CKM