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