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 /******************************************/
97 /* The buffer must be freed by the caller */
98 /******************************************/
static_encodeTwoTemplates(uint8_t ** ppBuffer,uint32_t * pBufferSize,const uint32_t nParamIndex,CK_ATTRIBUTE * pTemplate1,CK_ULONG ulCount1,CK_ATTRIBUTE * pTemplate2,CK_ULONG ulCount2)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 /******************************************/
static_encodeTemplate(uint8_t ** ppBuffer,uint32_t * pBufferSize,const uint32_t nParamIndex,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)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
static_C_CallInit(uint32_t nCommandID,CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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 */
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)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 */
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)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 */
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)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 */
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)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
C_CreateObject(CK_SESSION_HANDLE hSession,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE * phObject)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
C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)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
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)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
C_FindObjectsInit(CK_SESSION_HANDLE hSession,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)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
C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE * phObject,CK_ULONG ulMaxObjectCount,CK_ULONG * pulObjectCount)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
C_FindObjectsFinal(CK_SESSION_HANDLE hSession)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
C_DigestInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism)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
C_Digest(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pDigest,CK_ULONG * pulDigestLen)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
C_DigestUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen)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
C_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pDigest,CK_ULONG * pulDigestLen)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
C_SignInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Sign(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pSignature,CK_ULONG * pulSignatureLen)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
C_SignUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen)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
C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pSignature,CK_ULONG * pulSignatureLen)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
C_EncryptInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Encrypt(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pEncryptedData,CK_ULONG * pulEncryptedDataLen)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
C_EncryptUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen,CK_BYTE * pEncryptedPart,CK_ULONG * pulEncryptedPartLen)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
C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pLastEncryptedPart,CK_ULONG * pulLastEncryptedPartLen)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
C_DecryptInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Decrypt(CK_SESSION_HANDLE hSession,const CK_BYTE * pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE * pData,CK_ULONG * pulDataLen)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
C_DecryptUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE * pPart,CK_ULONG * pulPartLen)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
C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE * pLastPart,CK_ULONG * pulLastPartLen)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
C_GenerateKey(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE * phKey)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
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)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
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)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
C_SeedRandom(CK_SESSION_HANDLE hSession,const CK_BYTE * pSeed,CK_ULONG ulSeedLen)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
C_GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE * pRandomData,CK_ULONG ulRandomLen)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
C_VerifyInit(CK_SESSION_HANDLE hSession,const CK_MECHANISM * pMechanism,CK_OBJECT_HANDLE hKey)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
C_Verify(CK_SESSION_HANDLE hSession,const CK_BYTE * pData,CK_ULONG ulDataLen,CK_BYTE * pSignature,CK_ULONG ulSignatureLen)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
C_VerifyUpdate(CK_SESSION_HANDLE hSession,const CK_BYTE * pPart,CK_ULONG ulPartLen)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
C_VerifyFinal(CK_SESSION_HANDLE hSession,const CK_BYTE * pSignature,CK_ULONG ulSignatureLen)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
C_CloseObjectHandle(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)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
C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,const CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE * phNewObject)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