• 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 /******************************************/
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