• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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