blob: 79d6648fd06d2623c3c9528c57984aee663972ff [file] [log] [blame]
Andrzej Kurek753b86c2018-01-23 08:56:17 -05001/*
2 * Generic wrapper for Cryptoki (PKCS#11) support
3 *
4 * Copyright (C) 2017, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PKCS11_CLIENT_C)
29
30#include <stdint.h>
31#include <string.h>
32#include <pkcs11.h>
33
34#include "mbedtls/pkcs11_client.h"
35
36#if defined(MBEDTLS_PLATFORM_C)
37#include "mbedtls/platform.h"
38#else
39#include <stdlib.h>
40#define mbedtls_calloc calloc
41#define mbedtls_free free
42#endif
43
44
45
46#if defined(MBEDTLS_PK_C)
47#include "mbedtls/pk.h"
48#include "mbedtls/pk_info.h"
49
50#if defined(MBEDTLS_RSA_C)
51#include "mbedtls/bignum.h"
52#include "mbedtls/rsa.h"
53#endif
54
55#if defined(MBEDTLS_ECDSA_C)
56#include "mbedtls/asn1.h"
57#include "mbedtls/asn1write.h"
58#include "mbedtls/bignum.h"
59#include "mbedtls/ecdsa.h"
60#include "mbedtls/ecp.h"
61#include "mbedtls/oid.h"
62#endif
63
64#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( *( a ) ) )
65
66typedef struct {
67 mbedtls_pk_type_t key_type; /**< key type */
68 CK_SESSION_HANDLE hSession; /**< session handle */
69 CK_OBJECT_HANDLE hPublicKey; /**< public key handle (must not be null) */
70 CK_OBJECT_HANDLE hPrivateKey; /**< private key handle (may be null) */
71 uint16_t bit_length; /**< key length in bits */
72} mbedtls_pk_pkcs11_context_t;
73
74static int pkcs11_err_to_mbedtls_pk_err( CK_RV rv )
75{
76 switch( rv )
77 {
78 case CKR_OK:
79 return( 0 );
80 case CKR_HOST_MEMORY:
81 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
82 case CKR_ARGUMENTS_BAD:
83 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
84 case CKR_KEY_FUNCTION_NOT_PERMITTED:
85 return( MBEDTLS_ERR_PK_NOT_PERMITTED );
86 case CKR_MECHANISM_INVALID:
87 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
88 case CKR_MECHANISM_PARAM_INVALID:
89 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
90 case CKR_OBJECT_HANDLE_INVALID:
91 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
92 case CKR_SIGNATURE_INVALID:
93 return( MBEDTLS_ERR_PK_INVALID_SIGNATURE );
94 case CKR_SIGNATURE_LEN_RANGE:
95 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
96 case CKR_TEMPLATE_INCOMPLETE:
97 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
98 case CKR_BUFFER_TOO_SMALL:
99 return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
100 default:
101 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
102 }
103}
104
105static size_t pkcs11_pk_get_bitlen( const void *ctx_arg )
106{
107 const mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
108 return( ctx->bit_length );
109}
110
111static int pkcs11_pk_can_do( const void *ctx_arg, mbedtls_pk_type_t type )
112{
113 const mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
114 return ctx->key_type == mbedtls_pk_representation_type( type );
115}
116
117static void *pkcs11_pk_alloc( )
118{
119 return( mbedtls_calloc( 1, sizeof( mbedtls_pk_pkcs11_context_t ) ) );
120}
121
122static void pkcs11_pk_free( void *ctx )
123{
124 mbedtls_free( ctx );
125}
126
127static size_t pkcs11_pk_signature_size( const void *ctx_arg )
128{
129 const mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
130 switch( ctx->key_type )
131 {
132 case MBEDTLS_PK_RSA:
133 return( ( ctx->bit_length + 7 ) / 8 );
134 case MBEDTLS_PK_ECKEY:
135 return( MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->bit_length ) );
136 default:
137 return( 0 );
138 }
139}
140
141static int pkcs11_sign( void *ctx_arg,
142 mbedtls_md_type_t md_alg,
143 const unsigned char *hash, size_t hash_len,
144 unsigned char *sig, size_t *sig_len,
145 int (*f_rng)(void *, unsigned char *, size_t),
146 void *p_rng )
147{
148 mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
149 CK_RV rv;
150 CK_MECHANISM mechanism = {0, NULL_PTR, 0};
151 CK_ULONG ck_sig_len;
152
153 /* This function takes size_t arguments but the underlying layer
154 takes unsigned long. Either type may be smaller than the other.
155 Legitimate values won't overflow either type but we still need
156 to check for overflow for robustness. */
157 if( hash_len > (CK_ULONG)( -1 ) )
158 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
159 (void) f_rng;
160 (void) p_rng;
161
162 switch( ctx->key_type )
163 {
164#if defined(MBEDTLS_RSA_C)
165 case MBEDTLS_PK_RSA:
166 ck_sig_len = ( ctx->bit_length + 7 ) / 8;
167 // FIXME: these mechanisms perform hashing as well as signing.
168 // But here we get the hash as input. So we need to invoke
169 // CKM_RSA_PKCS. But CKM_RSA_PKCS doesn't perform the hash
170 // encoding, only a part of the padding.
171 switch( md_alg )
172 {
173 case MBEDTLS_MD_MD5:
174 mechanism.mechanism = CKM_MD5_RSA_PKCS;
175 break;
176 case MBEDTLS_MD_SHA1:
177 mechanism.mechanism = CKM_SHA1_RSA_PKCS;
178 break;
179 case MBEDTLS_MD_SHA256:
180 mechanism.mechanism = CKM_SHA256_RSA_PKCS;
181 break;
182 case MBEDTLS_MD_SHA384:
183 mechanism.mechanism = CKM_SHA384_RSA_PKCS;
184 break;
185 case MBEDTLS_MD_SHA512:
186 mechanism.mechanism = CKM_SHA512_RSA_PKCS;
187 break;
188 default:
189 return( MBEDTLS_ERR_PK_INVALID_ALG );
190 }
191 break;
192#endif /* MBEDTLS_RSA_C */
193 default:
194 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
195 }
196
197 rv = C_SignInit( ctx->hSession, &mechanism, ctx->hPrivateKey );
198 if( rv != CKR_OK )
199 goto exit;
200 rv = C_Sign( ctx->hSession, (CK_BYTE_PTR) hash, hash_len,
201 sig, &ck_sig_len );
202 if( rv != CKR_OK )
203 goto exit;
204
205 *sig_len = ck_sig_len;
206
207exit:
208 if( rv != CKR_OK )
209 memset( sig, 0, ck_sig_len );
210 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
211}
212
213static const mbedtls_pk_info_t mbedtls_pk_pkcs11_info = {
214 MBEDTLS_PK_OPAQUE,
215 "pkcs11",
216 pkcs11_pk_get_bitlen,
217 pkcs11_pk_can_do, //can_do
218 NULL, //pkcs11_verify,
219 pkcs11_sign,
220 NULL, //pkcs11_decrypt,
221 NULL, //pkcs11_encrypt,
222 NULL, //check_pair_func
223 pkcs11_pk_alloc,
224 pkcs11_pk_free,
225 NULL, //debug_func
226 pkcs11_pk_signature_size,
227};
228
229int mbedtls_pk_setup_pkcs11( mbedtls_pk_context *ctx,
230 CK_SESSION_HANDLE hSession,
231 CK_OBJECT_HANDLE hPublicKey,
232 CK_OBJECT_HANDLE hPrivateKey )
233{
234 CK_OBJECT_CLASS public_key_class = -1, private_key_class = -1;
235 CK_KEY_TYPE public_key_type = -1, private_key_type = -1;
236 mbedtls_pk_type_t can_do;
237 CK_ATTRIBUTE attributes[] = {
238 {CKA_CLASS, &public_key_class, sizeof( public_key_class )},
239 {CKA_KEY_TYPE, &public_key_type, sizeof( public_key_type )},
240 };
241 CK_RV rv;
242 uint16_t key_size = 0;
243
244 rv = C_GetAttributeValue( hSession, hPublicKey,
245 attributes, ARRAY_LENGTH( attributes ) );
246 if( rv != CKR_OK )
247 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
248 if( public_key_class != CKO_PUBLIC_KEY )
249 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
250
251 if( hPrivateKey != CK_INVALID_HANDLE )
252 {
253 attributes[0].pValue = &private_key_class;
254 attributes[1].pValue = &private_key_type;
255 rv = C_GetAttributeValue( hSession, hPrivateKey,
256 attributes, ARRAY_LENGTH( attributes ) );
257 if( rv != CKR_OK )
258 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
259 if( private_key_class != CKO_PRIVATE_KEY )
260 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
261 if( public_key_type != private_key_type )
262 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
263 }
264
265 switch( public_key_type ) {
266#if defined(MBEDTLS_RSA_C)
267 case CKK_RSA:
268 can_do = MBEDTLS_PK_RSA;
269 {
270 CK_ULONG modulus_bits;
271 attributes[0].type = CKA_MODULUS_BITS;
272 attributes[0].pValue = &modulus_bits;
273 attributes[0].ulValueLen = sizeof( modulus_bits );
274 rv = C_GetAttributeValue( hSession, hPrivateKey, attributes, 1 );
275 if( rv != CKR_OK )
276 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
277 if( modulus_bits > (uint16_t)( -1 ) )
278 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
279 key_size = modulus_bits;
280 }
281 break;
282#endif /* MBEDTLS_RSA_C */
283 default:
284 can_do = MBEDTLS_PK_OPAQUE;
285 break;
286 }
287
288 {
289 int ret = mbedtls_pk_setup( ctx, &mbedtls_pk_pkcs11_info );
290 if( ret != 0 )
291 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
292 }
293 {
294 mbedtls_pk_pkcs11_context_t *pkcs11_ctx = ctx->pk_ctx;
295 pkcs11_ctx->key_type = can_do;
296 pkcs11_ctx->bit_length = key_size;
297 pkcs11_ctx->hSession = hSession;
298 pkcs11_ctx->hPublicKey = hPublicKey;
299 pkcs11_ctx->hPrivateKey = hPrivateKey;
300 }
301 return( 0 );
302}
303
304#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
305static int mpi_to_ck( const mbedtls_mpi *mpi,
306 CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE at,
307 unsigned char **p, size_t len )
308{
309 if( mbedtls_mpi_write_binary( mpi, *p, len ) != 0 )
310 return( 0 );
311 attr->type = at;
312 attr->pValue = *p;
313 attr->ulValueLen = len;
314 *p += len;
315 return( 1 );
316}
317#define MPI_TO_CK( mpi, attr, at, p, len ) \
318 do \
319 { \
320 if( !mpi_to_ck( ( mpi ), ( attr ), ( at ), ( p ), ( len ) ) ) \
321 { \
322 rv = CKR_ARGUMENTS_BAD; \
323 goto exit; \
324 } \
325 } \
326 while( 0 )
327#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) */
328
329#define CK_BOOL( x ) ( ( x ) ? CK_TRUE : CK_FALSE )
330
331int mbedtls_pk_import_to_pkcs11( const mbedtls_pk_context *ctx,
332 uint32_t flags,
333 CK_SESSION_HANDLE hSession,
334 CK_OBJECT_HANDLE *hPublicKey,
335 CK_OBJECT_HANDLE *hPrivateKey )
336{
337 CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
338 CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
339 CK_KEY_TYPE ck_key_type;
340 CK_BBOOL ck_sensitive = CK_BOOL( flags & MBEDTLS_PK_FLAG_SENSITIVE );
341 CK_BBOOL ck_extractable = CK_BOOL( flags & MBEDTLS_PK_FLAG_EXTRACTABLE );
342 CK_BBOOL ck_sign = CK_BOOL( flags & MBEDTLS_PK_FLAG_SIGN );
343 CK_BBOOL ck_verify = CK_BOOL( flags & MBEDTLS_PK_FLAG_VERIFY );
344 CK_BBOOL ck_decrypt = CK_BOOL( flags & MBEDTLS_PK_FLAG_DECRYPT );
345 CK_BBOOL ck_encrypt = CK_BOOL( flags & MBEDTLS_PK_FLAG_ENCRYPT );
346 CK_BBOOL ck_token = CK_BOOL( flags & MBEDTLS_PKCS11_FLAG_TOKEN );
347 CK_ATTRIBUTE public_attributes[] = {
348 {CKA_CLASS, &cko_public_key, sizeof( cko_public_key )},
349 {CKA_KEY_TYPE, &ck_key_type, sizeof( ck_key_type )},
350 {CKA_TOKEN, &ck_token, sizeof( ck_token )},
351 {CKA_ENCRYPT, &ck_encrypt, sizeof( ck_encrypt )},
352 {CKA_VERIFY, &ck_verify, sizeof( ck_verify )},
353#define COMMON_PUBLIC_ATTRIBUTES 5 // number of attributes above
354 {-1, NULL, 0},
355 {-1, NULL, 0},
356 };
357 CK_ATTRIBUTE private_attributes[] = {
358 {CKA_CLASS, &cko_private_key, sizeof( cko_private_key )},
359 {CKA_KEY_TYPE, &ck_key_type, sizeof( ck_key_type )},
360 {CKA_TOKEN, &ck_token, sizeof( ck_token )},
361 {CKA_DECRYPT, &ck_decrypt, sizeof( ck_decrypt )},
362 {CKA_SIGN, &ck_sign, sizeof( ck_sign )},
363 {CKA_SENSITIVE, &ck_sensitive, sizeof( ck_sensitive )},
364 {CKA_EXTRACTABLE, &ck_extractable, sizeof( ck_extractable )},
365#define COMMON_PRIVATE_ATTRIBUTES 7 // number of attributes above
366 {-1, NULL, 0},
367 {-1, NULL, 0},
368 {-1, NULL, 0},
369 {-1, NULL, 0},
370 {-1, NULL, 0},
371 {-1, NULL, 0},
372 {-1, NULL, 0},
373 {-1, NULL, 0},
374 };
375 CK_ATTRIBUTE *public_end = public_attributes + COMMON_PUBLIC_ATTRIBUTES;
376 CK_ATTRIBUTE *private_end = private_attributes + COMMON_PRIVATE_ATTRIBUTES;
377#undef COMMON_PUBLIC_ATTRIBUTES
378#undef COMMON_PRIVATE_ATTRIBUTES
379 unsigned char *data = NULL;
380 CK_RV rv;
381
382 if( hPublicKey != NULL )
383 *hPublicKey = CK_INVALID_HANDLE;
384 if( hPrivateKey != NULL )
385 *hPrivateKey = CK_INVALID_HANDLE;
386
387 /* Prepare the data-dependent key attributes */
388 switch( mbedtls_pk_representation_type( mbedtls_pk_get_type( ctx ) ) )
389 {
390#if defined(MBEDTLS_RSA_C)
391 case MBEDTLS_PK_RSA:
392 {
393 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *ctx );
394 unsigned char *p;
395 size_t half_len = ( rsa->len + 1 ) / 2;
396 data = mbedtls_calloc( 1, 3 * rsa->len + 5 * half_len );
397 if( data == NULL )
398 {
399 rv = CKR_HOST_MEMORY;
400 goto exit;
401 }
402 p = data;
403 ck_key_type = CKK_RSA;
404 MPI_TO_CK( &rsa->N, public_end, CKA_MODULUS, &p, rsa->len );
405 *private_end++ = *public_end++;
406 MPI_TO_CK( &rsa->E, public_end, CKA_PUBLIC_EXPONENT, &p, rsa->len );
407 *private_end++ = *public_end++;
408 if( hPrivateKey != NULL )
409 {
410 MPI_TO_CK( &rsa->D, private_end++,
411 CKA_PRIVATE_EXPONENT, &p, rsa->len );
412 MPI_TO_CK( &rsa->P, private_end++,
413 CKA_PRIME_1, &p, half_len );
414 MPI_TO_CK( &rsa->Q, private_end++,
415 CKA_PRIME_2, &p, half_len );
416 MPI_TO_CK( &rsa->DP, private_end++,
417 CKA_EXPONENT_1, &p, half_len );
418 MPI_TO_CK( &rsa->DQ, private_end++,
419 CKA_EXPONENT_2, &p, half_len );
420 MPI_TO_CK( &rsa->QP, private_end++,
421 CKA_COEFFICIENT, &p, half_len );
422 }
423 }
424 break;
425#endif /* MBEDTLS_RSA_C */
426 default:
427 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
428 }
429
430 if( hPublicKey != NULL )
431 {
432 *hPublicKey = CK_INVALID_HANDLE;
433 rv = C_CreateObject( hSession,
434 public_attributes,
435 public_end - public_attributes,
436 hPublicKey );
437 if( rv != CKR_OK )
438 goto exit;
439 }
440
441 if( hPrivateKey != NULL )
442 {
443 rv = C_CreateObject( hSession,
444 private_attributes,
445 private_end - private_attributes,
446 hPrivateKey );
447 if( rv != CKR_OK )
448 goto exit;
449 }
450
451exit:
452 if( rv != CKR_OK )
453 {
454 /* In case an error happened, destroy any object that we
455 created. In case C_DestroyObject failed, we report the original
456 error, but *hPublicKey may contain a valid handle if
457 creating the private key failed and then destroying the public key
458 also failed (e.g. because the token disconnected). */
459 if( hPublicKey != NULL && *hPublicKey != CK_INVALID_HANDLE )
460 {
461 if( C_DestroyObject( hSession, *hPublicKey ) == CKR_OK )
462 *hPublicKey = CK_INVALID_HANDLE;
463 }
464 if( hPrivateKey != NULL && *hPrivateKey != CK_INVALID_HANDLE )
465 {
466 if( C_DestroyObject( hSession, *hPrivateKey ) == CKR_OK )
467 *hPrivateKey = CK_INVALID_HANDLE;
468 }
469 }
470 mbedtls_free( data );
471 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
472}
473
474#endif /* MBEDTLS_PK_C */
475
476
477
478#endif /* MBEDTLS_PKCS11_CLIENT_C */