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 "pkcs11_internal.h" 32 33 /* ------------------------------------------------------------------------ 34 Internal Functions 35 ------------------------------------------------------------------------- */ 36 /** 37 * Checks the following pre-conditions: 38 * - cryptoki is initialized, 39 * - hSession is valid (primary and/or secondary), 40 * - the user is logged in. 41 * 42 * And updates handle values: 43 * IN/OUT : phSession 44 * IN = Cryptoki external handle 45 * OUT = TFAPI handle = primary cryptoki session handle 46 * OUT : phSecSession16Msb 47 * OUT = 0 for a primary session or 48 * the secondary cryptoki session handle in the 16 MSB bits 49 */ 50 static CK_RV static_checkPreConditionsAndUpdateHandles( 51 CK_SESSION_HANDLE* phSession, 52 uint32_t* phCommandIDAndSession, 53 PPKCS11_PRIMARY_SESSION_CONTEXT* ppSession) 54 { 55 bool bIsPrimarySession; 56 57 /* Check Cryptoki is initialized */ 58 if (!g_bCryptokiInitialized) 59 { 60 return CKR_CRYPTOKI_NOT_INITIALIZED; 61 } 62 63 if (phSession == NULL) 64 { 65 return CKR_SESSION_HANDLE_INVALID; 66 } 67 68 /* Check that the session is valid */ 69 if (!ckInternalSessionIsOpenedEx(*phSession, &bIsPrimarySession)) 70 { 71 return CKR_SESSION_HANDLE_INVALID; 72 } 73 /* previous check is fine, then update session handles */ 74 if (bIsPrimarySession) 75 { 76 PPKCS11_PRIMARY_SESSION_CONTEXT pSession = 77 (PPKCS11_PRIMARY_SESSION_CONTEXT)(*phSession); 78 79 *phSession = pSession->hCryptoSession; 80 *phCommandIDAndSession = (pSession->hCryptoSession<<16)|(*phCommandIDAndSession&0x00007FFF); 81 *ppSession = pSession; 82 } 83 else 84 { 85 PPKCS11_SECONDARY_SESSION_CONTEXT pSecSession = 86 (PPKCS11_SECONDARY_SESSION_CONTEXT)(*phSession); 87 88 *phSession = pSecSession->pPrimarySession->hCryptoSession; 89 *phCommandIDAndSession = (pSecSession->hSecondaryCryptoSession<<16)|(1<<15)|(*phCommandIDAndSession&0x00007FFF); 90 *ppSession = pSecSession->pPrimarySession; 91 } 92 93 return CKR_OK; 94 } 95 96 /* Add up the sizes of the items and values in an attribute template. 97 */ 98 static CK_RV static_analyzeTemplate( 99 uint32_t *const pDataOffset, 100 uint32_t *const pBufferSize, 101 const CK_ATTRIBUTE *const pTemplate, 102 CK_ULONG const ulCount) 103 { 104 CK_ULONG i; 105 uint32_t nItemsSize; 106 uint32_t nValuesSize = 0; 107 108 nItemsSize = sizeof(uint32_t); /* for the number of attributes */ 109 if (ulCount == 0) 110 { 111 /* There are zero attributes, so the buffer will only contain the size word. */ 112 *pDataOffset += nItemsSize; 113 *pBufferSize += nItemsSize; 114 return CKR_OK; 115 } 116 nItemsSize += sizeof(INPUT_TEMPLATE_ITEM) * ulCount; /*for the attribute items*/ 117 118 /* Add up the attribute value sizes, taking the 4-byte alignment into account. */ 119 for (i = 0; i < ulCount; i++) 120 { 121 if (*pBufferSize + nValuesSize > 0x40000000) 122 { 123 /* Offsets above 0x40000000 aren't supported. */ 124 return CKR_DEVICE_ERROR; 125 } 126 nValuesSize += PKCS11_GET_SIZE_WITH_ALIGNMENT(pTemplate[i].ulValueLen); 127 } 128 129 *pDataOffset += nItemsSize; 130 *pBufferSize += nItemsSize + nValuesSize; 131 return CKR_OK; 132 } 133 134 static void static_copyTemplate( 135 uint8_t *const pBuffer, 136 uint32_t const nParamIndex, 137 uint8_t **const ppAttributeCursor, 138 uint8_t **const ppDataCursor, 139 const CK_ATTRIBUTE *const pTemplate, 140 CK_ULONG const ulCount) 141 { 142 INPUT_TEMPLATE_ITEM sItem; 143 CK_ULONG i; 144 *(uint32_t*)(*ppAttributeCursor) = ulCount; 145 *ppAttributeCursor += sizeof(uint32_t); 146 for (i = 0; i < ulCount; i++) 147 { 148 sItem.attributeType = pTemplate[i].type; 149 /* dataOffset = 0 means NULL buffer */ 150 sItem.dataOffset = ((pTemplate[i].pValue == NULL) ? 0 : 151 *ppDataCursor - pBuffer); 152 sItem.dataParamIndex = nParamIndex; /* The parameter where we store the data (0 to 3) */ 153 sItem.dataValueLen = pTemplate[i].ulValueLen; 154 /* Copy the item */ 155 memcpy(*ppAttributeCursor, &sItem, sizeof(INPUT_TEMPLATE_ITEM)); 156 *ppAttributeCursor += sizeof(INPUT_TEMPLATE_ITEM); 157 if (pTemplate[i].pValue != NULL) 158 { 159 /* Copy the data */ 160 memcpy(*ppDataCursor, pTemplate[i].pValue, pTemplate[i].ulValueLen); 161 /* Next data will be stored just after the previous one but aligned on 4 bytes */ 162 *ppDataCursor += PKCS11_GET_SIZE_WITH_ALIGNMENT(pTemplate[i].ulValueLen); 163 } 164 } 165 } 166 167 /******************************************/ 168 /* The buffer must be freed by the caller */ 169 /******************************************/ 170 static CK_RV static_encodeTwoTemplates( 171 uint8_t** ppBuffer, 172 uint32_t * pBufferSize, 173 const uint32_t nParamIndex, 174 const CK_ATTRIBUTE* pTemplate1, 175 CK_ULONG ulCount1, 176 const CK_ATTRIBUTE* pTemplate2, 177 CK_ULONG ulCount2) 178 { 179 uint8_t* pBuffer = NULL; 180 uint32_t nBufferSize = 0; 181 uint32_t nDataOffset = 0; 182 uint8_t *pAttributeCursor; 183 uint8_t *pDataCursor; 184 CK_RV nErrorCode; 185 186 nErrorCode = static_analyzeTemplate(&nDataOffset, &nBufferSize, pTemplate1, ulCount1); 187 if (nErrorCode != CKR_OK) return nErrorCode; 188 nErrorCode = static_analyzeTemplate(&nDataOffset, &nBufferSize, pTemplate2, ulCount2); 189 if (nErrorCode != CKR_OK) return nErrorCode; 190 191 pBuffer = malloc(nBufferSize); 192 if (pBuffer == NULL) return CKR_DEVICE_MEMORY; 193 memset(pBuffer, 0, nBufferSize); 194 195 pAttributeCursor = pBuffer; 196 pDataCursor = pBuffer + nDataOffset; 197 static_copyTemplate(pBuffer, nParamIndex, 198 &pAttributeCursor, &pDataCursor, 199 pTemplate1, ulCount1); 200 static_copyTemplate(pBuffer, nParamIndex, 201 &pAttributeCursor, &pDataCursor, 202 pTemplate2, ulCount2); 203 204 *ppBuffer = pBuffer; 205 *pBufferSize = nBufferSize; 206 return CKR_OK; 207 } 208 209 /******************************************/ 210 /* The buffer must be freed by the caller */ 211 /******************************************/ 212 static CK_RV static_encodeTemplate( 213 uint8_t** ppBuffer, 214 uint32_t* pBufferSize, 215 const uint32_t nParamIndex, 216 CK_ATTRIBUTE* pTemplate, 217 CK_ULONG ulCount) 218 { 219 uint8_t* pBuffer = NULL; 220 uint32_t nBufferSize = 0; 221 uint32_t nDataOffset = 0; 222 uint8_t *pAttributeCursor; 223 uint8_t *pDataCursor; 224 CK_RV nErrorCode; 225 226 if (pTemplate == NULL || ulCount == 0) 227 { 228 *ppBuffer = NULL; 229 *pBufferSize = 0; 230 return CKR_OK; 231 } 232 233 nErrorCode = static_analyzeTemplate(&nDataOffset, &nBufferSize, pTemplate, ulCount); 234 if (nErrorCode != CKR_OK) return nErrorCode; 235 236 pBuffer = malloc(nBufferSize); 237 if (pBuffer == NULL) return CKR_DEVICE_MEMORY; 238 239 pAttributeCursor = pBuffer; 240 pDataCursor = pBuffer + nDataOffset; 241 static_copyTemplate(pBuffer, nParamIndex, 242 &pAttributeCursor, &pDataCursor, 243 pTemplate, ulCount); 244 245 *ppBuffer = pBuffer; 246 *pBufferSize = nBufferSize; 247 return CKR_OK; 248 } 249 /* ----------------------------------------------------------------------- */ 250 251 static CK_RV static_C_CallInit( 252 uint32_t nCommandID, 253 CK_SESSION_HANDLE hSession, 254 const CK_MECHANISM* pMechanism, 255 CK_OBJECT_HANDLE hKey) 256 { 257 TEEC_Result teeErr; 258 uint32_t nErrorOrigin; 259 TEEC_Operation sOperation; 260 CK_RV nErrorCode = CKR_OK; 261 uint32_t nCommandIDAndSession = nCommandID; 262 uint32_t nParamType2 = TEEC_NONE; 263 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 264 265 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 266 if (nErrorCode != CKR_OK) 267 { 268 return nErrorCode; 269 } 270 if (pMechanism == NULL) 271 { 272 return CKR_ARGUMENTS_BAD; 273 } 274 275 memset(&sOperation, 0, sizeof(TEEC_Operation)); 276 sOperation.params[0].value.a = (uint32_t)pMechanism->mechanism; 277 if (nCommandID != SERVICE_SYSTEM_PKCS11_C_DIGESTINIT_COMMAND_ID) 278 { 279 sOperation.params[0].value.b = (uint32_t)hKey; 280 281 } 282 sOperation.params[1].tmpref.buffer = (uint8_t*)pMechanism->pParameter; 283 sOperation.params[1].tmpref.size = (uint32_t)pMechanism->ulParameterLen; 284 285 /* Specific case of RSA OAEP */ 286 if (((nCommandID == SERVICE_SYSTEM_PKCS11_C_ENCRYPTINIT_COMMAND_ID) 287 ||(nCommandID == SERVICE_SYSTEM_PKCS11_C_DECRYPTINIT_COMMAND_ID)) 288 && (pMechanism->mechanism == CKM_RSA_PKCS_OAEP) 289 && (pMechanism->pParameter != NULL)) 290 { 291 /* Add the source buffer of the RSA OAEP mechanism parameters */ 292 nParamType2 = TEEC_MEMREF_TEMP_INPUT; 293 sOperation.params[2].tmpref.buffer = (uint8_t*)((CK_RSA_PKCS_OAEP_PARAMS_PTR)(pMechanism->pParameter))->pSourceData; 294 sOperation.params[2].tmpref.size = (uint32_t) ((CK_RSA_PKCS_OAEP_PARAMS_PTR)(pMechanism->pParameter))->ulSourceDataLen; 295 } 296 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, nParamType2, TEEC_NONE); 297 teeErr = TEEC_InvokeCommand( &pSession->sSession, 298 nCommandIDAndSession, /* commandID */ 299 &sOperation, /* IN OUT operation */ 300 &nErrorOrigin /* OUT returnOrigin, optional */ 301 ); 302 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 303 teeErr : 304 ckInternalTeeErrorToCKError(teeErr)); 305 306 return nErrorCode; 307 } 308 309 /* ----------------------------------------------------------------------- */ 310 /** 311 * If bSend, the pData buffer is sent to the service. 312 * If bResult, a buffer is received, the convention described in 313 * PKCS11 Section 11.2 applies for pResult and pulResultLen. 314 * Specific function used for single operation 315 */ 316 static CK_RV static_C_CallForSingle( 317 uint32_t nCommandID, 318 CK_SESSION_HANDLE hSession, 319 const CK_BYTE* pData, 320 CK_ULONG ulDataLen, 321 CK_BYTE* pResult, 322 CK_ULONG* pulResultLen, 323 bool bSend, 324 bool bReceive) 325 { 326 TEEC_Result teeErr; 327 uint32_t nErrorOrigin; 328 TEEC_Operation sOperation; 329 CK_RV nErrorCode = CKR_OK; 330 uint32_t nCommandIDAndSession = nCommandID; 331 uint32_t nParamType0 = TEEC_NONE; 332 uint32_t nParamType1 = TEEC_NONE; 333 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 334 335 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 336 if (nErrorCode != CKR_OK) 337 { 338 return nErrorCode; 339 } 340 341 memset(&sOperation, 0, sizeof(TEEC_Operation)); 342 343 if (bSend) 344 { 345 nParamType0 = TEEC_MEMREF_TEMP_INPUT; 346 sOperation.params[0].tmpref.buffer = (uint8_t*)pData; 347 sOperation.params[0].tmpref.size = (uint32_t)ulDataLen; 348 } 349 350 if (bReceive) 351 { 352 if (pulResultLen == NULL) 353 { 354 /* The P11 API Spec states that, in this case, the operation must be 355 aborted and the error code CKR_ARGUMENTS_BAD must be returned. We 356 achieve this result by sending an invalid parameter type */ 357 nParamType1 = TEEC_NONE; 358 } 359 else if (pResult == NULL) 360 { 361 /* If pResult is NULL, the caller only wants the buffer length. 362 Send a NULL output memref */ 363 nParamType1 = TEEC_MEMREF_TEMP_OUTPUT; 364 sOperation.params[1].tmpref.buffer = (uint8_t*)NULL; 365 } 366 else 367 { 368 /* send the result buffer information */ 369 nParamType1 = TEEC_MEMREF_TEMP_OUTPUT; 370 sOperation.params[1].tmpref.buffer = (uint8_t*)pResult; 371 sOperation.params[1].tmpref.size = (uint32_t)*pulResultLen; 372 } 373 } 374 375 sOperation.paramTypes = TEEC_PARAM_TYPES(nParamType0, nParamType1, TEEC_NONE, TEEC_NONE); 376 teeErr = TEEC_InvokeCommand(&pSession->sSession, 377 nCommandIDAndSession, /* commandID */ 378 &sOperation, /* IN OUT operation */ 379 &nErrorOrigin /* OUT returnOrigin, optional */ 380 ); 381 if (teeErr != TEEC_SUCCESS) 382 { 383 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 384 teeErr : 385 ckInternalTeeErrorToCKError(teeErr)); 386 goto end; 387 } 388 389 /* Success */ 390 nErrorCode = CKR_OK; 391 392 end: 393 if (bReceive) 394 { 395 if ((nErrorCode == CKR_OK) || (nErrorCode == CKR_BUFFER_TOO_SMALL)) 396 { 397 /* The service has returned the actual result */ 398 /* The data is already in pResult, we get the returned length */ 399 *pulResultLen = sOperation.params[1].tmpref.size; 400 } 401 } 402 403 return nErrorCode; 404 } 405 406 /* ----------------------------------------------------------------------- */ 407 /** 408 * If bSend, the pData buffer is sent to the service. 409 * If bResult, a buffer is received, the convention described in 410 * PKCS11 Section 11.2 applies for pResult and pulResultLen. 411 * Specific function only used for update operations 412 */ 413 static CK_RV static_C_CallUpdate( 414 uint32_t nCommandID, 415 CK_SESSION_HANDLE hSession, 416 const CK_BYTE* pData, 417 CK_ULONG ulDataLen, 418 CK_BYTE* pResult, 419 CK_ULONG* pulResultLen, 420 bool bSend, 421 bool bReceive) 422 { 423 TEEC_Result teeErr; 424 uint32_t nErrorOrigin; 425 TEEC_Operation sOperation; 426 CK_RV nErrorCode = CKR_OK; 427 uint32_t nResultLen = 0; 428 uint32_t nCommandIDAndSession = nCommandID; 429 uint32_t nParamType0 = TEEC_NONE; 430 uint32_t nParamType1 = TEEC_NONE; 431 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 432 433 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 434 if (nErrorCode != CKR_OK) 435 { 436 return nErrorCode; 437 } 438 439 if (pulResultLen != NULL) 440 { 441 nResultLen = *pulResultLen; 442 } 443 444 memset(&sOperation, 0, sizeof(TEEC_Operation)); 445 446 if (bSend) 447 { 448 nParamType0 = TEEC_MEMREF_TEMP_INPUT; 449 sOperation.params[0].tmpref.buffer = (void*)pData; 450 sOperation.params[0].tmpref.size = ulDataLen; 451 } 452 453 if (bReceive) 454 { 455 if (pulResultLen == NULL) 456 { 457 /* The P11 API Spec states that, in this case, the operation must be 458 aborted and the error code CKR_ARGUMENTS_BAD must be returned. We 459 achieve this result by setting an invalid parameter type */ 460 nParamType1 = TEEC_NONE; 461 } 462 else if (pResult == NULL) 463 { 464 /* If pResult is NULL, the caller only wants the output buffer length. 465 Pass a NULL output ref */ 466 nParamType1 = TEEC_MEMREF_TEMP_OUTPUT; 467 sOperation.params[1].tmpref.buffer = NULL; 468 } 469 else 470 { 471 /* send the result buffer information */ 472 nParamType1 = TEEC_MEMREF_TEMP_OUTPUT; 473 sOperation.params[1].tmpref.buffer = pResult; 474 sOperation.params[1].tmpref.size = (uint32_t)*pulResultLen; 475 } 476 } 477 478 sOperation.paramTypes = TEEC_PARAM_TYPES(nParamType0, nParamType1, TEEC_NONE, TEEC_NONE); 479 teeErr = TEEC_InvokeCommand( &pSession->sSession, 480 nCommandIDAndSession, /* commandID */ 481 &sOperation, /* IN OUT operation */ 482 &nErrorOrigin /* OUT returnOrigin, optional */ 483 ); 484 if (teeErr != TEEC_SUCCESS) 485 { 486 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 487 teeErr : 488 ckInternalTeeErrorToCKError(teeErr)); 489 goto end; 490 } 491 492 /* Success */ 493 nErrorCode = CKR_OK; 494 495 end: 496 if (bReceive) 497 { 498 if ((nErrorCode == CKR_OK) || (nErrorCode == CKR_BUFFER_TOO_SMALL)) 499 { 500 /* The service has returned the actual result */ 501 /* The data is already in pResult, we get the returned length */ 502 *pulResultLen = sOperation.params[1].tmpref.size; 503 } 504 } 505 506 return nErrorCode; 507 } 508 509 /* Splits the buffer pData in chunks of nChunkSize size 510 * and calls static_C_CallUpdate for each chunk 511 */ 512 static CK_RV static_C_CallSplitUpdate( 513 uint32_t nCommandID, 514 CK_SESSION_HANDLE hSession, 515 const CK_BYTE* pData, 516 CK_ULONG ulDataLen, 517 CK_BYTE* pResult, 518 CK_ULONG* pulResultLen, 519 bool bSend, 520 bool bReceive, 521 uint32_t nChunkSize) 522 { 523 CK_RV nErrorCode; 524 CK_ULONG nPartDataLen; 525 CK_ULONG nPartResultLen = 0; 526 CK_ULONG ulResultLen = 0; 527 bool bIsSymOperation = false; 528 529 if (pulResultLen != NULL) 530 { 531 ulResultLen = *pulResultLen; 532 /* Check wether the operation is a symetrical or asymetrical */ 533 if (*pulResultLen == ulDataLen) 534 { 535 bIsSymOperation = true; 536 } 537 *pulResultLen = 0; 538 } 539 540 while (ulDataLen > 0) 541 { 542 nPartDataLen = (ulDataLen <= nChunkSize ? 543 ulDataLen : nChunkSize); 544 if (bIsSymOperation) 545 { 546 /* update the result only if it is a symetric operation */ 547 nPartResultLen = (ulResultLen <= nChunkSize ? 548 ulResultLen : nChunkSize); 549 } 550 else 551 { 552 nPartResultLen = ulResultLen; 553 } 554 555 nErrorCode = static_C_CallUpdate( 556 nCommandID, 557 hSession, 558 pData, 559 nPartDataLen, 560 pResult, 561 &nPartResultLen, 562 bSend, 563 bReceive); 564 if (nErrorCode != CKR_OK) 565 { 566 return nErrorCode; 567 } 568 569 ulDataLen -= nPartDataLen; 570 pData += nPartDataLen; 571 572 if (pResult != NULL) 573 { 574 ulResultLen -= nPartResultLen; 575 pResult += nPartResultLen; 576 } 577 578 if ((pulResultLen != NULL) && (bIsSymOperation)) 579 { 580 *pulResultLen += nPartResultLen; 581 } 582 } 583 return CKR_OK; 584 } 585 586 /* Decides whether to split or not the inout/output buffer into chunks 587 */ 588 static CK_RV static_C_Call_CallForUpdate( 589 uint32_t nCommandID, 590 CK_SESSION_HANDLE hSession, 591 const CK_BYTE* pData, 592 CK_ULONG ulDataLen, 593 CK_BYTE* pResult, 594 CK_ULONG* pulResultLen, 595 bool bSend, 596 bool bReceive) 597 { 598 CK_RV nErrorCode; 599 uint32_t nChunkSize; 600 601 TEEC_ImplementationLimits limits; 602 603 if (!g_bCryptokiInitialized) 604 { 605 return CKR_CRYPTOKI_NOT_INITIALIZED; 606 } 607 608 TEEC_GetImplementationLimits(&limits); 609 610 /* We can split the buffer in chunks of fixed size. 611 No matter of the start address of the buffer, 612 a safe size would be TotalNumberOfPages - 1 613 */ 614 nChunkSize = limits.tmprefMaxSize - limits.pageSize; 615 616 if (ulDataLen > nChunkSize) 617 { 618 /* inoutMaxSize = 0 means unlimited size */ 619 nErrorCode = static_C_CallSplitUpdate(nCommandID, 620 hSession, 621 pData, 622 ulDataLen, 623 pResult, 624 pulResultLen, 625 bSend, 626 bReceive, 627 nChunkSize); 628 } 629 else 630 { 631 nErrorCode = static_C_CallUpdate(nCommandID, 632 hSession, 633 pData, 634 ulDataLen, 635 pResult, 636 pulResultLen, 637 bSend, 638 bReceive); 639 } 640 return nErrorCode; 641 642 } 643 644 /* ------------------------------------------------------------------------ 645 Public Functions 646 ------------------------------------------------------------------------- */ 647 648 CK_RV PKCS11_EXPORT C_CreateObject( 649 CK_SESSION_HANDLE hSession, /* the session's handle */ 650 const CK_ATTRIBUTE* pTemplate, /* the object's template */ 651 CK_ULONG ulCount, /* attributes in template */ 652 CK_OBJECT_HANDLE* phObject) /* receives new object's handle. */ 653 { 654 TEEC_Result teeErr; 655 uint32_t nErrorOrigin; 656 TEEC_Operation sOperation; 657 CK_RV nErrorCode = CKR_OK; 658 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 659 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_CREATEOBJECT_COMMAND_ID; 660 uint8_t* pBuffer = NULL; 661 uint32_t nBufferSize = 0; 662 663 if ( pTemplate == NULL || phObject == NULL ) 664 { 665 return CKR_ARGUMENTS_BAD; 666 } 667 668 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 669 if (nErrorCode != CKR_OK) 670 { 671 return nErrorCode; 672 } 673 674 nErrorCode = static_encodeTemplate(&pBuffer, &nBufferSize, 0, (CK_ATTRIBUTE*)pTemplate, ulCount); /* Sets the template on the param 0 */ 675 if (nErrorCode != CKR_OK) 676 { 677 return nErrorCode; 678 } 679 680 memset(&sOperation, 0, sizeof(TEEC_Operation)); 681 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE); 682 sOperation.params[0].tmpref.buffer = pBuffer; 683 sOperation.params[0].tmpref.size = nBufferSize; 684 teeErr = TEEC_InvokeCommand( &pSession->sSession, 685 nCommandIDAndSession, /* commandID */ 686 &sOperation, /* IN OUT operation */ 687 &nErrorOrigin /* OUT returnOrigin, optional */ 688 ); 689 free(pBuffer); 690 691 if (teeErr != TEEC_SUCCESS) 692 { 693 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 694 teeErr : 695 ckInternalTeeErrorToCKError(teeErr)); 696 goto end; 697 } 698 699 *phObject = sOperation.params[1].value.a; 700 701 /* Success */ 702 nErrorCode = CKR_OK; 703 704 end: 705 return nErrorCode; 706 } 707 708 CK_RV PKCS11_EXPORT C_DestroyObject( 709 CK_SESSION_HANDLE hSession, /* the session's handle */ 710 CK_OBJECT_HANDLE hObject) /* the object's handle */ 711 { 712 TEEC_Result teeErr; 713 uint32_t nErrorOrigin; 714 TEEC_Operation sOperation; 715 CK_RV nErrorCode = CKR_OK; 716 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_DESTROYOBJECT_COMMAND_ID; 717 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 718 719 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 720 if (nErrorCode != CKR_OK) 721 { 722 return nErrorCode; 723 } 724 725 memset(&sOperation, 0, sizeof(TEEC_Operation)); 726 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 727 sOperation.params[0].value.a = (uint32_t)hObject; 728 teeErr = TEEC_InvokeCommand( &pSession->sSession, 729 nCommandIDAndSession, /* commandID */ 730 &sOperation, /* IN OUT operation */ 731 &nErrorOrigin /* OUT returnOrigin, optional */ 732 ); 733 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 734 teeErr : 735 ckInternalTeeErrorToCKError(teeErr)); 736 return nErrorCode; 737 } 738 739 CK_RV PKCS11_EXPORT C_GetAttributeValue( 740 CK_SESSION_HANDLE hSession, /* the session's handle */ 741 CK_OBJECT_HANDLE hObject, /* the object's handle */ 742 CK_ATTRIBUTE* pTemplate, /* specifies attributes, gets values */ 743 CK_ULONG ulCount) /* attributes in template */ 744 { 745 TEEC_Result teeErr; 746 uint32_t nErrorOrigin; 747 TEEC_Operation sOperation; 748 CK_RV nErrorCode = CKR_OK; 749 CK_RV nFinalErrorCode = CKR_OK; 750 uint32_t i = 0; 751 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_GETATTRIBUTEVALUE_COMMAND_ID; 752 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 753 754 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 755 if (nErrorCode != CKR_OK) 756 { 757 return nErrorCode; 758 } 759 760 if (pTemplate == NULL) 761 { 762 return CKR_ARGUMENTS_BAD; 763 } 764 765 if (ulCount == 0) 766 { 767 return CKR_OK; 768 } 769 770 for (i = 0; i < ulCount; i++) 771 { 772 memset(&sOperation, 0, sizeof(TEEC_Operation)); 773 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE); 774 sOperation.params[0].value.a = (uint32_t)hObject; 775 sOperation.params[0].value.b = (uint32_t)pTemplate[i].type; 776 sOperation.params[1].tmpref.buffer = pTemplate[i].pValue; 777 sOperation.params[1].tmpref.size = pTemplate[i].ulValueLen; 778 teeErr = TEEC_InvokeCommand( &pSession->sSession, 779 nCommandIDAndSession, /* commandID */ 780 &sOperation, /* IN OUT operation */ 781 &nErrorOrigin /* OUT returnOrigin, optional */ 782 ); 783 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 784 teeErr : 785 ckInternalTeeErrorToCKError(teeErr)); 786 if (nErrorCode != CKR_OK) 787 { 788 if ( (nErrorCode == CKR_ATTRIBUTE_SENSITIVE) || 789 (nErrorCode == CKR_ATTRIBUTE_TYPE_INVALID) || 790 (nErrorCode == CKR_BUFFER_TOO_SMALL)) 791 { 792 nFinalErrorCode = nErrorCode; 793 } 794 else 795 { 796 /* Not some of the special error codes: this is fatal */ 797 return nErrorCode; 798 } 799 } 800 801 pTemplate[i].ulValueLen = sOperation.params[1].tmpref.size; 802 } 803 804 return nFinalErrorCode; 805 } 806 807 CK_RV PKCS11_EXPORT C_FindObjectsInit( 808 CK_SESSION_HANDLE hSession, /* the session's handle */ 809 const CK_ATTRIBUTE* pTemplate, /* attribute values to match */ 810 CK_ULONG ulCount) /* attributes in search template */ 811 { 812 TEEC_Result teeErr; 813 uint32_t nErrorOrigin; 814 TEEC_Operation sOperation; 815 CK_RV nErrorCode = CKR_OK; 816 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 817 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_FINDOBJECTSINIT_COMMAND_ID; 818 uint8_t* pBuffer = NULL; 819 uint32_t nBufferSize = 0; 820 821 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 822 if (nErrorCode != CKR_OK) 823 { 824 return nErrorCode; 825 } 826 827 nErrorCode = static_encodeTemplate(&pBuffer, &nBufferSize, 0, (CK_ATTRIBUTE*)pTemplate, ulCount); /* Sets the template on the param 0 */ 828 if (nErrorCode != CKR_OK) 829 { 830 return nErrorCode; 831 } 832 833 memset(&sOperation, 0, sizeof(TEEC_Operation)); 834 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 835 sOperation.params[0].tmpref.buffer = pBuffer; 836 sOperation.params[0].tmpref.size = nBufferSize; 837 teeErr = TEEC_InvokeCommand( &pSession->sSession, 838 nCommandIDAndSession, /* commandID */ 839 &sOperation, /* IN OUT operation */ 840 &nErrorOrigin /* OUT returnOrigin, optional */ 841 ); 842 free(pBuffer); 843 844 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 845 teeErr : 846 ckInternalTeeErrorToCKError(teeErr)); 847 return nErrorCode; 848 } 849 850 851 CK_RV PKCS11_EXPORT C_FindObjects( 852 CK_SESSION_HANDLE hSession, /* the session's handle */ 853 CK_OBJECT_HANDLE* phObject, /* receives object handle array */ 854 CK_ULONG ulMaxObjectCount, /* max handles to be returned */ 855 CK_ULONG* pulObjectCount) /* actual number returned */ 856 { 857 TEEC_Result teeErr; 858 uint32_t nErrorOrigin; 859 TEEC_Operation sOperation; 860 CK_RV nErrorCode = CKR_OK; 861 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 862 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_FINDOBJECTS_COMMAND_ID; 863 864 if ( (phObject == NULL) || (pulObjectCount == NULL)) 865 { 866 return CKR_ARGUMENTS_BAD; 867 } 868 869 *pulObjectCount = 0; 870 871 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 872 if (nErrorCode != CKR_OK) 873 { 874 return nErrorCode; 875 } 876 877 memset(&sOperation, 0, sizeof(TEEC_Operation)); 878 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 879 sOperation.params[0].tmpref.buffer = (uint8_t*)phObject; 880 sOperation.params[0].tmpref.size = (uint32_t)ulMaxObjectCount * sizeof(uint32_t); 881 882 teeErr = TEEC_InvokeCommand( &pSession->sSession, 883 nCommandIDAndSession, /* commandID */ 884 &sOperation, /* IN OUT operation */ 885 &nErrorOrigin /* OUT returnOrigin, optional */ 886 ); 887 888 if (teeErr != TEEC_SUCCESS) 889 { 890 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 891 teeErr : 892 ckInternalTeeErrorToCKError(teeErr)); 893 return nErrorCode; 894 } 895 896 *pulObjectCount = sOperation.params[0].tmpref.size / sizeof(uint32_t); 897 898 return CKR_OK; 899 } 900 901 CK_RV PKCS11_EXPORT C_FindObjectsFinal(CK_SESSION_HANDLE hSession) /* the session's handle */ 902 { 903 TEEC_Result teeErr; 904 uint32_t nErrorOrigin; 905 TEEC_Operation sOperation; 906 CK_RV nErrorCode = CKR_OK; 907 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_FINDOBJECTSFINAL_COMMAND_ID; 908 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 909 910 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 911 if (nErrorCode != CKR_OK) 912 { 913 return nErrorCode; 914 } 915 916 memset(&sOperation, 0, sizeof(TEEC_Operation)); 917 teeErr = TEEC_InvokeCommand( &pSession->sSession, 918 nCommandIDAndSession, /* commandID */ 919 &sOperation, /* IN OUT operation */ 920 &nErrorOrigin /* OUT returnOrigin, optional */ 921 ); 922 923 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 924 teeErr : 925 ckInternalTeeErrorToCKError(teeErr)); 926 return nErrorCode; 927 } 928 929 930 CK_RV PKCS11_EXPORT C_DigestInit( 931 CK_SESSION_HANDLE hSession, /* the session's handle */ 932 const CK_MECHANISM* pMechanism) /* the digesting mechanism */ 933 { 934 return static_C_CallInit( 935 SERVICE_SYSTEM_PKCS11_C_DIGESTINIT_COMMAND_ID, 936 hSession, 937 pMechanism, 938 CK_INVALID_HANDLE); 939 } 940 941 CK_RV PKCS11_EXPORT C_Digest( 942 CK_SESSION_HANDLE hSession, /* the session's handle */ 943 const CK_BYTE* pData, /* data to be digested */ 944 CK_ULONG ulDataLen, /* bytes of data to be digested */ 945 CK_BYTE* pDigest, /* receives the message digest */ 946 CK_ULONG* pulDigestLen) /* receives byte length of digest */ 947 { 948 return static_C_CallForSingle( 949 SERVICE_SYSTEM_PKCS11_C_DIGEST_COMMAND_ID, 950 hSession, 951 pData, 952 ulDataLen, 953 pDigest, 954 pulDigestLen, 955 TRUE, 956 TRUE); 957 } 958 959 CK_RV PKCS11_EXPORT C_DigestUpdate( 960 CK_SESSION_HANDLE hSession, /* the session's handle */ 961 const CK_BYTE* pPart, /* data to be digested */ 962 CK_ULONG ulPartLen) /* bytes of data to be digested */ 963 { 964 return static_C_Call_CallForUpdate( 965 SERVICE_SYSTEM_PKCS11_C_DIGESTUPDATE_COMMAND_ID, 966 hSession, 967 pPart, 968 ulPartLen, 969 NULL, 970 NULL, 971 TRUE, 972 FALSE); 973 } 974 975 CK_RV PKCS11_EXPORT C_DigestFinal( 976 CK_SESSION_HANDLE hSession, /* the session's handle */ 977 CK_BYTE* pDigest, /* receives the message digest */ 978 CK_ULONG* pulDigestLen) /* receives byte count of digest */ 979 { 980 return static_C_Call_CallForUpdate( 981 SERVICE_SYSTEM_PKCS11_C_DIGESTFINAL_COMMAND_ID, 982 hSession, 983 NULL, 984 0, 985 pDigest, 986 pulDigestLen, 987 FALSE, 988 TRUE); 989 } 990 991 992 CK_RV PKCS11_EXPORT C_SignInit( 993 CK_SESSION_HANDLE hSession, /* the session's handle */ 994 const CK_MECHANISM* pMechanism, /* the signature mechanism */ 995 CK_OBJECT_HANDLE hKey) /* handle of the signature key */ 996 { 997 return static_C_CallInit( 998 SERVICE_SYSTEM_PKCS11_C_SIGNINIT_COMMAND_ID, 999 hSession, 1000 pMechanism, 1001 hKey); 1002 } 1003 1004 CK_RV PKCS11_EXPORT C_Sign( 1005 CK_SESSION_HANDLE hSession, /* the session's handle */ 1006 const CK_BYTE* pData, /* the data (digest) to be signed */ 1007 CK_ULONG ulDataLen, /* count of bytes to be signed */ 1008 CK_BYTE* pSignature, /* receives the signature */ 1009 CK_ULONG* pulSignatureLen) /* receives byte count of signature */ 1010 { 1011 return static_C_CallForSingle( 1012 SERVICE_SYSTEM_PKCS11_C_SIGN_COMMAND_ID, 1013 hSession, 1014 pData, 1015 ulDataLen, 1016 pSignature, 1017 pulSignatureLen, 1018 TRUE, 1019 TRUE); 1020 } 1021 1022 CK_RV PKCS11_EXPORT C_SignUpdate( 1023 CK_SESSION_HANDLE hSession, /* the session's handle */ 1024 const CK_BYTE* pPart, /* the data (digest) to be signed */ 1025 CK_ULONG ulPartLen) /* count of bytes to be signed */ 1026 { 1027 return static_C_Call_CallForUpdate( 1028 SERVICE_SYSTEM_PKCS11_C_SIGNUPDATE_COMMAND_ID, 1029 hSession, 1030 pPart, 1031 ulPartLen, 1032 NULL, 1033 NULL, 1034 TRUE, 1035 FALSE); 1036 } 1037 1038 CK_RV PKCS11_EXPORT C_SignFinal( 1039 CK_SESSION_HANDLE hSession, /* the session's handle */ 1040 CK_BYTE* pSignature, /* receives the signature */ 1041 CK_ULONG* pulSignatureLen) /* receives byte count of signature */ 1042 { 1043 return static_C_Call_CallForUpdate( 1044 SERVICE_SYSTEM_PKCS11_C_SIGNFINAL_COMMAND_ID, 1045 hSession, 1046 NULL, 1047 0, 1048 pSignature, 1049 pulSignatureLen, 1050 FALSE, 1051 TRUE); 1052 } 1053 1054 CK_RV PKCS11_EXPORT C_EncryptInit( 1055 CK_SESSION_HANDLE hSession, /* the session's handle */ 1056 const CK_MECHANISM* pMechanism, /* the encryption mechanism */ 1057 CK_OBJECT_HANDLE hKey) /* handle of encryption key */ 1058 { 1059 return static_C_CallInit( 1060 SERVICE_SYSTEM_PKCS11_C_ENCRYPTINIT_COMMAND_ID, 1061 hSession, 1062 pMechanism, 1063 hKey); 1064 } 1065 1066 CK_RV PKCS11_EXPORT C_Encrypt( 1067 CK_SESSION_HANDLE hSession, /* the session's handle */ 1068 const CK_BYTE* pData, /* the plaintext data */ 1069 CK_ULONG ulDataLen, /* bytes of plaintext data */ 1070 CK_BYTE* pEncryptedData, /* receives encrypted data */ 1071 CK_ULONG* pulEncryptedDataLen) /* receives encrypted byte count */ 1072 { 1073 1074 return static_C_CallForSingle( 1075 SERVICE_SYSTEM_PKCS11_C_ENCRYPT_COMMAND_ID, 1076 hSession, 1077 pData, 1078 ulDataLen, 1079 pEncryptedData, 1080 pulEncryptedDataLen, 1081 TRUE, 1082 TRUE); 1083 } 1084 1085 1086 1087 CK_RV PKCS11_EXPORT C_EncryptUpdate( 1088 CK_SESSION_HANDLE hSession, /* the session's handle */ 1089 const CK_BYTE* pPart, /* the plaintext data */ 1090 CK_ULONG ulPartLen, /* bytes of plaintext data */ 1091 CK_BYTE* pEncryptedPart, /* receives encrypted data */ 1092 CK_ULONG* pulEncryptedPartLen)/* receives encrypted byte count */ 1093 { 1094 return static_C_Call_CallForUpdate( 1095 SERVICE_SYSTEM_PKCS11_C_ENCRYPTUPDATE_COMMAND_ID, 1096 hSession, 1097 pPart, 1098 ulPartLen, 1099 pEncryptedPart, 1100 pulEncryptedPartLen, 1101 TRUE, 1102 TRUE); 1103 } 1104 1105 CK_RV PKCS11_EXPORT C_EncryptFinal( 1106 CK_SESSION_HANDLE hSession, /* the session's handle */ 1107 CK_BYTE* pLastEncryptedPart, /* receives encrypted last part */ 1108 CK_ULONG* pulLastEncryptedPartLen) /* receives byte count */ 1109 { 1110 return static_C_Call_CallForUpdate( 1111 SERVICE_SYSTEM_PKCS11_C_ENCRYPTFINAL_COMMAND_ID, 1112 hSession, 1113 NULL, 1114 0, 1115 pLastEncryptedPart, 1116 pulLastEncryptedPartLen, 1117 FALSE, 1118 TRUE); 1119 } 1120 1121 CK_RV PKCS11_EXPORT C_DecryptInit( 1122 CK_SESSION_HANDLE hSession, /* the session's handle */ 1123 const CK_MECHANISM* pMechanism, /* the decryption mechanism */ 1124 CK_OBJECT_HANDLE hKey) /* handle of the decryption key */ 1125 { 1126 return static_C_CallInit( 1127 SERVICE_SYSTEM_PKCS11_C_DECRYPTINIT_COMMAND_ID, 1128 hSession, 1129 pMechanism, 1130 hKey); 1131 } 1132 1133 CK_RV PKCS11_EXPORT C_Decrypt( 1134 CK_SESSION_HANDLE hSession, /* the session's handle */ 1135 const CK_BYTE* pEncryptedData, /* input encrypted data */ 1136 CK_ULONG ulEncryptedDataLen, /* count of bytes of input */ 1137 CK_BYTE* pData, /* receives decrypted output */ 1138 CK_ULONG* pulDataLen) /* receives decrypted byte count */ 1139 { 1140 1141 return static_C_CallForSingle( 1142 SERVICE_SYSTEM_PKCS11_C_DECRYPT_COMMAND_ID, 1143 hSession, 1144 pEncryptedData, 1145 ulEncryptedDataLen, 1146 pData, 1147 pulDataLen, 1148 TRUE, 1149 TRUE); 1150 } 1151 1152 CK_RV PKCS11_EXPORT C_DecryptUpdate( 1153 CK_SESSION_HANDLE hSession, /* the session's handle */ 1154 const CK_BYTE* pEncryptedPart, /* input encrypted data */ 1155 CK_ULONG ulEncryptedPartLen, /* count of bytes of input */ 1156 CK_BYTE* pPart, /* receives decrypted output */ 1157 CK_ULONG* pulPartLen) /* receives decrypted byte count */ 1158 { 1159 return static_C_Call_CallForUpdate( 1160 SERVICE_SYSTEM_PKCS11_C_DECRYPTUPDATE_COMMAND_ID, 1161 hSession, 1162 pEncryptedPart, 1163 ulEncryptedPartLen, 1164 pPart, 1165 pulPartLen, 1166 TRUE, 1167 TRUE); 1168 } 1169 1170 CK_RV PKCS11_EXPORT C_DecryptFinal( 1171 CK_SESSION_HANDLE hSession, /* the session's handle */ 1172 CK_BYTE* pLastPart, /* receives decrypted output */ 1173 CK_ULONG* pulLastPartLen) /* receives decrypted byte count */ 1174 { 1175 return static_C_Call_CallForUpdate( 1176 SERVICE_SYSTEM_PKCS11_C_DECRYPTFINAL_COMMAND_ID, 1177 hSession, 1178 NULL, 1179 0, 1180 pLastPart, 1181 pulLastPartLen, 1182 FALSE, 1183 TRUE); 1184 } 1185 1186 1187 CK_RV PKCS11_EXPORT C_GenerateKey( 1188 CK_SESSION_HANDLE hSession, /* the session's handle */ 1189 const CK_MECHANISM* pMechanism, /* the key generation mechanism */ 1190 const CK_ATTRIBUTE* pTemplate, /* template for the new key */ 1191 CK_ULONG ulCount, /* number of attributes in template */ 1192 CK_OBJECT_HANDLE* phKey) /* receives handle of new key */ 1193 { 1194 TEEC_Result teeErr; 1195 uint32_t nErrorOrigin; 1196 TEEC_Operation sOperation; 1197 CK_RV nErrorCode = CKR_OK; 1198 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_GENERATEKEY_COMMAND_ID; 1199 uint8_t* pBuffer = NULL; 1200 uint32_t nBufferSize = 0; 1201 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1202 1203 if ((pMechanism == NULL) || (phKey == NULL) || (pTemplate == NULL)) 1204 { 1205 return CKR_ARGUMENTS_BAD; 1206 } 1207 1208 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1209 if (nErrorCode != CKR_OK) 1210 { 1211 return nErrorCode; 1212 } 1213 1214 nErrorCode = static_encodeTemplate(&pBuffer, &nBufferSize, 2, (CK_ATTRIBUTE*)pTemplate, ulCount); 1215 if (nErrorCode != CKR_OK) 1216 { 1217 return nErrorCode; 1218 } 1219 1220 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1221 sOperation.params[0].value.a = (uint32_t)pMechanism->mechanism; 1222 sOperation.params[0].value.b = 0; 1223 sOperation.params[1].tmpref.buffer = pMechanism->pParameter; 1224 sOperation.params[1].tmpref.size = (uint32_t)pMechanism->ulParameterLen; 1225 sOperation.params[2].tmpref.buffer = pBuffer; 1226 sOperation.params[2].tmpref.size = nBufferSize; 1227 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE); 1228 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1229 nCommandIDAndSession, /* commandID */ 1230 &sOperation, /* IN OUT operation */ 1231 &nErrorOrigin /* OUT returnOrigin, optional */ 1232 ); 1233 free(pBuffer); 1234 1235 if (teeErr != TEEC_SUCCESS) 1236 { 1237 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1238 teeErr : 1239 ckInternalTeeErrorToCKError(teeErr)); 1240 return nErrorCode; 1241 } 1242 1243 *phKey = sOperation.params[0].value.a; 1244 1245 return CKR_OK; 1246 } 1247 1248 CK_RV PKCS11_EXPORT C_GenerateKeyPair( 1249 CK_SESSION_HANDLE hSession, /* the session's handle */ 1250 const CK_MECHANISM* pMechanism, /* the key gen. mech. */ 1251 const CK_ATTRIBUTE* pPublicKeyTemplate, /* pub. attr. template */ 1252 CK_ULONG ulPublicKeyAttributeCount, /* # of pub. attrs. */ 1253 const CK_ATTRIBUTE* pPrivateKeyTemplate, /* priv. attr. template */ 1254 CK_ULONG ulPrivateKeyAttributeCount, /* # of priv. attrs. */ 1255 CK_OBJECT_HANDLE* phPublicKey, /* gets pub. key handle */ 1256 CK_OBJECT_HANDLE* phPrivateKey) /* gets priv. key handle */ 1257 { 1258 TEEC_Result teeErr; 1259 uint32_t nErrorOrigin; 1260 TEEC_Operation sOperation; 1261 CK_RV nErrorCode = CKR_OK; 1262 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_GENERATEKEYPAIR_COMMAND_ID; 1263 uint8_t* pBuffer = NULL; 1264 uint32_t nBufferSize = 0; 1265 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1266 1267 if ( (pMechanism == NULL) || 1268 (pPublicKeyTemplate == NULL) || 1269 (phPublicKey== NULL) || (phPrivateKey== NULL)) 1270 { 1271 return CKR_ARGUMENTS_BAD; 1272 } 1273 1274 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1275 if (nErrorCode != CKR_OK) 1276 { 1277 return nErrorCode; 1278 } 1279 1280 nErrorCode = static_encodeTwoTemplates(&pBuffer, &nBufferSize, 2, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount); 1281 if (nErrorCode != CKR_OK) 1282 { 1283 return nErrorCode; 1284 } 1285 1286 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1287 sOperation.params[0].value.a = (uint32_t)pMechanism->mechanism; 1288 sOperation.params[0].value.b = 0; 1289 sOperation.params[1].tmpref.buffer = (uint8_t*)pMechanism->pParameter; 1290 sOperation.params[1].tmpref.size = (uint32_t)pMechanism->ulParameterLen; 1291 sOperation.params[2].tmpref.buffer = pBuffer; 1292 sOperation.params[2].tmpref.size = nBufferSize; 1293 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE); 1294 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1295 nCommandIDAndSession, /* commandID */ 1296 &sOperation, /* IN OUT operation */ 1297 &nErrorOrigin /* OUT returnOrigin, optional */ 1298 ); 1299 free(pBuffer); 1300 1301 if (teeErr != TEEC_SUCCESS) 1302 { 1303 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1304 teeErr : 1305 ckInternalTeeErrorToCKError(teeErr)); 1306 return nErrorCode; 1307 } 1308 1309 *phPublicKey = sOperation.params[0].value.a; 1310 *phPrivateKey = sOperation.params[0].value.b; 1311 1312 return CKR_OK; 1313 } 1314 1315 CK_RV PKCS11_EXPORT C_DeriveKey( 1316 CK_SESSION_HANDLE hSession, /* session's handle */ 1317 const CK_MECHANISM* pMechanism, /* key deriv. mech. */ 1318 CK_OBJECT_HANDLE hBaseKey, /* base key */ 1319 const CK_ATTRIBUTE* pTemplate, /* new key template */ 1320 CK_ULONG ulAttributeCount, /* template length */ 1321 CK_OBJECT_HANDLE* phKey) /* gets new handle */ 1322 { 1323 TEEC_Result teeErr; 1324 uint32_t nErrorOrigin; 1325 TEEC_Operation sOperation; 1326 CK_RV nErrorCode = CKR_OK; 1327 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_DERIVEKEY_COMMAND_ID; 1328 uint8_t* pBuffer = NULL; 1329 uint32_t nBufferSize = 0; 1330 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1331 1332 if ((pMechanism == NULL) || (pTemplate == NULL) || (phKey == NULL)) 1333 { 1334 return CKR_ARGUMENTS_BAD; 1335 } 1336 1337 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1338 if (nErrorCode != CKR_OK) 1339 { 1340 return nErrorCode; 1341 } 1342 1343 nErrorCode = static_encodeTemplate(&pBuffer, &nBufferSize, 2, (CK_ATTRIBUTE*)pTemplate, ulAttributeCount); 1344 if (nErrorCode != CKR_OK) 1345 { 1346 return nErrorCode; 1347 } 1348 1349 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1350 sOperation.params[0].value.a = (uint32_t)pMechanism->mechanism; 1351 sOperation.params[0].value.b = (uint32_t)hBaseKey; 1352 sOperation.params[1].tmpref.buffer = (uint8_t*)pMechanism->pParameter; 1353 sOperation.params[1].tmpref.size = (uint32_t)pMechanism->ulParameterLen; 1354 sOperation.params[2].tmpref.buffer = pBuffer; 1355 sOperation.params[2].tmpref.size = nBufferSize; 1356 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE); 1357 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1358 nCommandIDAndSession, /* commandID */ 1359 &sOperation, /* IN OUT operation */ 1360 &nErrorOrigin /* OUT returnOrigin, optional */ 1361 ); 1362 free(pBuffer); 1363 1364 if (teeErr != TEEC_SUCCESS) 1365 { 1366 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1367 teeErr : 1368 ckInternalTeeErrorToCKError(teeErr)); 1369 return nErrorCode; 1370 } 1371 1372 *phKey = sOperation.params[0].value.a; 1373 1374 return CKR_OK; 1375 } 1376 1377 CK_RV PKCS11_EXPORT C_SeedRandom( 1378 CK_SESSION_HANDLE hSession, /* the session's handle */ 1379 const CK_BYTE* pSeed, /* the seed material */ 1380 CK_ULONG ulSeedLen) /* count of bytes of seed material */ 1381 { 1382 TEEC_Result teeErr; 1383 uint32_t nErrorOrigin; 1384 TEEC_Operation sOperation; 1385 CK_RV nErrorCode = CKR_OK; 1386 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_SEEDRANDOM_COMMAND_ID; 1387 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1388 1389 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1390 if (nErrorCode != CKR_OK) 1391 { 1392 return nErrorCode; 1393 } 1394 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1395 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 1396 sOperation.params[0].tmpref.buffer = (uint8_t*)pSeed; 1397 sOperation.params[0].tmpref.size = (uint32_t)ulSeedLen; 1398 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1399 nCommandIDAndSession, /* commandID */ 1400 &sOperation, /* IN OUT operation */ 1401 &nErrorOrigin /* OUT returnOrigin, optional */ 1402 ); 1403 1404 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1405 teeErr : 1406 ckInternalTeeErrorToCKError(teeErr)); 1407 return nErrorCode; 1408 } 1409 1410 CK_RV PKCS11_EXPORT C_GenerateRandom( 1411 CK_SESSION_HANDLE hSession, /* the session's handle */ 1412 CK_BYTE* pRandomData, /* receives the random data */ 1413 CK_ULONG ulRandomLen) /* number of bytes to be generated */ 1414 { 1415 TEEC_Result teeErr; 1416 uint32_t nErrorOrigin; 1417 TEEC_Operation sOperation; 1418 CK_RV nErrorCode = CKR_OK; 1419 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_GENERATERANDOM_COMMAND_ID; 1420 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1421 1422 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1423 if (nErrorCode != CKR_OK) 1424 { 1425 return nErrorCode; 1426 } 1427 1428 do 1429 { 1430 CK_ULONG nArrayLength; 1431 nArrayLength = 1024; 1432 if (ulRandomLen < nArrayLength) 1433 { 1434 nArrayLength = ulRandomLen; 1435 } 1436 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1437 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 1438 sOperation.params[0].tmpref.buffer = (uint8_t*)pRandomData; 1439 sOperation.params[0].tmpref.size = (uint32_t)nArrayLength; 1440 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1441 nCommandIDAndSession, /* commandID */ 1442 &sOperation, /* IN OUT operation */ 1443 &nErrorOrigin /* OUT returnOrigin, optional */ 1444 ); 1445 if (teeErr != TEEC_SUCCESS) 1446 { 1447 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1448 teeErr : 1449 ckInternalTeeErrorToCKError(teeErr)); 1450 return nErrorCode; 1451 } 1452 1453 ulRandomLen -= nArrayLength; 1454 pRandomData += nArrayLength; 1455 if (ulRandomLen == 0) 1456 { 1457 break; 1458 } 1459 } 1460 while(1); 1461 1462 return CKR_OK; 1463 } 1464 1465 CK_RV PKCS11_EXPORT C_VerifyInit( 1466 CK_SESSION_HANDLE hSession, /* the session's handle */ 1467 const CK_MECHANISM* pMechanism, /* the verification mechanism */ 1468 CK_OBJECT_HANDLE hKey) /* handle of the verification key */ 1469 { 1470 return static_C_CallInit( 1471 SERVICE_SYSTEM_PKCS11_C_VERIFYINIT_COMMAND_ID, 1472 hSession, 1473 pMechanism, 1474 hKey); 1475 } 1476 1477 CK_RV PKCS11_EXPORT C_Verify( 1478 CK_SESSION_HANDLE hSession, /* the session's handle */ 1479 const CK_BYTE* pData, /* plaintext data (digest) to compare */ 1480 CK_ULONG ulDataLen, /* length of data (digest) in bytes */ 1481 CK_BYTE* pSignature, /* the signature to be verified */ 1482 CK_ULONG ulSignatureLen) /* count of bytes of signature */ 1483 { 1484 TEEC_Result teeErr; 1485 uint32_t nErrorOrigin; 1486 TEEC_Operation sOperation; 1487 CK_RV nErrorCode = CKR_OK; 1488 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_VERIFY_COMMAND_ID; 1489 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1490 1491 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1492 if (nErrorCode != CKR_OK) 1493 { 1494 return nErrorCode; 1495 } 1496 1497 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1498 sOperation.params[0].tmpref.buffer = (uint8_t*)pData; 1499 sOperation.params[0].tmpref.size = (uint32_t)ulDataLen; 1500 sOperation.params[1].tmpref.buffer = (uint8_t*)pSignature; 1501 sOperation.params[1].tmpref.size = (uint32_t)ulSignatureLen; 1502 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); 1503 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1504 nCommandIDAndSession, /* commandID */ 1505 &sOperation, /* IN OUT operation */ 1506 &nErrorOrigin /* OUT returnOrigin, optional */ 1507 ); 1508 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1509 teeErr : 1510 ckInternalTeeErrorToCKError(teeErr)); 1511 return nErrorCode; 1512 } 1513 1514 CK_RV PKCS11_EXPORT C_VerifyUpdate( 1515 CK_SESSION_HANDLE hSession, /* the session's handle */ 1516 const CK_BYTE* pPart, /* plaintext data (digest) to compare */ 1517 CK_ULONG ulPartLen) /* length of data (digest) in bytes */ 1518 { 1519 return static_C_Call_CallForUpdate( 1520 SERVICE_SYSTEM_PKCS11_C_VERIFYUPDATE_COMMAND_ID, 1521 hSession, 1522 pPart, 1523 ulPartLen, 1524 NULL, 1525 NULL, 1526 TRUE, 1527 FALSE); 1528 } 1529 1530 CK_RV PKCS11_EXPORT C_VerifyFinal( 1531 CK_SESSION_HANDLE hSession, /* the session's handle */ 1532 const CK_BYTE* pSignature, /* the signature to be verified */ 1533 CK_ULONG ulSignatureLen) /* count of bytes of signature */ 1534 { 1535 return static_C_Call_CallForUpdate( 1536 SERVICE_SYSTEM_PKCS11_C_VERIFYFINAL_COMMAND_ID, 1537 hSession, 1538 pSignature, 1539 ulSignatureLen, 1540 NULL, 1541 NULL, 1542 TRUE, 1543 FALSE); 1544 } 1545 1546 CK_RV PKCS11_EXPORT C_CloseObjectHandle( 1547 CK_SESSION_HANDLE hSession, /* the session's handle */ 1548 CK_OBJECT_HANDLE hObject) /* the object's handle */ 1549 { 1550 TEEC_Result teeErr; 1551 uint32_t nErrorOrigin; 1552 TEEC_Operation sOperation; 1553 CK_RV nErrorCode = CKR_OK; 1554 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_CLOSEOBJECTHANDLE_COMMAND_ID; 1555 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1556 1557 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1558 if (nErrorCode != CKR_OK) 1559 { 1560 return nErrorCode; 1561 } 1562 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1563 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 1564 sOperation.params[0].value.a = (uint32_t)hObject; 1565 sOperation.params[0].value.b = 0; 1566 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1567 nCommandIDAndSession, /* commandID */ 1568 &sOperation, /* IN OUT operation */ 1569 &nErrorOrigin /* OUT returnOrigin, optional */ 1570 ); 1571 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1572 teeErr : 1573 ckInternalTeeErrorToCKError(teeErr)); 1574 return nErrorCode; 1575 } 1576 1577 CK_RV PKCS11_EXPORT C_CopyObject( 1578 CK_SESSION_HANDLE hSession, /* the session's handle */ 1579 CK_OBJECT_HANDLE hObject, /* the source object's handle */ 1580 const CK_ATTRIBUTE* pTemplate, /* the template of the copied object */ 1581 CK_ULONG ulCount, /* the number of attributes of the template*/ 1582 CK_OBJECT_HANDLE* phNewObject) /* the copied object's handle */ 1583 { 1584 TEEC_Result teeErr; 1585 uint32_t nErrorOrigin; 1586 TEEC_Operation sOperation; 1587 CK_RV nErrorCode = CKR_OK; 1588 uint32_t nCommandIDAndSession = SERVICE_SYSTEM_PKCS11_C_COPYOBJECT_COMMAND_ID; 1589 uint8_t* pBuffer = NULL; 1590 uint32_t nBufferSize = 0; 1591 PPKCS11_PRIMARY_SESSION_CONTEXT pSession; 1592 1593 if ((pTemplate == NULL) || (phNewObject == NULL)) 1594 { 1595 return CKR_ARGUMENTS_BAD; 1596 } 1597 1598 nErrorCode = static_checkPreConditionsAndUpdateHandles(&hSession, &nCommandIDAndSession, &pSession); 1599 if (nErrorCode != CKR_OK) 1600 { 1601 return nErrorCode; 1602 } 1603 1604 nErrorCode = static_encodeTemplate(&pBuffer, &nBufferSize, 1, (CK_ATTRIBUTE*)pTemplate, ulCount); 1605 if (nErrorCode != CKR_OK) 1606 { 1607 return nErrorCode; 1608 } 1609 1610 memset(&sOperation, 0, sizeof(TEEC_Operation)); 1611 sOperation.params[0].value.a = (uint32_t)hObject; 1612 sOperation.params[0].value.b = 0; 1613 sOperation.params[1].tmpref.buffer = pBuffer; 1614 sOperation.params[1].tmpref.size = nBufferSize; 1615 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); 1616 teeErr = TEEC_InvokeCommand( &pSession->sSession, 1617 nCommandIDAndSession, /* commandID */ 1618 &sOperation, /* IN OUT operation */ 1619 &nErrorOrigin /* OUT returnOrigin, optional */ 1620 ); 1621 free(pBuffer); 1622 1623 if (teeErr != TEEC_SUCCESS) 1624 { 1625 nErrorCode = (nErrorOrigin == TEEC_ORIGIN_TRUSTED_APP ? 1626 teeErr : 1627 ckInternalTeeErrorToCKError(teeErr)); 1628 return nErrorCode; 1629 } 1630 1631 *phNewObject = sOperation.params[0].value.a; 1632 1633 return CKR_OK; 1634 } 1635