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