Home | History | Annotate | Download | only in tf_crypto_sst
      1 /**
      2  * Copyright(c) 2011 Trusted Logic.   All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *  * Neither the name Trusted Logic nor the names of its
     15  *    contributors may be used to endorse or promote products derived
     16  *    from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include <assert.h>
     32 #include <stdlib.h>
     33 #include <string.h>
     34 
     35 #define MTC_EXPORTS
     36 #include "mtc.h"
     37 
     38 /* Included for the TEE management */
     39 #include "pkcs11_internal.h"
     40 
     41 
     42 /*------------------------------------------------------------------------------
     43    Defines
     44 ------------------------------------------------------------------------------*/
     45 
     46 /**
     47  * The magic word.
     48  */
     49 #define MTC_SESSION_MAGIC  ( (uint32_t)0x4D544300 )   /* "MTC\0" */
     50 
     51 /**
     52  * The MTC session context
     53  */
     54 typedef struct
     55 {
     56    /* Magic word, must be set to {MTC_SESSION_MAGIC}. */
     57    uint32_t    nMagicWord;
     58 
     59    /* MTC Identifier */
     60    uint32_t nCounterIdentifier;
     61 
     62    /* TEEC session and cryptoki session */
     63    TEEC_Session sSession;
     64    uint32_t     hCryptoSession;
     65 
     66 } MTC_SESSION_CONTEXT;
     67 
     68 
     69 static bool g_bMTCInitialized = false;
     70 
     71 
     72 /*------------------------------------------------------------------------------
     73    Static functions
     74 ------------------------------------------------------------------------------*/
     75 
     76 static S_RESULT static_getMonotonicCounter(S_HANDLE hCounter,
     77                                            S_MONOTONIC_COUNTER_VALUE* psValue,
     78                                            bool bIncrement)
     79 {
     80    TEEC_Result          nError;
     81    TEEC_Operation       sOperation;
     82    MTC_SESSION_CONTEXT* pSession = NULL;
     83    uint32_t             nCommandID;
     84 
     85    if (!g_bMTCInitialized)
     86    {
     87       return S_ERROR_BAD_STATE;
     88    }
     89 
     90    pSession = (MTC_SESSION_CONTEXT *)hCounter;
     91    if ((pSession == NULL) || (pSession->nMagicWord != MTC_SESSION_MAGIC))
     92    {
     93       return S_ERROR_BAD_PARAMETERS;
     94    }
     95 
     96    if (bIncrement)
     97    {
     98       nCommandID = SERVICE_SYSTEM_PKCS11_INCREMENT_MTC_COMMAND_ID;
     99    }
    100    else
    101    {
    102       nCommandID = SERVICE_SYSTEM_PKCS11_GET_MTC_COMMAND_ID;
    103    }
    104 
    105    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
    106    sOperation.params[0].value.a = pSession->nCounterIdentifier;
    107    sOperation.params[0].value.b = 0;
    108    nError = TEEC_InvokeCommand(&pSession->sSession,
    109                             (pSession->hCryptoSession << 16 ) |
    110                               (nCommandID & 0x00007FFF),
    111                             &sOperation,
    112                             NULL);
    113 
    114    psValue->nLow  = sOperation.params[0].value.a;
    115    psValue->nHigh = sOperation.params[0].value.b;
    116 
    117    return nError;
    118 }
    119 
    120 /*------------------------------------------------------------------------------
    121    API
    122 ------------------------------------------------------------------------------*/
    123 
    124 MTC_EXPORT S_RESULT SMonotonicCounterInit(void)
    125 {
    126    TEEC_Result nTeeError;
    127 
    128    stubMutexLock();
    129    if (g_bMTCInitialized)
    130    {
    131       nTeeError = TEEC_SUCCESS;
    132    }
    133    else
    134    {
    135       nTeeError = stubInitializeContext();
    136       if (nTeeError == TEEC_SUCCESS)
    137       {
    138          g_bMTCInitialized = true;
    139       }
    140    }
    141    stubMutexUnlock();
    142 
    143    return nTeeError;
    144 }
    145 
    146 MTC_EXPORT void SMonotonicCounterTerminate(void)
    147 {
    148    stubMutexLock();
    149    if (g_bMTCInitialized)
    150    {
    151       stubFinalizeContext();
    152       g_bMTCInitialized = false;
    153    }
    154    stubMutexUnlock();
    155 }
    156 
    157 MTC_EXPORT S_RESULT SMonotonicCounterOpen(
    158                  uint32_t nCounterIdentifier,
    159                  OUT S_HANDLE* phCounter)
    160 {
    161    TEEC_Result                nError;
    162    TEEC_Operation             sOperation;
    163    MTC_SESSION_CONTEXT*       pSession = NULL;
    164    S_MONOTONIC_COUNTER_VALUE  nCounterValue;
    165 
    166    if (phCounter == NULL)
    167    {
    168       return S_ERROR_BAD_PARAMETERS;
    169    }
    170 
    171    *phCounter = S_HANDLE_NULL;
    172 
    173    if (!g_bMTCInitialized)
    174    {
    175       return S_ERROR_BAD_STATE;
    176    }
    177 
    178    if (nCounterIdentifier != S_MONOTONIC_COUNTER_GLOBAL)
    179    {
    180       return S_ERROR_ITEM_NOT_FOUND;
    181    }
    182 
    183    pSession = (MTC_SESSION_CONTEXT*)malloc(sizeof(MTC_SESSION_CONTEXT));
    184    if (pSession == NULL)
    185    {
    186       return S_ERROR_OUT_OF_MEMORY;
    187    }
    188    memset(pSession, 0, sizeof(MTC_SESSION_CONTEXT));
    189    pSession->nMagicWord = MTC_SESSION_MAGIC;
    190 
    191    /* Open a TEE session with the system service */
    192    nError = TEEC_OpenSession(&g_sContext,
    193                              &pSession->sSession,
    194                              &SERVICE_UUID,
    195                              TEEC_LOGIN_PUBLIC,
    196                              NULL,
    197                              NULL, /* No operation parameters */
    198                              NULL);
    199    if (nError != TEEC_SUCCESS)
    200    {
    201       goto error;
    202    }
    203 
    204    /* Open a cryptoki session */
    205    sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
    206    sOperation.params[0].value.a = CKV_TOKEN_SYSTEM_SHARED;
    207    sOperation.params[0].value.b = CKF_RW_SESSION | CKF_SERIAL_SESSION;
    208    nError = TEEC_InvokeCommand(&pSession->sSession,
    209                                SERVICE_SYSTEM_PKCS11_C_OPEN_SESSION_COMMAND_ID & 0x00007FFF,
    210                                &sOperation,
    211                                NULL);
    212    if (nError != TEEC_SUCCESS)
    213    {
    214       TEEC_CloseSession(&pSession->sSession);
    215       goto error;
    216    }
    217 
    218    pSession->hCryptoSession = sOperation.params[0].value.a;
    219    pSession->nCounterIdentifier = nCounterIdentifier;
    220 
    221    nError = SMonotonicCounterGet((S_HANDLE)pSession, &nCounterValue);
    222    if (nError != TEEC_SUCCESS)
    223    {
    224       SMonotonicCounterClose((S_HANDLE)pSession);
    225       return nError;
    226    }
    227 
    228    *phCounter = (S_HANDLE)pSession;
    229 
    230    return TEEC_SUCCESS;
    231 
    232 error:
    233    free(pSession);
    234    return nError;
    235 }
    236 
    237 MTC_EXPORT void SMonotonicCounterClose(S_HANDLE hCounter)
    238 {
    239    MTC_SESSION_CONTEXT* pSession;
    240 
    241    if (!g_bMTCInitialized)
    242    {
    243       return;
    244    }
    245 
    246    pSession = (MTC_SESSION_CONTEXT *)hCounter;
    247    if ((pSession == NULL) || (pSession->nMagicWord != MTC_SESSION_MAGIC))
    248    {
    249       return;
    250    }
    251 
    252    (void)TEEC_InvokeCommand(&pSession->sSession,
    253                             (pSession->hCryptoSession << 16 ) |
    254                               (SERVICE_SYSTEM_PKCS11_C_CLOSE_SESSION_COMMAND_ID & 0x00007FFF),
    255                             NULL, /* No operation parameters */
    256                             NULL);
    257 
    258    TEEC_CloseSession(&pSession->sSession);
    259    free(pSession);
    260 }
    261 
    262 MTC_EXPORT S_RESULT SMonotonicCounterGet(
    263                  S_HANDLE hCounter,
    264                  S_MONOTONIC_COUNTER_VALUE* psCurrentValue)
    265 {
    266    return static_getMonotonicCounter(hCounter, psCurrentValue, false);
    267 }
    268 
    269 MTC_EXPORT S_RESULT SMonotonicCounterIncrement(
    270                  S_HANDLE hCounter,
    271                  S_MONOTONIC_COUNTER_VALUE* psNewValue)
    272 {
    273    return static_getMonotonicCounter(hCounter, psNewValue, true);
    274 }
    275