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 */
static_checkPreConditionsAndUpdateHandles(CK_SESSION_HANDLE * phSession,uint32_t * phCommandIDAndSession,PPKCS11_PRIMARY_SESSION_CONTEXT * ppSession)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 */
static_analyzeTemplate(uint32_t * const pDataOffset,uint32_t * const pBufferSize,const CK_ATTRIBUTE * const pTemplate,CK_ULONG const ulCount)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
static_copyTemplate(uint8_t * const pBuffer,uint32_t const nParamIndex,uint8_t ** const ppAttributeCursor,uint8_t ** const ppDataCursor,const CK_ATTRIBUTE * const pTemplate,CK_ULONG const ulCount)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 /******************************************/
static_encodeTwoTemplates(uint8_t ** ppBuffer,uint32_t * pBufferSize,const uint32_t nParamIndex,const CK_ATTRIBUTE * pTemplate1,CK_ULONG ulCount1,const CK_ATTRIBUTE * pTemplate2,CK_ULONG ulCount2)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 /******************************************/
static_encodeTemplate(uint8_t ** ppBuffer,uint32_t * pBufferSize,const uint32_t nParamIndex,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)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
static_C_CallInit(uint32_t nCommandID,CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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 */
static_C_CallForSingle(uint32_t nCommandID,CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pResult,CK_ULONG * pulResultLen,bool bSend,bool bReceive)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 */
static_C_CallUpdate(uint32_t nCommandID,CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pResult,CK_ULONG * pulResultLen,bool bSend,bool bReceive)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 */
static_C_CallSplitUpdate(uint32_t nCommandID,CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pResult,CK_ULONG * pulResultLen,bool bSend,bool bReceive,uint32_t nChunkSize)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 */
static_C_Call_CallForUpdate(uint32_t nCommandID,CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pResult,CK_ULONG * pulResultLen,bool bSend,bool bReceive)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
C_CreateObject(CK_SESSION_HANDLE hSession,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE * phObject)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
C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)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
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)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
C_FindObjectsInit(CK_SESSION_HANDLE hSession,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)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
C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE * phObject,CK_ULONG ulMaxObjectCount,CK_ULONG * pulObjectCount)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
C_FindObjectsFinal(CK_SESSION_HANDLE hSession)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
C_DigestInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism)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
C_Digest(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pDigest,CK_ULONG * pulDigestLen)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
C_DigestUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen)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
C_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pDigest,CK_ULONG * pulDigestLen)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
C_SignInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Sign(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pSignature,CK_ULONG * pulSignatureLen)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
C_SignUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen)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
C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pSignature,CK_ULONG * pulSignatureLen)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
C_EncryptInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Encrypt(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pEncryptedData,CK_ULONG * pulEncryptedDataLen)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
C_EncryptUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen,CK_BYTE * pEncryptedPart,CK_ULONG * pulEncryptedPartLen)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
C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pLastEncryptedPart,CK_ULONG * pulLastEncryptedPartLen)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
C_DecryptInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Decrypt(CK_SESSION_HANDLE hSession,const CK_BYTE * pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE * pData,CK_ULONG * pulDataLen)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
C_DecryptUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE * pPart,CK_ULONG * pulPartLen)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
C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pLastPart,CK_ULONG * pulLastPartLen)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
C_GenerateKey(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE * phKey)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
C_GenerateKeyPair(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,const CK_ATTRIBUTE * pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,const CK_ATTRIBUTE * pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE * phPublicKey,CK_OBJECT_HANDLE * phPrivateKey)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
C_DeriveKey(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hBaseKey,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulAttributeCount,CK_OBJECT_HANDLE * phKey)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
C_SeedRandom(CK_SESSION_HANDLE hSession,const CK_BYTE * pSeed,CK_ULONG ulSeedLen)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
C_GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE * pRandomData,CK_ULONG ulRandomLen)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
C_VerifyInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Verify(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pSignature,CK_ULONG ulSignatureLen)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
C_VerifyUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen)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
C_VerifyFinal(CK_SESSION_HANDLE hSession,const CK_BYTE * pSignature,CK_ULONG ulSignatureLen)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
C_CloseObjectHandle(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)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
C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE * phNewObject)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