Home | History | Annotate | Download | only in libkeymaster
      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  */
     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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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