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