1 /*
2  * FreeRTOS V202212.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26 
27 #include "logging_levels.h"
28 
29 #define LIBRARY_LOG_NAME     "MbedTLSPkP11"
30 #define LIBRARY_LOG_LEVEL    LOG_ERROR
31 
32 #include "logging_stack.h"
33 
34 /**
35  * @file mbedtls_pk_pkcs11.c
36  * @brief mbedtls_pk implementation for pkcs11 ECDSA and RSA keys.
37  *           Exports a mbedtls_pk_info_t type.
38  */
39 
40 #include <string.h>
41 
42 /* Mbedtls Includes */
43 #ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS
44     #define MBEDTLS_ALLOW_PRIVATE_ACCESS
45 #endif /* MBEDTLS_ALLOW_PRIVATE_ACCESS */
46 
47 /* MBedTLS Includes */
48 #if !defined( MBEDTLS_CONFIG_FILE )
49     #include "mbedtls/mbedtls_config.h"
50 #else
51     #include MBEDTLS_CONFIG_FILE
52 #endif
53 
54 #ifdef MBEDTLS_PSA_CRYPTO_C
55     /* MbedTLS PSA Includes */
56     #include "psa/crypto.h"
57     #include "psa/crypto_values.h"
58 #endif /* MBEDTLS_PSA_CRYPTO_C */
59 
60 #include "mbedtls/pk.h"
61 #include "mbedtls/asn1.h"
62 #include "mbedtls/x509_crt.h"
63 #include "mbedtls/platform.h"
64 #include "mbedtls/asn1write.h"
65 #include "mbedtls/ecdsa.h"
66 #include "pk_wrap.h"
67 
68 #include "core_pkcs11_config.h"
69 #include "core_pkcs11.h"
70 
71 /* PKCS11 Includes */
72 #include "pkcs11t.h"
73 
74 /*-----------------------------------------------------------*/
75 
76 typedef struct P11PkCtx
77 {
78     CK_FUNCTION_LIST_PTR pxFunctionList;
79     CK_SESSION_HANDLE xSessionHandle;
80     CK_OBJECT_HANDLE xPkHandle;
81 } P11PkCtx_t;
82 
83 typedef struct P11EcDsaCtx
84 {
85     mbedtls_ecdsa_context xMbedEcDsaCtx;
86     P11PkCtx_t xP11PkCtx;
87 } P11EcDsaCtx_t;
88 
89 typedef struct P11RsaCtx
90 {
91     mbedtls_rsa_context xMbedRsaCtx;
92     P11PkCtx_t xP11PkCtx;
93 } P11RsaCtx_t;
94 
95 /*-----------------------------------------------------------*/
96 
97 /**
98  * @brief Allocates a P11EcDsaCtx_t
99  *
100  * @return A void pointer to the newly created P11EcDsaCtx_t.
101  */
102 static void * p11_ecdsa_ctx_alloc( void );
103 
104 /**
105  * @brief Initializes a P11EcDsaCtx_t with the given PKCS11 parameters.
106  *
107  * @param pvCtx Void pointer to the P11EcDsaCtx_t.
108  * @param pxFunctionList Pointer to a CK_FUNCTION_LIST for the PKCS11 module.
109  * @param xSessionHandle An initialized CK_SESSION_HANDLE for the given PKCS11 module.
110  * @param xPkHandle The CK_OBJECT_HANDLE for the target private key.
111  * @return CKR_OK on success
112  */
113 static CK_RV p11_ecdsa_ctx_init( mbedtls_pk_context * pxMbedtlsPkCtx,
114                                  CK_FUNCTION_LIST_PTR pxFunctionList,
115                                  CK_SESSION_HANDLE xSessionHandle,
116                                  CK_OBJECT_HANDLE xPkHandle );
117 
118 /**
119  * @brief Frees a P11EcDsaCtx_t
120  *
121  * @param pvCtx void pointer to the context to be freed.
122  */
123 static void p11_ecdsa_ctx_free( void * pvCtx );
124 
125 /**
126  * @brief Perform an ecdsa sign operation with the given P11EcDsaCtx_t.
127  *
128  * @param pvCtx Void pointer to the relevant P11EcDsaCtx_t
129  * @param xMdAlg Hashing algorithm used to generate pucHash
130  * @param pucHash Pointer to a buffer containing the has of the data to be signed
131  * @param xHashLen Length of the hash of data to be signed
132  * @param pucSig Pointer to a buffer in which the signature should be stored
133  * @param xSigBufferSize Length of the buffer provided in pucSig
134  * @param pxSigLen Pointer to a size_t in which the length of the generated signature will be stored
135  * @param plRng Function pointer to the RNG function
136  * @param pvRng Void pointer to the RNG function context
137  * @return 0 on success
138  * @return A negative number on failure
139  */
140 static int p11_ecdsa_sign( mbedtls_pk_context * pk,
141                            mbedtls_md_type_t xMdAlg,
142                            const unsigned char * pucHash,
143                            size_t xHashLen,
144                            unsigned char * pucSig,
145                            size_t xSigBufferSize,
146                            size_t * pxSigLen,
147                            int ( * plRng )( void *, unsigned char *, size_t ),
148                            void * pvRng );
149 
150 /**
151  * @brief Get the bit length of the relevant key.
152  *
153  * @param pvCtx Void pointer to the relevant P11EcDsaCtx_t.
154  * @return size_t Bit length of the key.
155  */
156 static size_t p11_ecdsa_get_bitlen( mbedtls_pk_context * pxMbedtlsPkCtx );
157 
158 /**
159  * @brief Returns true if the pk context can perform the given pk operation.
160  *
161  * @param xType Type of operation.
162  * @return int 0 if the key is an ecdsa key.
163  */
164 static int p11_ecdsa_can_do( mbedtls_pk_type_t xType );
165 
166 /**
167  * @brief Perform an ECDSA verify operation with the given pk context.
168  *
169  * @note Validates that the signature given in the pucSig and xSigLen arguments
170  * matches the hash given in pucHash and xSigLen for the P11EcDsaCtx_t
171  * specified in pvCtx.
172  *
173  * @param pvCtx Void pointer to the relevant P11EcDsaCtx_t
174  * @param xMdAlg The hashing algorithm used to generate pucHash
175  * @param pucHash Pointer to a buffer containing the hash to validate against
176  * @param xHashLen Length of the hash in pucHash
177  * @param pucSig Pointer to a buffer containing the signature to validate
178  * @param xSigLen Length of the signature given in pucSig
179  * @return 0 on success
180  */
181 static int p11_ecdsa_verify( mbedtls_pk_context * pxMbedtlsPkCtx,
182                              mbedtls_md_type_t xMdAlg,
183                              const unsigned char * pucHash,
184                              size_t xHashLen,
185                              const unsigned char * pucSig,
186                              size_t xSigLen );
187 
188 static int p11_ecdsa_check_pair( mbedtls_pk_context * pxPub,
189                                  mbedtls_pk_context * pxMbedtlsPkCtx,
190                                  int ( * lFRng )( void *, unsigned char *, size_t ),
191                                  void * pvPRng );
192 
193 static void p11_ecdsa_debug( mbedtls_pk_context * pxMbedtlsPkCtx,
194                              mbedtls_pk_debug_item * pxItems );
195 
196 static int prvEcdsaSigToASN1InPlace( unsigned char * pucSig,
197                                      size_t xSigBufferSize,
198                                      size_t * pxSigLen );
199 
200 static int prvASN1WriteBigIntFromOctetStr( unsigned char ** ppucPosition,
201                                            const unsigned char * pucStart,
202                                            const unsigned char * pucOctetStr,
203                                            size_t xOctetStrLen );
204 
205 /**
206  * @brief mbedtls_pk_info_t struct for PKCS#11 ECDSA operations.
207  */
208 mbedtls_pk_info_t mbedtls_pkcs11_pk_ecdsa =
209 {
210     .type               = MBEDTLS_PK_ECKEY,
211     .name               = "PKCS#11",
212     .get_bitlen         = p11_ecdsa_get_bitlen,
213     .can_do             = p11_ecdsa_can_do,
214     .verify_func        = p11_ecdsa_verify,
215     .sign_func          = p11_ecdsa_sign,
216     #if defined( MBEDTLS_ECDSA_C ) && defined( MBEDTLS_ECP_RESTARTABLE )
217         .verify_rs_func = NULL,
218         .sign_rs_func   = NULL,
219     #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
220     .decrypt_func       = NULL,
221     .encrypt_func       = NULL,
222     .check_pair_func    = p11_ecdsa_check_pair,
223     .ctx_alloc_func     = p11_ecdsa_ctx_alloc,
224     .ctx_free_func      = p11_ecdsa_ctx_free,
225     #if defined( MBEDTLS_ECDSA_C ) && defined( MBEDTLS_ECP_RESTARTABLE )
226         .rs_alloc_func  = NULL,
227         .rs_free_func   = NULL,
228     #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
229     .debug_func         = p11_ecdsa_debug,
230 };
231 
232 /*-----------------------------------------------------------*/
233 
234 static size_t p11_rsa_get_bitlen( mbedtls_pk_context * ctx );
235 
236 static int p11_rsa_can_do( mbedtls_pk_type_t xType );
237 
238 static int p11_rsa_verify( mbedtls_pk_context * pxMbedtlsPkCtx,
239                            mbedtls_md_type_t xMdAlg,
240                            const unsigned char * pucHash,
241                            size_t xHashLen,
242                            const unsigned char * pucSig,
243                            size_t xSigLen );
244 
245 static int p11_rsa_sign( mbedtls_pk_context * pk,
246                          mbedtls_md_type_t md_alg,
247                          const unsigned char * hash,
248                          size_t hash_len,
249                          unsigned char * sig,
250                          size_t sig_size,
251                          size_t * sig_len,
252                          int ( * f_rng )( void *, unsigned char *, size_t ),
253                          void * p_rng );
254 
255 static int p11_rsa_check_pair( mbedtls_pk_context * pvPub,
256                                mbedtls_pk_context * pxMbedtlsPkCtx,
257                                int ( * lFRng )( void *, unsigned char *, size_t ),
258                                void * pvPRng );
259 
260 static void * p11_rsa_ctx_alloc( void );
261 
262 static CK_RV p11_rsa_ctx_init( mbedtls_pk_context * pk,
263                                CK_FUNCTION_LIST_PTR pxFunctionList,
264                                CK_SESSION_HANDLE xSessionHandle,
265                                CK_OBJECT_HANDLE xPkHandle );
266 
267 static void p11_rsa_ctx_free( void * pvCtx );
268 
269 static void p11_rsa_debug( mbedtls_pk_context * pxMbedtlsPkCtx,
270                            mbedtls_pk_debug_item * pxItems );
271 
272 /*-----------------------------------------------------------*/
273 
274 /**
275  * @brief mbedtls_pk_info_t struct for PKCS#11 RSA operations.
276  */
277 mbedtls_pk_info_t mbedtls_pkcs11_pk_rsa =
278 {
279     .type               = MBEDTLS_PK_RSA,
280     .name               = "PKCS#11",
281     .get_bitlen         = p11_rsa_get_bitlen,
282     .can_do             = p11_rsa_can_do,
283     .verify_func        = p11_rsa_verify,
284     .sign_func          = p11_rsa_sign,
285     #if defined( MBEDTLS_ECDSA_C ) && defined( MBEDTLS_ECP_RESTARTABLE )
286         .verify_rs_func = NULL,
287         .sign_rs_func   = NULL,
288     #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
289     .decrypt_func       = NULL,
290     .encrypt_func       = NULL,
291     .check_pair_func    = p11_rsa_check_pair,
292     .ctx_alloc_func     = p11_rsa_ctx_alloc,
293     .ctx_free_func      = p11_rsa_ctx_free,
294     #if defined( MBEDTLS_ECDSA_C ) && defined( MBEDTLS_ECP_RESTARTABLE )
295         .rs_alloc_func  = NULL,
296         .rs_free_func   = NULL,
297     #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
298     .debug_func         = p11_rsa_debug,
299 };
300 
301 /*-----------------------------------------------------------*/
302 
xPKCS11_initMbedtlsPkContext(mbedtls_pk_context * pxMbedtlsPkCtx,CK_SESSION_HANDLE xSessionHandle,CK_OBJECT_HANDLE xPkHandle)303 CK_RV xPKCS11_initMbedtlsPkContext( mbedtls_pk_context * pxMbedtlsPkCtx,
304                                     CK_SESSION_HANDLE xSessionHandle,
305                                     CK_OBJECT_HANDLE xPkHandle )
306 {
307     CK_RV xResult = CKR_OK;
308 
309     CK_KEY_TYPE xKeyType = CKK_VENDOR_DEFINED;
310     CK_FUNCTION_LIST_PTR pxFunctionList = NULL;
311 
312     if( pxMbedtlsPkCtx == NULL )
313     {
314         xResult = CKR_ARGUMENTS_BAD;
315     }
316     else if( xSessionHandle == CK_INVALID_HANDLE )
317     {
318         xResult = CKR_SESSION_HANDLE_INVALID;
319     }
320     else if( xPkHandle == CK_INVALID_HANDLE )
321     {
322         xResult = CKR_KEY_HANDLE_INVALID;
323     }
324     else if( ( C_GetFunctionList( &pxFunctionList ) != CKR_OK ) ||
325              ( pxFunctionList == NULL ) ||
326              ( pxFunctionList->C_GetAttributeValue == NULL ) )
327     {
328         xResult = CKR_FUNCTION_FAILED;
329     }
330     /* Determine key type */
331     else
332     {
333         CK_ATTRIBUTE xAttrTemplate =
334         {
335             .pValue     = &xKeyType,
336             .type       = CKA_KEY_TYPE,
337             .ulValueLen = sizeof( CK_KEY_TYPE )
338         };
339 
340         xResult = pxFunctionList->C_GetAttributeValue( xSessionHandle,
341                                                        xPkHandle,
342                                                        &xAttrTemplate,
343                                                        sizeof( xAttrTemplate ) / sizeof( CK_ATTRIBUTE ) );
344     }
345 
346     if( xResult == CKR_OK )
347     {
348         xResult = CKR_FUNCTION_FAILED;
349 
350         switch( xKeyType )
351         {
352             case CKK_ECDSA:
353                 pxMbedtlsPkCtx->pk_ctx = p11_ecdsa_ctx_alloc();
354 
355                 if( pxMbedtlsPkCtx->pk_ctx != NULL )
356                 {
357                     xResult = p11_ecdsa_ctx_init( pxMbedtlsPkCtx->pk_ctx,
358                                                   pxFunctionList, xSessionHandle, xPkHandle );
359                 }
360 
361                 if( xResult == CKR_OK )
362                 {
363                     pxMbedtlsPkCtx->pk_info = &mbedtls_pkcs11_pk_ecdsa;
364                 }
365                 else
366                 {
367                     p11_ecdsa_ctx_free( pxMbedtlsPkCtx->pk_ctx );
368                     pxMbedtlsPkCtx->pk_ctx = NULL;
369                     pxMbedtlsPkCtx->pk_info = NULL;
370                 }
371 
372                 break;
373 
374             case CKK_RSA:
375                 pxMbedtlsPkCtx->pk_ctx = p11_rsa_ctx_alloc();
376 
377                 if( pxMbedtlsPkCtx->pk_ctx != NULL )
378                 {
379                     xResult = p11_rsa_ctx_init( pxMbedtlsPkCtx->pk_ctx,
380                                                 pxFunctionList, xSessionHandle, xPkHandle );
381                 }
382 
383                 if( xResult == CKR_OK )
384                 {
385                     pxMbedtlsPkCtx->pk_info = &mbedtls_pkcs11_pk_rsa;
386                 }
387                 else
388                 {
389                     p11_rsa_ctx_free( pxMbedtlsPkCtx->pk_ctx );
390                     pxMbedtlsPkCtx->pk_ctx = NULL;
391                     pxMbedtlsPkCtx->pk_info = NULL;
392                 }
393 
394                 break;
395 
396             default:
397                 pxMbedtlsPkCtx->pk_ctx = NULL;
398                 pxMbedtlsPkCtx->pk_info = NULL;
399                 break;
400         }
401     }
402 
403     return xResult;
404 }
405 
406 /*-----------------------------------------------------------*/
407 
p11_ecdsa_ctx_alloc(void)408 static void * p11_ecdsa_ctx_alloc( void )
409 {
410     void * pvCtx = NULL;
411 
412     pvCtx = mbedtls_calloc( 1, sizeof( P11EcDsaCtx_t ) );
413 
414     if( pvCtx != NULL )
415     {
416         P11EcDsaCtx_t * pxP11EcDsa = ( P11EcDsaCtx_t * ) pvCtx;
417 
418         /* Initialize other fields */
419         pxP11EcDsa->xP11PkCtx.pxFunctionList = NULL;
420         pxP11EcDsa->xP11PkCtx.xSessionHandle = CK_INVALID_HANDLE;
421         pxP11EcDsa->xP11PkCtx.xPkHandle = CK_INVALID_HANDLE;
422 
423         mbedtls_ecdsa_init( &( pxP11EcDsa->xMbedEcDsaCtx ) );
424     }
425 
426     return pvCtx;
427 }
428 
p11_ecdsa_ctx_free(void * pvCtx)429 static void p11_ecdsa_ctx_free( void * pvCtx )
430 {
431     if( pvCtx != NULL )
432     {
433         P11EcDsaCtx_t * pxP11EcDsa = ( P11EcDsaCtx_t * ) pvCtx;
434 
435         mbedtls_ecdsa_free( &( pxP11EcDsa->xMbedEcDsaCtx ) );
436 
437         mbedtls_free( pvCtx );
438     }
439 }
440 
441 /*-----------------------------------------------------------*/
442 
p11_ecdsa_ctx_init(mbedtls_pk_context * pk,CK_FUNCTION_LIST_PTR pxFunctionList,CK_SESSION_HANDLE xSessionHandle,CK_OBJECT_HANDLE xPkHandle)443 static CK_RV p11_ecdsa_ctx_init( mbedtls_pk_context * pk,
444                                  CK_FUNCTION_LIST_PTR pxFunctionList,
445                                  CK_SESSION_HANDLE xSessionHandle,
446                                  CK_OBJECT_HANDLE xPkHandle )
447 {
448     CK_RV xResult = CKR_OK;
449     P11EcDsaCtx_t * pxP11EcDsaCtx = ( P11EcDsaCtx_t * ) pk;
450     mbedtls_ecdsa_context * pxMbedEcDsaCtx = NULL;
451 
452     configASSERT( pxFunctionList != NULL );
453     configASSERT( xSessionHandle != CK_INVALID_HANDLE );
454     configASSERT( xPkHandle != CK_INVALID_HANDLE );
455 
456     if( pxP11EcDsaCtx != NULL )
457     {
458         pxMbedEcDsaCtx = &( pxP11EcDsaCtx->xMbedEcDsaCtx );
459     }
460     else
461     {
462         LogError( ( "Received a NULL mbedtls_pk_context" ) );
463         xResult = CKR_FUNCTION_FAILED;
464     }
465 
466     if( xResult == CKR_OK )
467     {
468         /* Initialize public EC parameter data from attributes */
469         CK_ATTRIBUTE pxAttrs[ 2 ] =
470         {
471             { .type = CKA_EC_PARAMS, .ulValueLen = 0, .pValue = NULL },
472             { .type = CKA_EC_POINT,  .ulValueLen = 0, .pValue = NULL }
473         };
474 
475         /* Determine necessary size */
476         xResult = pxFunctionList->C_GetAttributeValue( xSessionHandle,
477                                                        xPkHandle,
478                                                        pxAttrs,
479                                                        sizeof( pxAttrs ) / sizeof( CK_ATTRIBUTE ) );
480 
481         if( xResult == CKR_OK )
482         {
483             if( pxAttrs[ 0 ].ulValueLen > 0 )
484             {
485                 pxAttrs[ 0 ].pValue = pvPortMalloc( pxAttrs[ 0 ].ulValueLen );
486             }
487 
488             if( pxAttrs[ 1 ].ulValueLen > 0 )
489             {
490                 pxAttrs[ 1 ].pValue = pvPortMalloc( pxAttrs[ 1 ].ulValueLen );
491             }
492 
493             xResult = pxFunctionList->C_GetAttributeValue( xSessionHandle,
494                                                            xPkHandle,
495                                                            pxAttrs,
496                                                            2 );
497         }
498 
499         /* Parse EC Group */
500         if( xResult == CKR_OK )
501         {
502             /*TODO: Parse the ECParameters object */
503             int lResult = mbedtls_ecp_group_load( &( pxMbedEcDsaCtx->grp ), MBEDTLS_ECP_DP_SECP256R1 );
504 
505             if( lResult != 0 )
506             {
507                 xResult = CKR_FUNCTION_FAILED;
508             }
509         }
510 
511         /* Parse ECPoint */
512         if( xResult == CKR_OK )
513         {
514             unsigned char * pucIterator = pxAttrs[ 1 ].pValue;
515             size_t uxLen = pxAttrs[ 1 ].ulValueLen;
516             int lResult = 0;
517 
518             lResult = mbedtls_asn1_get_tag( &pucIterator, &( pucIterator[ uxLen ] ), &uxLen, MBEDTLS_ASN1_OCTET_STRING );
519 
520             if( lResult != 0 )
521             {
522                 xResult = CKR_GENERAL_ERROR;
523             }
524             else
525             {
526                 lResult = mbedtls_ecp_point_read_binary( &( pxMbedEcDsaCtx->grp ),
527                                                          &( pxMbedEcDsaCtx->Q ),
528                                                          pucIterator,
529                                                          uxLen );
530             }
531 
532             if( lResult != 0 )
533             {
534                 xResult = CKR_GENERAL_ERROR;
535             }
536         }
537 
538         if( pxAttrs[ 0 ].pValue != NULL )
539         {
540             vPortFree( pxAttrs[ 0 ].pValue );
541         }
542 
543         if( pxAttrs[ 1 ].pValue != NULL )
544         {
545             vPortFree( pxAttrs[ 1 ].pValue );
546         }
547 
548         if( xResult == CKR_OK )
549         {
550             pxP11EcDsaCtx->xP11PkCtx.pxFunctionList = pxFunctionList;
551             pxP11EcDsaCtx->xP11PkCtx.xSessionHandle = xSessionHandle;
552             pxP11EcDsaCtx->xP11PkCtx.xPkHandle = xPkHandle;
553         }
554     }
555 
556     return xResult;
557 }
558 
559 /*-----------------------------------------------------------*/
560 
prvASN1WriteBigIntFromOctetStr(unsigned char ** ppucPosition,const unsigned char * pucStart,const unsigned char * pucOctetStr,size_t uxOctetStrLen)561 static int prvASN1WriteBigIntFromOctetStr( unsigned char ** ppucPosition,
562                                            const unsigned char * pucStart,
563                                            const unsigned char * pucOctetStr,
564                                            size_t uxOctetStrLen )
565 {
566     size_t uxRequiredLen = 0;
567     int lReturn = 0;
568 
569     /* Check if zero byte is needed at beginning */
570     if( pucOctetStr[ 0 ] > 0x7F )
571     {
572         uxRequiredLen = uxOctetStrLen + 1;
573     }
574     else
575     {
576         uxRequiredLen = uxOctetStrLen;
577     }
578 
579     if( ( *ppucPosition - uxRequiredLen ) >= pucStart )
580     {
581         *ppucPosition = *ppucPosition - uxOctetStrLen;
582 
583         /* Copy octet string */
584         ( void ) memcpy( *ppucPosition, pucOctetStr, uxOctetStrLen );
585 
586         /* Prepend additional byte if necessary */
587         if( pucOctetStr[ 0 ] > 0x7F )
588         {
589             *ppucPosition = &( ( *ppucPosition )[ -1 ] );
590             **ppucPosition = 0;
591         }
592 
593         lReturn = mbedtls_asn1_write_len( ppucPosition, pucStart, uxRequiredLen );
594 
595         if( lReturn > 0 )
596         {
597             uxRequiredLen += ( size_t ) lReturn;
598             lReturn = mbedtls_asn1_write_tag( ppucPosition, pucStart, MBEDTLS_ASN1_INTEGER );
599         }
600 
601         if( lReturn > 0 )
602         {
603             lReturn = ( size_t ) lReturn + uxRequiredLen;
604         }
605     }
606 
607     return lReturn;
608 }
609 
610 /*-----------------------------------------------------------*/
611 
612 /*
613  * SEQUENCE LENGTH (of entire rest of signature)
614  *      INTEGER LENGTH  (of R component)
615  *      INTEGER LENGTH  (of S component)
616  */
prvEcdsaSigToASN1InPlace(unsigned char * pucSig,size_t xSigBufferSize,size_t * pxSigLen)617 static int prvEcdsaSigToASN1InPlace( unsigned char * pucSig,
618                                      size_t xSigBufferSize,
619                                      size_t * pxSigLen )
620 {
621     unsigned char pucTempBuf[ MBEDTLS_ECDSA_MAX_LEN ] = { 0 };
622     unsigned char * pucPosition = pucTempBuf + sizeof( pucTempBuf );
623 
624     size_t uxLen = 0;
625     int lReturn = 0;
626     size_t xComponentLen;
627 
628     configASSERT( pucSig != NULL );
629     configASSERT( pxSigLen != NULL );
630     configASSERT( xSigBufferSize > *pxSigLen );
631 
632     xComponentLen = ( *pxSigLen ) / 2;
633 
634     /* Write "S" portion VLT */
635     lReturn = prvASN1WriteBigIntFromOctetStr( &pucPosition, pucTempBuf,
636                                               &( pucSig[ xComponentLen ] ), xComponentLen );
637 
638     /* Write "R" Portion VLT */
639     if( lReturn > 0 )
640     {
641         uxLen += ( size_t ) lReturn;
642         lReturn = prvASN1WriteBigIntFromOctetStr( &pucPosition, pucTempBuf,
643                                                   pucSig, xComponentLen );
644     }
645 
646     if( lReturn > 0 )
647     {
648         uxLen += ( size_t ) lReturn;
649         lReturn = mbedtls_asn1_write_len( &pucPosition, pucTempBuf, uxLen );
650     }
651 
652     if( lReturn > 0 )
653     {
654         uxLen += ( size_t ) lReturn;
655         lReturn = mbedtls_asn1_write_tag( &pucPosition, pucTempBuf,
656                                           MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
657     }
658 
659     if( lReturn > 0 )
660     {
661         uxLen += ( size_t ) lReturn;
662     }
663 
664     if( ( lReturn > 0 ) && ( uxLen <= xSigBufferSize ) )
665     {
666         ( void ) memcpy( pucSig, pucPosition, uxLen );
667         *pxSigLen = uxLen;
668         lReturn = 0;
669     }
670     else
671     {
672         lReturn = -1;
673     }
674 
675     return lReturn;
676 }
677 
678 /*-----------------------------------------------------------*/
679 
p11_ecdsa_sign(mbedtls_pk_context * pk,mbedtls_md_type_t xMdAlg,const unsigned char * pucHash,size_t xHashLen,unsigned char * pucSig,size_t xSigBufferSize,size_t * pxSigLen,int (* plRng)(void *,unsigned char *,size_t),void * pvRng)680 static int p11_ecdsa_sign( mbedtls_pk_context * pk,
681                            mbedtls_md_type_t xMdAlg,
682                            const unsigned char * pucHash,
683                            size_t xHashLen,
684                            unsigned char * pucSig,
685                            size_t xSigBufferSize,
686                            size_t * pxSigLen,
687                            int ( * plRng )( void *, unsigned char *, size_t ),
688                            void * pvRng )
689 {
690     CK_RV xResult = CKR_OK;
691     int32_t lFinalResult = 0;
692     const P11EcDsaCtx_t * pxEcDsaCtx = ( P11EcDsaCtx_t * ) pk->pk_ctx;
693     const P11PkCtx_t * pxP11Ctx = NULL;
694     unsigned char pucHashCopy[ MBEDTLS_MD_MAX_SIZE ];
695 
696     CK_MECHANISM xMech =
697     {
698         .mechanism      = CKM_ECDSA,
699         .pParameter     = NULL,
700         .ulParameterLen = 0
701     };
702 
703     /* Unused parameters. */
704     ( void ) ( xMdAlg );
705     ( void ) ( plRng );
706     ( void ) ( pvRng );
707 
708     configASSERT( pucSig != NULL );
709     configASSERT( xSigBufferSize > 0 );
710     configASSERT( pxSigLen != NULL );
711     configASSERT( pucHash != NULL );
712     configASSERT( xHashLen > 0 );
713 
714     if( pxEcDsaCtx != NULL )
715     {
716         pxP11Ctx = &( pxEcDsaCtx->xP11PkCtx );
717     }
718     else
719     {
720         xResult = CKR_FUNCTION_FAILED;
721     }
722 
723     if( CKR_OK == xResult )
724     {
725         /* Use the PKCS#11 module to sign. */
726         xResult = pxP11Ctx->pxFunctionList->C_SignInit( pxP11Ctx->xSessionHandle,
727                                                         &xMech,
728                                                         pxP11Ctx->xPkHandle );
729     }
730 
731     if( CKR_OK == xResult )
732     {
733         CK_ULONG ulSigLen = xSigBufferSize;
734 
735         ( void ) memcpy( pucHashCopy, pucHash, xHashLen );
736 
737         xResult = pxP11Ctx->pxFunctionList->C_Sign( pxP11Ctx->xSessionHandle,
738                                                     pucHashCopy, xHashLen,
739                                                     pucSig, &ulSigLen );
740 
741         if( xResult == CKR_OK )
742         {
743             *pxSigLen = ulSigLen;
744         }
745     }
746 
747     if( xResult != CKR_OK )
748     {
749         LogError( ( "Failed to sign message using PKCS #11 with error code %02X.", xResult ) );
750         lFinalResult = -1;
751     }
752     else
753     {
754         lFinalResult = prvEcdsaSigToASN1InPlace( pucSig, xSigBufferSize, pxSigLen );
755     }
756 
757     return lFinalResult;
758 }
759 
760 /*-----------------------------------------------------------*/
761 
p11_ecdsa_get_bitlen(mbedtls_pk_context * pxMbedtlsPkCtx)762 static size_t p11_ecdsa_get_bitlen( mbedtls_pk_context * pxMbedtlsPkCtx )
763 {
764     configASSERT( mbedtls_ecdsa_info.get_bitlen );
765 
766     return mbedtls_ecdsa_info.get_bitlen( pxMbedtlsPkCtx );
767 }
768 
769 /*-----------------------------------------------------------*/
770 
p11_ecdsa_can_do(mbedtls_pk_type_t xType)771 static int p11_ecdsa_can_do( mbedtls_pk_type_t xType )
772 {
773     return( xType == MBEDTLS_PK_ECDSA );
774 }
775 
776 /*-----------------------------------------------------------*/
777 
p11_ecdsa_verify(mbedtls_pk_context * pxMbedtlsPkCtx,mbedtls_md_type_t xMdAlg,const unsigned char * pucHash,size_t xHashLen,const unsigned char * pucSig,size_t xSigLen)778 static int p11_ecdsa_verify( mbedtls_pk_context * pxMbedtlsPkCtx,
779                              mbedtls_md_type_t xMdAlg,
780                              const unsigned char * pucHash,
781                              size_t xHashLen,
782                              const unsigned char * pucSig,
783                              size_t xSigLen )
784 {
785     configASSERT( mbedtls_ecdsa_info.verify_func );
786 
787     return mbedtls_ecdsa_info.verify_func( pxMbedtlsPkCtx,
788                                            xMdAlg,
789                                            pucHash, xHashLen,
790                                            pucSig, xSigLen );
791 }
792 
793 /*-----------------------------------------------------------*/
794 
p11_ecdsa_check_pair(mbedtls_pk_context * pxPub,mbedtls_pk_context * pxMbedtlsPkCtx,int (* lFRng)(void *,unsigned char *,size_t),void * pvPRng)795 static int p11_ecdsa_check_pair( mbedtls_pk_context * pxPub,
796                                  mbedtls_pk_context * pxMbedtlsPkCtx,
797                                  int ( * lFRng )( void *, unsigned char *, size_t ),
798                                  void * pvPRng )
799 {
800     P11EcDsaCtx_t * pxP11PrvKey = ( P11EcDsaCtx_t * ) pxMbedtlsPkCtx->pk_ctx;
801 
802     mbedtls_ecp_keypair * pxPubKey = ( mbedtls_ecp_keypair * ) pxPub;
803     mbedtls_ecp_keypair * pxPrvKey = &( pxP11PrvKey->xMbedEcDsaCtx );
804 
805     int lResult = 0;
806 
807     ( void ) lFRng;
808     ( void ) pvPRng;
809 
810     if( ( pxPubKey == NULL ) || ( pxPrvKey == NULL ) )
811     {
812         lResult = -1;
813     }
814 
815     if( lResult == 0 )
816     {
817         if( ( pxPubKey->grp.id == MBEDTLS_ECP_DP_NONE ) ||
818             ( pxPubKey->grp.id != pxPrvKey->grp.id ) )
819         {
820             lResult = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
821         }
822     }
823 
824     /* Compare public key points */
825     if( lResult == 0 )
826     {
827         lResult = mbedtls_mpi_cmp_mpi( &( pxPubKey->Q.X ), &( pxPrvKey->Q.X ) );
828     }
829 
830     if( lResult == 0 )
831     {
832         lResult = mbedtls_mpi_cmp_mpi( &( pxPubKey->Q.Y ), &( pxPrvKey->Q.Y ) );
833     }
834 
835     if( lResult == 0 )
836     {
837         lResult = mbedtls_mpi_cmp_mpi( &( pxPubKey->Q.Z ), &( pxPrvKey->Q.Z ) );
838     }
839 
840     /* Test sign op */
841     if( lResult == 0 )
842     {
843         unsigned char pucTestHash[ 32 ] =
844         {
845             0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
846             0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
847             0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
848             0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38
849         };
850         unsigned char pucTestSignature[ MBEDTLS_ECDSA_MAX_SIG_LEN( 256 ) ] = { 0 };
851         size_t uxSigLen = 0;
852         lResult = p11_ecdsa_sign( ( mbedtls_pk_context * ) pxMbedtlsPkCtx, MBEDTLS_MD_SHA256,
853                                   pucTestHash, sizeof( pucTestHash ),
854                                   pucTestSignature, sizeof( pucTestSignature ), &uxSigLen,
855                                   NULL, NULL );
856 
857         if( lResult == 0 )
858         {
859             lResult = mbedtls_ecdsa_read_signature( pxPubKey,
860                                                     pucTestHash, sizeof( pucTestHash ),
861                                                     pucTestSignature, uxSigLen );
862         }
863     }
864 
865     return lResult;
866 }
867 
868 /*-----------------------------------------------------------*/
869 
p11_ecdsa_debug(mbedtls_pk_context * pxMbedtlsPkCtx,mbedtls_pk_debug_item * pxItems)870 static void p11_ecdsa_debug( mbedtls_pk_context * pxMbedtlsPkCtx,
871                              mbedtls_pk_debug_item * pxItems )
872 {
873     configASSERT( mbedtls_ecdsa_info.debug_func );
874 
875     mbedtls_ecdsa_info.debug_func( ( mbedtls_pk_context * ) pxMbedtlsPkCtx, pxItems );
876 }
877 
878 /*-----------------------------------------------------------*/
879 
p11_rsa_get_bitlen(mbedtls_pk_context * pxMbedtlsPkCtx)880 static size_t p11_rsa_get_bitlen( mbedtls_pk_context * pxMbedtlsPkCtx )
881 {
882     mbedtls_rsa_context * pxRsaCtx = ( mbedtls_rsa_context * ) pxMbedtlsPkCtx->pk_ctx;
883 
884     configASSERT( mbedtls_rsa_info.get_bitlen );
885 
886     return mbedtls_rsa_info.get_bitlen( pxMbedtlsPkCtx );
887 }
888 
889 /*-----------------------------------------------------------*/
890 
p11_rsa_can_do(mbedtls_pk_type_t xType)891 static int p11_rsa_can_do( mbedtls_pk_type_t xType )
892 {
893     return( ( xType == MBEDTLS_PK_RSA ) || ( xType == MBEDTLS_PK_RSASSA_PSS ) );
894 }
895 
896 /*-----------------------------------------------------------*/
897 
p11_rsa_verify(mbedtls_pk_context * pxMbedtlsPkCtx,mbedtls_md_type_t xMdAlg,const unsigned char * pucHash,size_t xHashLen,const unsigned char * pucSig,size_t xSigLen)898 static int p11_rsa_verify( mbedtls_pk_context * pxMbedtlsPkCtx,
899                            mbedtls_md_type_t xMdAlg,
900                            const unsigned char * pucHash,
901                            size_t xHashLen,
902                            const unsigned char * pucSig,
903                            size_t xSigLen )
904 {
905     configASSERT( mbedtls_rsa_info.verify_func );
906 
907     return mbedtls_rsa_info.verify_func( pxMbedtlsPkCtx,
908                                          xMdAlg,
909                                          pucHash, xHashLen,
910                                          pucSig, xSigLen );
911 }
912 
913 /*-----------------------------------------------------------*/
914 
p11_rsa_sign(mbedtls_pk_context * pk,mbedtls_md_type_t xMdAlg,const unsigned char * pucHash,size_t xHashLen,unsigned char * pucSig,size_t xSigBufferSize,size_t * pxSigLen,int (* plRng)(void *,unsigned char *,size_t),void * pvRng)915 static int p11_rsa_sign( mbedtls_pk_context * pk,
916                          mbedtls_md_type_t xMdAlg,
917                          const unsigned char * pucHash,
918                          size_t xHashLen,
919                          unsigned char * pucSig,
920                          size_t xSigBufferSize,
921                          size_t * pxSigLen,
922                          int ( * plRng )( void *, unsigned char *, size_t ),
923                          void * pvRng )
924 {
925     CK_RV xResult = CKR_OK;
926     int32_t lFinalResult = 0;
927 
928     const P11RsaCtx_t * pxP11RsaCtx = NULL;
929     const P11PkCtx_t * pxP11Ctx = NULL;
930 
931     CK_BYTE pxToBeSigned[ 256 ];
932 
933     CK_MECHANISM xMech =
934     {
935         .mechanism      = CKM_RSA_PKCS,
936         .pParameter     = NULL,
937         .ulParameterLen = 0
938     };
939 
940     /* Unused parameters. */
941     ( void ) ( plRng );
942     ( void ) ( pvRng );
943 
944     configASSERT( pucSig != NULL );
945     configASSERT( xSigBufferSize > 0 );
946     configASSERT( pxSigLen != NULL );
947     configASSERT( pucHash != NULL );
948     configASSERT( xHashLen > 0 );
949 
950     configASSERT( xMdAlg == MBEDTLS_MD_SHA256 );
951     configASSERT( xHashLen <= sizeof( pxToBeSigned ) );
952 
953     /* Sanity check buffer length. */
954     if( xHashLen > sizeof( pxToBeSigned ) )
955     {
956         xResult = CKR_ARGUMENTS_BAD;
957     }
958     else if( pk != NULL )
959     {
960         pxP11RsaCtx = ( P11RsaCtx_t * ) pk->pk_ctx;
961         pxP11Ctx = &( pxP11RsaCtx->xP11PkCtx );
962     }
963     else
964     {
965         xResult = CKR_FUNCTION_FAILED;
966     }
967 
968     if( xResult == CKR_OK )
969     {
970         xResult = vAppendSHA256AlgorithmIdentifierSequence( ( uint8_t * ) pucHash, pxToBeSigned );
971     }
972 
973     if( CKR_OK == xResult )
974     {
975         /* Use the PKCS#11 module to sign. */
976         xResult = pxP11Ctx->pxFunctionList->C_SignInit( pxP11Ctx->xSessionHandle,
977                                                         &xMech,
978                                                         pxP11Ctx->xPkHandle );
979     }
980 
981     if( CKR_OK == xResult )
982     {
983         CK_ULONG ulSigLen = sizeof( pxToBeSigned );
984 
985         xResult = pxP11Ctx->pxFunctionList->C_Sign( pxP11Ctx->xSessionHandle,
986                                                     pxToBeSigned,
987                                                     pkcs11RSA_SIGNATURE_INPUT_LENGTH,
988                                                     pucSig,
989                                                     &ulSigLen );
990 
991         *pxSigLen = ( size_t ) ulSigLen;
992     }
993 
994     if( xResult != CKR_OK )
995     {
996         LogError( ( "Failed to sign message using PKCS #11 with error code %02X.", xResult ) );
997         lFinalResult = -1;
998     }
999 
1000     return lFinalResult;
1001 }
1002 
1003 /*-----------------------------------------------------------*/
1004 
p11_rsa_check_pair(mbedtls_pk_context * pxPub,mbedtls_pk_context * pxMbedtlsPkCtx,int (* lFRng)(void *,unsigned char *,size_t),void * pvPRng)1005 static int p11_rsa_check_pair( mbedtls_pk_context * pxPub,
1006                                mbedtls_pk_context * pxMbedtlsPkCtx,
1007                                int ( * lFRng )( void *, unsigned char *, size_t ),
1008                                void * pvPRng )
1009 {
1010     configASSERT( mbedtls_rsa_info.check_pair_func );
1011 
1012     return mbedtls_rsa_info.check_pair_func( pxPub,
1013                                              pxMbedtlsPkCtx,
1014                                              lFRng,
1015                                              pvPRng );
1016 }
1017 
1018 /*-----------------------------------------------------------*/
1019 
p11_rsa_ctx_alloc(void)1020 static void * p11_rsa_ctx_alloc( void )
1021 {
1022     void * pvCtx = NULL;
1023 
1024     pvCtx = mbedtls_calloc( 1, sizeof( P11RsaCtx_t ) );
1025 
1026     if( pvCtx != NULL )
1027     {
1028         P11RsaCtx_t * pxRsaCtx = ( P11RsaCtx_t * ) pvCtx;
1029 
1030         /* Initialize other fields */
1031         pxRsaCtx->xP11PkCtx.pxFunctionList = NULL;
1032         pxRsaCtx->xP11PkCtx.xSessionHandle = CK_INVALID_HANDLE;
1033         pxRsaCtx->xP11PkCtx.xPkHandle = CK_INVALID_HANDLE;
1034 
1035         mbedtls_rsa_init( &( pxRsaCtx->xMbedRsaCtx ) );
1036     }
1037 
1038     return pvCtx;
1039 }
1040 
1041 /*-----------------------------------------------------------*/
1042 
p11_rsa_ctx_init(mbedtls_pk_context * pk,CK_FUNCTION_LIST_PTR pxFunctionList,CK_SESSION_HANDLE xSessionHandle,CK_OBJECT_HANDLE xPkHandle)1043 static CK_RV p11_rsa_ctx_init( mbedtls_pk_context * pk,
1044                                CK_FUNCTION_LIST_PTR pxFunctionList,
1045                                CK_SESSION_HANDLE xSessionHandle,
1046                                CK_OBJECT_HANDLE xPkHandle )
1047 {
1048     CK_RV xResult = CKR_OK;
1049     P11RsaCtx_t * pxP11RsaCtx = ( P11RsaCtx_t * ) pk;
1050     mbedtls_rsa_context * pxMbedRsaCtx = NULL;
1051 
1052     configASSERT( pxFunctionList != NULL );
1053     configASSERT( xSessionHandle != CK_INVALID_HANDLE );
1054     configASSERT( xPkHandle != CK_INVALID_HANDLE );
1055 
1056     if( pxP11RsaCtx != NULL )
1057     {
1058         pxMbedRsaCtx = &( pxP11RsaCtx->xMbedRsaCtx );
1059     }
1060     else
1061     {
1062         xResult = CKR_FUNCTION_FAILED;
1063     }
1064 
1065     CK_ATTRIBUTE pxAttrs[ 8 ] =
1066     {
1067         { .type = CKA_MODULUS,          .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->N )  },
1068         { .type = CKA_PUBLIC_EXPONENT,  .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->E )  },
1069         { .type = CKA_PRIME_1,          .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->P )  },
1070         { .type = CKA_PRIME_2,          .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->Q )  },
1071         { .type = CKA_PRIVATE_EXPONENT, .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->D )  },
1072         { .type = CKA_EXPONENT_1,       .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->DP ) },
1073         { .type = CKA_EXPONENT_2,       .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->DQ ) },
1074         { .type = CKA_COEFFICIENT,      .ulValueLen = sizeof( mbedtls_mpi ), .pValue = &( pxMbedRsaCtx->QP ) },
1075     };
1076 
1077     xResult = pxFunctionList->C_GetAttributeValue( xSessionHandle,
1078                                                    xPkHandle,
1079                                                    pxAttrs,
1080                                                    sizeof( pxAttrs ) / sizeof( CK_ATTRIBUTE ) );
1081 
1082     if( xResult == CKR_OK )
1083     {
1084         pxP11RsaCtx->xP11PkCtx.pxFunctionList = pxFunctionList;
1085         pxP11RsaCtx->xP11PkCtx.xSessionHandle = xSessionHandle;
1086         pxP11RsaCtx->xP11PkCtx.xPkHandle = xPkHandle;
1087     }
1088 
1089     return xResult;
1090 }
1091 
1092 /*-----------------------------------------------------------*/
1093 
p11_rsa_ctx_free(void * pvCtx)1094 static void p11_rsa_ctx_free( void * pvCtx )
1095 {
1096     if( pvCtx != NULL )
1097     {
1098         P11RsaCtx_t * pxP11Rsa = ( P11RsaCtx_t * ) pvCtx;
1099 
1100         mbedtls_rsa_free( &( pxP11Rsa->xMbedRsaCtx ) );
1101 
1102         mbedtls_free( pvCtx );
1103     }
1104 }
1105 
1106 /*-----------------------------------------------------------*/
1107 
p11_rsa_debug(mbedtls_pk_context * pxMbedtlsPkCtx,mbedtls_pk_debug_item * pxItems)1108 static void p11_rsa_debug( mbedtls_pk_context * pxMbedtlsPkCtx,
1109                            mbedtls_pk_debug_item * pxItems )
1110 {
1111     configASSERT( mbedtls_rsa_info.debug_func );
1112 
1113     mbedtls_rsa_info.debug_func( pxMbedtlsPkCtx, pxItems );
1114 }
1115 
1116 /*-----------------------------------------------------------*/
1117