blob: b7b862e8ca435251e30393e4413a849b04e29b46 [file] [log] [blame]
DongJin Park8eff0eb2012-08-31 18:08:58 +09001/**
2 * @file tlcTeeKeymaster_if.c
3 * @brief Contains trustlet connector interface implementations to
4 * handle key operations with TEE Keymaster trustlet
5 *
6 * Copyright Giesecke & Devrient GmbH 2012
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote
17 * products derived from this software without specific prior
18 * written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <stdlib.h>
34
35#include "MobiCoreDriverApi.h"
36#include "tlTeeKeymaster_Api.h"
37#include "tlcTeeKeymaster_log.h"
38#include "tlcTeeKeymaster_if.h"
39
40
41/* Global definitions */
42static const uint32_t DEVICE_ID = MC_DEVICE_ID_DEFAULT;
43static const mcUuid_t uuid = TEE_KEYMASTER_TL_UUID;
44
45/**
46 * TEE_Open
47 *
48 * Open session to the TEE Keymaster trustlet
49 *
50 * @param pSessionHandle [out] Return pointer to the session handle
51 */
52static tciMessage_ptr TEE_Open(
53 mcSessionHandle_t *pSessionHandle
54){
55 tciMessage_ptr pTci = NULL;
56 mcResult_t mcRet;
57
58 do
59 {
60
61 /* Validate session handle */
62 if (!pSessionHandle)
63 {
64 LOG_E("TEE_Open(): Invalid session handle\n");
65 break;
66 }
67
68 /* Initialize session handle data */
69 bzero(pSessionHandle, sizeof(mcSessionHandle_t));
70
71 /* Open MobiCore device */
72 mcRet = mcOpenDevice(DEVICE_ID);
73 if (MC_DRV_OK != mcRet)
74 {
75 LOG_E("TEE_Open(): mcOpenDevice returned: %d\n", mcRet);
76 break;
77 }
78
79 /* Allocating WSM for TCI */
80 mcRet = mcMallocWsm(DEVICE_ID, 0, sizeof(tciMessage_t), (uint8_t **) &pTci, 0);
81 if (MC_DRV_OK != mcRet)
82 {
83 LOG_E("TEE_Open(): mcMallocWsm returned: %d\n", mcRet);
84 break;
85 }
86
87 /* Open session the TEE Keymaster trustlet */
88 pSessionHandle->deviceId = DEVICE_ID;
89 mcRet = mcOpenSession(pSessionHandle,
90 &uuid,
91 (uint8_t *) pTci,
92 (uint32_t) sizeof(tciMessage_t));
93 if (MC_DRV_OK != mcRet)
94 {
95 LOG_E("TEE_Open(): mcOpenSession returned: %d\n", mcRet);
96 break;
97 }
98
99 } while (false);
100
101 return pTci;
102}
103
104
105/**
106 * TEE_Close
107 *
108 * Close session to the TEE Keymaster trustlet
109 *
110 * @param sessionHandle [in] Session handle
111 */
112static void TEE_Close(
113 mcSessionHandle_t sessionHandle
114){
115 teeResult_t ret = TEE_ERR_NONE;
116 mcResult_t mcRet;
117
118 do {
119
120 /* Close session */
121 mcRet = mcCloseSession(&sessionHandle);
122 if (MC_DRV_OK != mcRet)
123 {
124 LOG_E("TEE_Close(): mcCloseSession returned: %d\n", mcRet);
125 ret = TEE_ERR_SESSION;
126 break;
127 }
128
129 /* Close MobiCore device */
130 mcRet = mcCloseDevice(DEVICE_ID);
131 if (MC_DRV_OK != mcRet)
132 {
133 LOG_E("TEE_Close(): mcCloseDevice returned: %d\n", mcRet);
134 ret = TEE_ERR_MC_DEVICE;
135 }
136
137 } while (false);
138}
139
140
141/**
142 * TEE_RSAGenerateKeyPair
143 *
144 * Generates RSA key pair and returns key pair data as wrapped object
145 *
146 * @param keyType [in] Key pair type. RSA or RSACRT
147 * @param keyData [in] Pointer to the key data buffer
148 * @param keyDataLength [in] Key data buffer length
149 * @param keySize [in] Key size
150 * @param exponent [in] Exponent number
151 * @param soLen [out] Key data secure object length
152 */
153teeResult_t TEE_RSAGenerateKeyPair(
154 teeRsaKeyPairType_t keyType,
155 uint8_t* keyData,
156 uint32_t keyDataLength,
157 uint32_t keySize,
158 uint32_t exponent,
159 uint32_t* soLen
160){
161 teeResult_t ret = TEE_ERR_NONE;
162 tciMessage_ptr pTci = NULL;
163 mcSessionHandle_t sessionHandle;
164 mcBulkMap_t mapInfo;
165 mcResult_t mcRet;
166
167 do {
168
169 /* Open session to the trustlet */
170 pTci = TEE_Open(&sessionHandle);
171 if (!pTci) {
172 ret = TEE_ERR_MEMORY;
173 break;
174 }
175
176 /* Map memory to the secure world */
177 mcRet = mcMap(&sessionHandle, keyData, keyDataLength, &mapInfo);
178 if (MC_DRV_OK != mcRet) {
179 ret = TEE_ERR_MAP;
180 break;
181 }
182
183 /* Update TCI buffer */
184 pTci->command.header.commandId = CMD_ID_TEE_RSA_GEN_KEY_PAIR;
185 pTci->rsagenkey.type = keyType;
186 pTci->rsagenkey.keysize = keySize;
187 pTci->rsagenkey.keydata = (uint32_t)mapInfo.sVirtualAddr;
188 pTci->rsagenkey.keydatalen = keyDataLength;
189 pTci->rsagenkey.exponent = exponent;
190
191 /* Notify the trustlet */
192 mcRet = mcNotify(&sessionHandle);
193 if (MC_DRV_OK != mcRet)
194 {
195 ret = TEE_ERR_NOTIFICATION;
196 break;
197 }
198
199 /* Wait for response from the trustlet */
200 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
201 {
202 ret = TEE_ERR_NOTIFICATION;
203 break;
204 }
205
206 /* Unmap memory */
207 mcRet = mcUnmap(&sessionHandle, keyData, &mapInfo);
208 if (MC_DRV_OK != mcRet)
209 {
210 ret = TEE_ERR_MAP;
211 break;
212 }
213
214 if (RET_OK != pTci->response.header.returnCode)
215 {
216 LOG_E("TEE_RSAGenerateKeyPair(): TEE Keymaster trustlet returned: 0x%.8x\n",
217 pTci->response.header.returnCode);
218 ret = TEE_ERR_FAIL;
219 break;
220 }
221
222 /* Update secure object length */
223 *soLen = pTci->rsagenkey.solen;
224
225 } while (false);
226
227 /* Close session to the trustlet */
228 TEE_Close(sessionHandle);
229
230 return ret;
231}
232
233
234/**
235 * TEE_RSASign
236 *
237 * Signs given plain data and returns signature data
238 *
239 * @param keyData [in] Pointer to key data buffer
240 * @param keyDataLength [in] Key data buffer length
241 * @param plainData [in] Pointer to plain data to be signed
242 * @param plainDataLength [in] Plain data length
243 * @param signatureData [out] Pointer to signature data
244 * @param signatureDataLength [out] Signature data length
245 * @param algorithm [in] RSA signature algorithm
246 */
247teeResult_t TEE_RSASign(
248 const uint8_t* keyData,
249 const uint32_t keyDataLength,
250 const uint8_t* plainData,
251 const uint32_t plainDataLength,
252 uint8_t* signatureData,
253 uint32_t* signatureDataLength,
254 teeRsaSigAlg_t algorithm
255){
256 teeResult_t ret = TEE_ERR_NONE;
257 tciMessage_ptr pTci = NULL;
258 mcSessionHandle_t sessionHandle;
259 mcBulkMap_t keyMapInfo;
260 mcBulkMap_t plainMapInfo;
261 mcBulkMap_t signatureMapInfo;
262 mcResult_t mcRet;
263
264 do {
265
266 /* Open session to the trustlet */
267 pTci = TEE_Open(&sessionHandle);
268 if (!pTci) {
269 ret = TEE_ERR_MEMORY;
270 break;
271 }
272
273 /* Map memory to the secure world */
274 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo);
275 if (MC_DRV_OK != mcRet) {
276 ret = TEE_ERR_MAP;
277 break;
278 }
279
280 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo);
281 if (MC_DRV_OK != mcRet) {
282 ret = TEE_ERR_MAP;
283 break;
284 }
285
286 mcRet = mcMap(&sessionHandle, (void*)signatureData, *signatureDataLength, &signatureMapInfo);
287 if (MC_DRV_OK != mcRet) {
288 ret = TEE_ERR_MAP;
289 break;
290 }
291
292 /* Update TCI buffer */
293 pTci->command.header.commandId = CMD_ID_TEE_RSA_SIGN;
294 pTci->rsasign.keydata = (uint32_t)keyMapInfo.sVirtualAddr;
295 pTci->rsasign.keydatalen = keyDataLength;
296
297 pTci->rsasign.plaindata = (uint32_t)plainMapInfo.sVirtualAddr;
298 pTci->rsasign.plaindatalen = plainDataLength;
299
300 pTci->rsasign.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr;
301 pTci->rsasign.signaturedatalen = *signatureDataLength;
302
303 pTci->rsasign.algorithm = algorithm;
304
305 /* Notify the trustlet */
306 mcRet = mcNotify(&sessionHandle);
307 if (MC_DRV_OK != mcRet)
308 {
309 ret = TEE_ERR_NOTIFICATION;
310 break;
311 }
312
313 /* Wait for response from the trustlet */
314 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
315 {
316 ret = TEE_ERR_NOTIFICATION;
317 break;
318 }
319
320 /* Unmap memory */
321 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo);
322 if (MC_DRV_OK != mcRet)
323 {
324 ret = TEE_ERR_MAP;
325 break;
326 }
327
328 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo);
329 if (MC_DRV_OK != mcRet)
330 {
331 ret = TEE_ERR_MAP;
332 break;
333 }
334
335 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo);
336 if (MC_DRV_OK != mcRet)
337 {
338 ret = TEE_ERR_MAP;
339 break;
340 }
341
342 if (RET_OK != pTci->response.header.returnCode)
343 {
344 LOG_E("TEE_RSASign(): TEE Keymaster trustlet returned: 0x%.8x\n",
345 pTci->response.header.returnCode);
346 ret = TEE_ERR_FAIL;
347 break;
348 }
349
350 /* Retrieve signature data length */
351 *signatureDataLength = pTci->rsasign.signaturedatalen;
352
353 } while (false);
354
355 /* Close session to the trustlet */
356 TEE_Close(sessionHandle);
357
358 return ret;
359}
360
361
362/**
363 * TEE_RSAVerify
364 *
365 * Verifies given data with RSA public key and return status
366 *
367 * @param keyData [in] Pointer to key data buffer
368 * @param keyDataLength [in] Key data buffer length
369 * @param plainData [in] Pointer to plain data to be signed
370 * @param plainDataLength [in] Plain data length
371 * @param signatureData [in] Pointer to signed data
372 * @param signatureData [in] Plain data length
373 * @param algorithm [in] RSA signature algorithm
374 * @param validity [out] Signature validity
375 */
376teeResult_t TEE_RSAVerify(
377 const uint8_t* keyData,
378 const uint32_t keyDataLength,
379 const uint8_t* plainData,
380 const uint32_t plainDataLength,
381 const uint8_t* signatureData,
382 const uint32_t signatureDataLength,
383 teeRsaSigAlg_t algorithm,
384 bool *validity
385){
386 teeResult_t ret = TEE_ERR_NONE;
387 tciMessage_ptr pTci = NULL;
388 mcSessionHandle_t sessionHandle;
389 mcBulkMap_t keyMapInfo;
390 mcBulkMap_t plainMapInfo;
391 mcBulkMap_t signatureMapInfo;
392 mcResult_t mcRet;
393
394 do {
395
396 /* Open session to the trustlet */
397 pTci = TEE_Open(&sessionHandle);
398 if (!pTci) {
399 ret = TEE_ERR_MEMORY;
400 break;
401 }
402
403 /* Map memory to the secure world */
404 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo);
405 if (MC_DRV_OK != mcRet) {
406 ret = TEE_ERR_MAP;
407 break;
408 }
409
410 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo);
411 if (MC_DRV_OK != mcRet) {
412 ret = TEE_ERR_MAP;
413 break;
414 }
415
416 mcRet = mcMap(&sessionHandle, (void*)signatureData, signatureDataLength, &signatureMapInfo);
417 if (MC_DRV_OK != mcRet) {
418 ret = TEE_ERR_MAP;
419 break;
420 }
421
422 /* Update TCI buffer */
423 pTci->command.header.commandId = CMD_ID_TEE_RSA_VERIFY;
424 pTci->rsaverify.keydata = (uint32_t)keyMapInfo.sVirtualAddr;
425 pTci->rsaverify.keydatalen = keyDataLength;
426
427 pTci->rsaverify.plaindata = (uint32_t)plainMapInfo.sVirtualAddr;
428 pTci->rsaverify.plaindatalen = plainDataLength;
429
430 pTci->rsaverify.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr;
431 pTci->rsaverify.signaturedatalen = signatureDataLength;
432
433 pTci->rsaverify.algorithm = algorithm;
434 pTci->rsaverify.validity = false;
435
436 /* Notify the trustlet */
437 mcRet = mcNotify(&sessionHandle);
438 if (MC_DRV_OK != mcRet)
439 {
440 ret = TEE_ERR_NOTIFICATION;
441 break;
442 }
443
444 /* Wait for response from the trustlet */
445 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
446 {
447 ret = TEE_ERR_NOTIFICATION;
448 break;
449 }
450
451 /* Unmap memory */
452 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo);
453 if (MC_DRV_OK != mcRet)
454 {
455 ret = TEE_ERR_MAP;
456 break;
457 }
458
459 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo);
460 if (MC_DRV_OK != mcRet)
461 {
462 ret = TEE_ERR_MAP;
463 break;
464 }
465
466 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo);
467 if (MC_DRV_OK != mcRet)
468 {
469 ret = TEE_ERR_MAP;
470 break;
471 }
472
473 if (RET_OK != pTci->response.header.returnCode)
474 {
475 LOG_E("TEE_RSAVerify(): TEE Keymaster trustlet returned: 0x%.8x\n",
476 pTci->response.header.returnCode);
477 ret = TEE_ERR_FAIL;
478 break;
479 }
480
481 *validity = pTci->rsaverify.validity;
482
483 } while (false);
484
485 /* Close session to the trustlet */
486 TEE_Close(sessionHandle);
487
488 return ret;
489}
490
491
492/**
493 * TEE_HMACKeyGenerate
494 *
495 * Generates random key for HMAC calculation and returns key data as wrapped object
496 * (key is encrypted)
497 *
498 * @param keyData [out] Pointer to key data
499 * @param keyDataLength [in] Key data buffer length
500 * @param soLen [out] Key data secure object length
501 */
502teeResult_t TEE_HMACKeyGenerate(
503 uint8_t* keyData,
504 uint32_t keyDataLength,
505 uint32_t* soLen
506){
507 teeResult_t ret = TEE_ERR_NONE;
508 tciMessage_ptr pTci = NULL;
509 mcSessionHandle_t sessionHandle;
510 mcBulkMap_t keyMapInfo;
511 mcResult_t mcRet;
512
513 do {
514
515 /* Open session to the trustlet */
516 pTci = TEE_Open(&sessionHandle);
517 if (!pTci) {
518 ret = TEE_ERR_MEMORY;
519 break;
520 }
521
522 /* Map memory to the secure world */
523 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo);
524 if (MC_DRV_OK != mcRet) {
525 ret = TEE_ERR_MAP;
526 break;
527 }
528
529 /* Update TCI buffer */
530 pTci->command.header.commandId = CMD_ID_TEE_HMAC_GEN_KEY;
531 pTci->hmacgenkey.keydata = (uint32_t)keyMapInfo.sVirtualAddr;
532 pTci->hmacgenkey.keydatalen = keyDataLength;
533
534 /* Notify the trustlet */
535 mcRet = mcNotify(&sessionHandle);
536 if (MC_DRV_OK != mcRet)
537 {
538 ret = TEE_ERR_NOTIFICATION;
539 break;
540 }
541
542 /* Wait for response from the trustlet */
543 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
544 {
545 ret = TEE_ERR_NOTIFICATION;
546 break;
547 }
548
549 /* Unmap memory */
550 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo);
551 if (MC_DRV_OK != mcRet)
552 {
553 ret = TEE_ERR_MAP;
554 break;
555 }
556
557 if (RET_OK != pTci->response.header.returnCode)
558 {
559 LOG_E("TEE_RSAVerify(): TEE Keymaster trustlet returned: 0x%.8x\n",
560 pTci->response.header.returnCode);
561 ret = TEE_ERR_FAIL;
562 }
563
564 /* Update secure object length */
565 *soLen = pTci->hmacgenkey.solen;
566
567 }while (false);
568
569 /* Close session to the trustlet */
570 TEE_Close(sessionHandle);
571
572 return ret;
573}
574
575/**
576 * TEE_HMACSign
577 *
578 * Signs given plain data and returns HMAC signature data
579 *
580 * @param keyData [in] Pointer to key data buffer
581 * @param keyDataLength [in] Key data buffer length
582 * @param plainData [in] Pointer to plain data to be signed
583 * @param plainDataLength [in] Plain data length
584 * @param signatureData [out] Pointer to signature data
585 * @param signatureDataLength [out] Signature data length
586 * @param digest [in] Digest type
587 */
588teeResult_t TEE_HMACSign(
589 const uint8_t* keyData,
590 const uint32_t keyDataLength,
591 const uint8_t* plainData,
592 const uint32_t plainDataLength,
593 uint8_t* signatureData,
594 uint32_t* signatureDataLength,
595 teeDigest_t digest
596){
597 teeResult_t ret = TEE_ERR_NONE;
598 tciMessage_ptr pTci = NULL;
599 mcSessionHandle_t sessionHandle;
600 mcBulkMap_t keyMapInfo;
601 mcBulkMap_t plainMapInfo;
602 mcBulkMap_t signatureMapInfo;
603 mcResult_t mcRet;
604
605 do {
606
607 /* Open session to the trustlet */
608 pTci = TEE_Open(&sessionHandle);
609 if (!pTci) {
610 ret = TEE_ERR_MEMORY;
611 break;
612 }
613
614 /* Map memory to the secure world */
615 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo);
616 if (MC_DRV_OK != mcRet) {
617 ret = TEE_ERR_MAP;
618 break;
619 }
620
621 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo);
622 if (MC_DRV_OK != mcRet) {
623 ret = TEE_ERR_MAP;
624 break;
625 }
626
627 mcRet = mcMap(&sessionHandle, (void*)signatureData, *signatureDataLength, &signatureMapInfo);
628 if (MC_DRV_OK != mcRet) {
629 ret = TEE_ERR_MAP;
630 break;
631 }
632
633 /* Update TCI buffer */
634 pTci->command.header.commandId = CMD_ID_TEE_HMAC_SIGN;
635 pTci->hmacsign.keydata = (uint32_t)keyMapInfo.sVirtualAddr;
636 pTci->hmacsign.keydatalen = keyDataLength;
637
638 pTci->hmacsign.plaindata = (uint32_t)plainMapInfo.sVirtualAddr;
639 pTci->hmacsign.plaindatalen = plainDataLength;
640
641 pTci->hmacsign.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr;
642 pTci->hmacsign.signaturedatalen = *signatureDataLength;
643
644 pTci->hmacsign.digest = digest;
645
646 /* Notify the trustlet */
647 mcRet = mcNotify(&sessionHandle);
648 if (MC_DRV_OK != mcRet)
649 {
650 ret = TEE_ERR_NOTIFICATION;
651 break;
652 }
653
654 /* Wait for response from the trustlet */
655 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
656 {
657 ret = TEE_ERR_NOTIFICATION;
658 break;
659 }
660
661 /* Unmap memory */
662 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo);
663 if (MC_DRV_OK != mcRet)
664 {
665 ret = TEE_ERR_MAP;
666 break;
667 }
668
669 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo);
670 if (MC_DRV_OK != mcRet)
671 {
672 ret = TEE_ERR_MAP;
673 break;
674 }
675
676 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo);
677 if (MC_DRV_OK != mcRet)
678 {
679 ret = TEE_ERR_MAP;
680 break;
681 }
682
683 if (RET_OK != pTci->response.header.returnCode)
684 {
685 LOG_E("TEE_HMACSign(): TEE Keymaster trustlet returned: 0x%.8x\n",
686 pTci->response.header.returnCode);
687 ret = TEE_ERR_FAIL;
688 break;
689 }
690
691 /* Retrieve signature data length */
692 *signatureDataLength = pTci->hmacsign.signaturedatalen;
693
694 } while (false);
695
696 /* Close session to the trustlet */
697 TEE_Close(sessionHandle);
698
699 return ret;
700}
701
702
703/**
704 * TEE_HMACVerify
705 *
706 * Verifies given data HMAC key data and return status
707 *
708 * @param plainData [in] Pointer to plain data to be signed
709 * @param plainDataLength [in] Plain data length
710 * @param signatureData [in] Pointer to signed data
711 * @param signatureData [in] Plain data length
712 * @param digest [in] Digest type
713 * @param validity [out] Signature validity
714 */
715teeResult_t TEE_HMACVerify(
716 const uint8_t* keyData,
717 const uint32_t keyDataLength,
718 const uint8_t* plainData,
719 const uint32_t plainDataLength,
720 const uint8_t* signatureData,
721 const uint32_t signatureDataLength,
722 teeDigest_t digest,
723 bool *validity
724){
725 teeResult_t ret = TEE_ERR_NONE;
726 tciMessage_ptr pTci = NULL;
727 mcSessionHandle_t sessionHandle;
728 mcBulkMap_t keyMapInfo;
729 mcBulkMap_t plainMapInfo;
730 mcBulkMap_t signatureMapInfo;
731 mcResult_t mcRet;
732
733 do {
734
735 /* Open session to the trustlet */
736 pTci = TEE_Open(&sessionHandle);
737 if (!pTci) {
738 ret = TEE_ERR_MEMORY;
739 break;
740 }
741
742 /* Map memory to the secure world */
743 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo);
744 if (MC_DRV_OK != mcRet) {
745 ret = TEE_ERR_MAP;
746 break;
747 }
748
749 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo);
750 if (MC_DRV_OK != mcRet) {
751 ret = TEE_ERR_MAP;
752 break;
753 }
754
755 mcRet = mcMap(&sessionHandle, (void*)signatureData, signatureDataLength, &signatureMapInfo);
756 if (MC_DRV_OK != mcRet) {
757 ret = TEE_ERR_MAP;
758 break;
759 }
760
761 /* Update TCI buffer */
762 pTci->command.header.commandId = CMD_ID_TEE_HMAC_VERIFY;
763 pTci->hmacverify.keydata = (uint32_t)keyMapInfo.sVirtualAddr;
764 pTci->hmacverify.keydatalen = keyDataLength;
765
766 pTci->hmacverify.plaindata = (uint32_t)plainMapInfo.sVirtualAddr;
767 pTci->hmacverify.plaindatalen = plainDataLength;
768
769 pTci->hmacverify.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr;
770 pTci->hmacverify.signaturedatalen = signatureDataLength;
771
772 pTci->hmacverify.digest = digest;
773 pTci->hmacverify.validity = false;
774
775 /* Notify the trustlet */
776 mcRet = mcNotify(&sessionHandle);
777 if (MC_DRV_OK != mcRet)
778 {
779 ret = TEE_ERR_NOTIFICATION;
780 break;
781 }
782
783 /* Wait for response from the trustlet */
784 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
785 {
786 ret = TEE_ERR_NOTIFICATION;
787 break;
788 }
789
790 /* Unmap memory */
791 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo);
792 if (MC_DRV_OK != mcRet)
793 {
794 ret = TEE_ERR_MAP;
795 break;
796 }
797
798 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo);
799 if (MC_DRV_OK != mcRet)
800 {
801 ret = TEE_ERR_MAP;
802 break;
803 }
804
805 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo);
806 if (MC_DRV_OK != mcRet)
807 {
808 ret = TEE_ERR_MAP;
809 break;
810 }
811
812 if (RET_OK != pTci->response.header.returnCode)
813 {
814 LOG_E("TEE_HMACVerify(): TEE Keymaster trustlet returned: 0x%.8x\n",
815 pTci->response.header.returnCode);
816 ret = TEE_ERR_FAIL;
817 break;
818 }
819
820 *validity = pTci->hmacverify.validity;
821
822 } while (false);
823
824 /* Close session to the trustlet */
825 TEE_Close(sessionHandle);
826
827 return ret;
828}
829
830
831/**
832 * TEE_KeyImport
833 *
834 * Imports key data and returns key data as secure object
835 *
836 * Key data needs to be in the following format
837 *
838 * RSA key data:
839 * |--key metadata--|--public modulus--|--public exponent--|--private exponent--|
840 *
841 * RSA CRT key data:
842 * |--key metadata--|--public modulus--|--public exponent--|--P--|--Q--|--DP--|--DQ--|--Qinv--|
843 *
844 * Where:
845 * P: secret prime factor
846 * Q: secret prime factor
847 * DP: d mod (p-1)
848 * DQ: d mod (q-1)
849 * Qinv: q^-1 mod p
850 *
851 * @param keyData [in] Pointer to key data
852 * @param keyDataLength [in] Key data length
853 * @param soData [out] Pointer to wrapped key data
854 * @param soDataLength [out] Wrapped key data length
855 */
856teeResult_t TEE_KeyImport(
857 const uint8_t* keyData,
858 const uint32_t keyDataLength,
859 uint8_t* soData,
860 uint32_t* soDataLength
861){
862 teeResult_t ret = TEE_ERR_NONE;
863 tciMessage_ptr pTci = NULL;
864 mcSessionHandle_t sessionHandle;
865 mcBulkMap_t keyMapInfo;
866 mcBulkMap_t soMapInfo;
867 mcResult_t mcRet;
868
869 do {
870
871 /* Open session to the trustlet */
872 pTci = TEE_Open(&sessionHandle);
873 if (!pTci) {
874 ret = TEE_ERR_MEMORY;
875 break;
876 }
877
878 /* Map memory to the secure world */
879 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo);
880 if (MC_DRV_OK != mcRet) {
881 ret = TEE_ERR_MAP;
882 break;
883 }
884
885 mcRet = mcMap(&sessionHandle, (void*)soData, *soDataLength, &soMapInfo);
886 if (MC_DRV_OK != mcRet) {
887 ret = TEE_ERR_MAP;
888 break;
889 }
890
891 /* Update TCI buffer */
892 pTci->command.header.commandId = CMD_ID_TEE_KEY_IMPORT;
893 pTci->keyimport.keydata = (uint32_t)keyMapInfo.sVirtualAddr;
894 pTci->keyimport.keydatalen = keyDataLength;
895 pTci->keyimport.sodata = (uint32_t)soMapInfo.sVirtualAddr;
896 pTci->keyimport.sodatalen = *soDataLength;
897
898 /* Notify the trustlet */
899 mcRet = mcNotify(&sessionHandle);
900 if (MC_DRV_OK != mcRet)
901 {
902 ret = TEE_ERR_NOTIFICATION;
903 break;
904 }
905
906 /* Wait for response from the trustlet */
907 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
908 {
909 ret = TEE_ERR_NOTIFICATION;
910 break;
911 }
912
913 /* Unmap memory */
914 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo);
915 if (MC_DRV_OK != mcRet)
916 {
917 ret = TEE_ERR_MAP;
918 break;
919 }
920
921 mcRet = mcUnmap(&sessionHandle, (void*)soData, &soMapInfo);
922 if (MC_DRV_OK != mcRet)
923 {
924 ret = TEE_ERR_MAP;
925 break;
926 }
927
928 if (RET_OK != pTci->response.header.returnCode)
929 {
930 LOG_E("TEE_KeyWrap(): TEE Keymaster trustlet returned: 0x%.8x\n",
931 pTci->response.header.returnCode);
932 ret = TEE_ERR_FAIL;
933 break;
934 }
935
936 /* Update secure object length */
937 *soDataLength = pTci->keyimport.sodatalen;
938
939 } while (false);
940
941 /* Close session to the trustlet */
942 TEE_Close(sessionHandle);
943
944 return ret;
945}
946
947
948/** * TEE_GetPubKey
949 *
950 * Retrieves public key daya (modulus and exponent) from wrapped key data
951 *
952 * @param keyData [in] Pointer to key data
953 * @param keyDataLength [in] Key data length
954 * @param modulus [out] Pointer to public key modulus data
955 * @param modulusLength [out] Modulus data length
956 * @param exponent [out] Pointer to public key exponent data
957 * @param exponentLength [out] Exponent data length
958 */
959teeResult_t TEE_GetPubKey(
960 const uint8_t* keyData,
961 const uint32_t keyDataLength,
962 uint8_t* modulus,
963 uint32_t* modulusLength,
964 uint8_t* exponent,
965 uint32_t* exponentLength
966){
967 teeResult_t ret = TEE_ERR_NONE;
968 tciMessage_ptr pTci = NULL;
969 mcSessionHandle_t sessionHandle;
970 mcBulkMap_t keyMapInfo;
971 mcBulkMap_t modMapInfo;
972 mcBulkMap_t expMapInfo;
973 mcResult_t mcRet;
974
975 do {
976
977 /* Open session to the trustlet */
978 pTci = TEE_Open(&sessionHandle);
979 if (!pTci) {
980 ret = TEE_ERR_MEMORY;
981 break;
982 }
983
984 /* Map memory to the secure world */
985 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo);
986 if (MC_DRV_OK != mcRet) {
987 ret = TEE_ERR_MAP;
988 break;
989 }
990
991 mcRet = mcMap(&sessionHandle, (void*)modulus, *modulusLength, &modMapInfo);
992 if (MC_DRV_OK != mcRet) {
993 ret = TEE_ERR_MAP;
994 break;
995 }
996
997 mcRet = mcMap(&sessionHandle, (void*)exponent, *exponentLength, &expMapInfo);
998 if (MC_DRV_OK != mcRet) {
999 ret = TEE_ERR_MAP;
1000 break;
1001 }
1002
1003 /* Update TCI buffer */
1004 pTci->command.header.commandId = CMD_ID_TEE_GET_PUB_KEY;
1005 pTci->getpubkey.keydata = (uint32_t)keyMapInfo.sVirtualAddr;
1006 pTci->getpubkey.keydatalen = keyDataLength;
1007 pTci->getpubkey.modulus = (uint32_t)modMapInfo.sVirtualAddr;
1008 pTci->getpubkey.moduluslen = *modulusLength;
1009 pTci->getpubkey.exponent = (uint32_t)expMapInfo.sVirtualAddr;
1010 pTci->getpubkey.exponentlen = *exponentLength;
1011
1012 /* Notify the trustlet */
1013 mcRet = mcNotify(&sessionHandle);
1014 if (MC_DRV_OK != mcRet)
1015 {
1016 ret = TEE_ERR_NOTIFICATION;
1017 break;
1018 }
1019
1020 /* Wait for response from the trustlet */
1021 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT))
1022 {
1023 ret = TEE_ERR_NOTIFICATION;
1024 break;
1025 }
1026
1027 /* Unmap memory */
1028 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo);
1029 if (MC_DRV_OK != mcRet)
1030 {
1031 ret = TEE_ERR_MAP;
1032 break;
1033 }
1034
1035 mcRet = mcUnmap(&sessionHandle, (void*)modulus, &modMapInfo);
1036 if (MC_DRV_OK != mcRet)
1037 {
1038 ret = TEE_ERR_MAP;
1039 break;
1040 }
1041
1042 mcRet = mcUnmap(&sessionHandle, (void*)exponent, &expMapInfo);
1043 if (MC_DRV_OK != mcRet)
1044 {
1045 ret = TEE_ERR_MAP;
1046 break;
1047 }
1048
1049 if (RET_OK != pTci->response.header.returnCode)
1050 {
1051 LOG_E("TEE_GetPubKey(): TEE Keymaster trustlet returned: 0x%.8x\n",
1052 pTci->response.header.returnCode);
1053 ret = TEE_ERR_FAIL;
1054 break;
1055 }
1056
1057 /* Update modulus and exponent lengths */
1058 *modulusLength = pTci->getpubkey.moduluslen;
1059 *exponentLength = pTci->getpubkey.exponentlen;
1060
1061 } while (false);
1062
1063 /* Close session to the trustlet */
1064 TEE_Close(sessionHandle);
1065
1066 return ret;
1067}