• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
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 */
42 static const uint32_t DEVICE_ID = MC_DEVICE_ID_DEFAULT;
43 static 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  */
TEE_Open(mcSessionHandle_t * pSessionHandle)52 static 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  */
TEE_Close(mcSessionHandle_t sessionHandle)112 static 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  */
TEE_RSAGenerateKeyPair(teeRsaKeyPairType_t keyType,uint8_t * keyData,uint32_t keyDataLength,uint32_t keySize,uint32_t exponent,uint32_t * soLen)153 teeResult_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  */
TEE_RSASign(const uint8_t * keyData,const uint32_t keyDataLength,const uint8_t * plainData,const uint32_t plainDataLength,uint8_t * signatureData,uint32_t * signatureDataLength,teeRsaSigAlg_t algorithm)247 teeResult_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  */
TEE_RSAVerify(const uint8_t * keyData,const uint32_t keyDataLength,const uint8_t * plainData,const uint32_t plainDataLength,const uint8_t * signatureData,const uint32_t signatureDataLength,teeRsaSigAlg_t algorithm,bool * validity)376 teeResult_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  */
TEE_HMACKeyGenerate(uint8_t * keyData,uint32_t keyDataLength,uint32_t * soLen)502 teeResult_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  */
TEE_HMACSign(const uint8_t * keyData,const uint32_t keyDataLength,const uint8_t * plainData,const uint32_t plainDataLength,uint8_t * signatureData,uint32_t * signatureDataLength,teeDigest_t digest)588 teeResult_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  */
TEE_HMACVerify(const uint8_t * keyData,const uint32_t keyDataLength,const uint8_t * plainData,const uint32_t plainDataLength,const uint8_t * signatureData,const uint32_t signatureDataLength,teeDigest_t digest,bool * validity)715 teeResult_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  */
TEE_KeyImport(const uint8_t * keyData,const uint32_t keyDataLength,uint8_t * soData,uint32_t * soDataLength)856 teeResult_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  */
TEE_GetPubKey(const uint8_t * keyData,const uint32_t keyDataLength,uint8_t * modulus,uint32_t * modulusLength,uint8_t * exponent,uint32_t * exponentLength)959 teeResult_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 }
1068