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