blob: e43a0e47d8e207555986c26369afd5f0e79e98a9 [file] [log] [blame]
Andrzej Kurek753b86c2018-01-23 08:56:17 -05001/* BEGIN_HEADER */
2#include <string.h>
3
4#include <pkcs11.h>
5
6#include "mbedtls/pkcs11_client.h"
7
8#if defined(MBEDTLS_PK_C)
9
10#include "mbedtls/oid.h"
11#include "mbedtls/asn1write.h"
12#include "mbedtls/bignum.h"
13#include "mbedtls/rsa.h"
14#include "mbedtls/pk.h"
15
16#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( *( a ) ) )
17
18#define CK_ASSERT( expr ) \
19 do { \
20 CK_RV CK_ASSERT_rv = ( expr ); \
21 char CK_ASSERT_msg[sizeof( #expr ) + 20] = #expr; \
22 if( CK_ASSERT_rv != CKR_OK ) { \
23 sprintf( CK_ASSERT_msg + strlen( CK_ASSERT_msg ), \
24 " -> 0x%x", (unsigned) CK_ASSERT_rv ); \
25 test_fail( CK_ASSERT_msg, __LINE__, __FILE__ ); \
26 goto exit; \
27 } \
28 } while( 0 )
29
Gilles Peskine72a07892018-01-22 08:25:52 +010030#define RSA_KEY_SIZE_BITS 1024
Andrzej Kurek753b86c2018-01-23 08:56:17 -050031#define RSA_KEY_SIZE_BYTES ( ( RSA_KEY_SIZE_BITS + 7 ) / 8 )
32#define ECP_GROUP_ID MBEDTLS_ECP_DP_SECP256R1
33#define ECP_GROUP_NAME( id ) #id
34
35//static CK_BBOOL ck_false = CK_FALSE;
36static CK_BBOOL ck_true = CK_TRUE;
37
38static int pkcs11_token_label_is( const CK_TOKEN_INFO *info, const char *label )
39{
40 size_t n = strlen( label );
41 if( n > sizeof( info->label ) )
42 return( 0 );
43 if( memcmp( info->label, label, n ) )
44 return( 0 );
45 for( ; n < sizeof( info->label ); n++ )
46 {
47 if( info->label[n] != ' ' )
48 return( 0 );
49 }
50 return( 1 );
51}
52
53static int pkcs11_get_slot_id( const char *label, CK_SLOT_ID *slot )
54{
55 CK_SLOT_ID *slots = NULL;
56 CK_ULONG count;
57 CK_ULONG i;
58 CK_TOKEN_INFO info;
59 int found = 0;
60 CK_ASSERT( C_GetSlotList( CK_TRUE, NULL_PTR, &count ) );
61 slots = mbedtls_calloc( sizeof( *slots ), count );
62 TEST_ASSERT( slots != NULL );
63 CK_ASSERT( C_GetSlotList( CK_TRUE, slots, &count ) );
64 for( i = 0; i < count; i++ )
65 {
66 CK_ASSERT( C_GetTokenInfo( slots[i], &info ) );
67 if( pkcs11_token_label_is( &info, label ) )
68 {
69 *slot = slots[i];
70 found = 1;
71 break;
72 }
73 }
74 if( !found )
75 mbedtls_fprintf( stdout, "No token found with label %s\n", label );
76exit:
77 mbedtls_free( slots );
78 return( found );
79}
80
81static CK_OBJECT_HANDLE pkcs11_init( void )
82{
83 CK_SESSION_HANDLE hSession;
84 CK_SLOT_ID slot;
85 unsigned char user_pin[4] = "0000";
86 CK_ASSERT( C_Initialize( NULL_PTR ) );
87 TEST_ASSERT( pkcs11_get_slot_id( "scratch", &slot ) );
88 CK_ASSERT( C_OpenSession( slot,
89 CKF_RW_SESSION | CKF_SERIAL_SESSION,
90 NULL_PTR, NULL_PTR,
91 &hSession ) );
92 CK_ASSERT( C_Login( hSession, CKU_USER, user_pin, sizeof( user_pin ) ) );
93 return( hSession );
94exit:
95 return( CK_INVALID_HANDLE );
96}
97
98static CK_RV pkcs11_generate_key( mbedtls_pk_type_t key_type,
99 CK_SESSION_HANDLE hSession,
100 CK_OBJECT_HANDLE *phPublicKey,
101 CK_OBJECT_HANDLE *phPrivateKey )
102{
103 CK_MECHANISM mechanism = {0, NULL_PTR, 0};
104 CK_ATTRIBUTE public_attributes[] = {
105 {0, 0, 0},
106 {CKA_ENCRYPT, &ck_true, sizeof( ck_true )},
107 {CKA_VERIFY, &ck_true, sizeof( ck_true )},
108 };
109 CK_ATTRIBUTE private_attributes[] = {
110 {CKA_DECRYPT, &ck_true, sizeof( ck_true )},
111 {CKA_SIGN, &ck_true, sizeof( ck_true )},
112 };
113 CK_ULONG ck_rsa_key_size = RSA_KEY_SIZE_BITS;
Andrzej Kurek753b86c2018-01-23 08:56:17 -0500114
115 switch( key_type )
116 {
117#if defined(MBEDTLS_RSA_C)
118 case MBEDTLS_PK_RSA:
119 mechanism.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
120 public_attributes[0].type = CKA_MODULUS_BITS;
121 public_attributes[0].pValue = &ck_rsa_key_size;
122 public_attributes[0].ulValueLen = sizeof( ck_rsa_key_size );
123 break;
124#endif /* MBEDTLS_RSA_C */
125 default:
126 test_fail( "Unsupported key type in test data", __LINE__, __FILE__ );
127 break;
128 }
129
130 return( C_GenerateKeyPair( hSession,
131 &mechanism,
132 public_attributes,
133 ARRAY_LENGTH( public_attributes ),
134 private_attributes,
135 ARRAY_LENGTH( private_attributes ),
136 phPublicKey, phPrivateKey ) );
Andrzej Kurek753b86c2018-01-23 08:56:17 -0500137}
138
139
140#endif /* MBEDTLS_PK_C */
141
142/* END_HEADER */
143
144/* BEGIN_DEPENDENCIES
145 * depends_on:MBEDTLS_PKCS11_CLIENT_C
146 * END_DEPENDENCIES
147 */
148
149/* BEGIN_CASE depends_on:MBEDTLS_PK_C:MBEDTLS_SHA256_C */
150void pk_generate_sign( int key_type )
151{
152 mbedtls_pk_context pkcs11_ctx;
153 mbedtls_pk_context transparent_ctx;
154 CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
155 CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE;
156 CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
157 unsigned char hash_value[32] = "Fake hash, it doesn't matter....";
158 unsigned char sig_buffer[RSA_KEY_SIZE_BYTES];
159 size_t sig_length = sizeof( sig_buffer );
160
161 mbedtls_pk_init( &pkcs11_ctx );
162 mbedtls_pk_init( &transparent_ctx );
163
164 /* Initialize cryptoki and generate a key in the token */
165 hSession = pkcs11_init( );
166 TEST_ASSERT( hSession != CK_INVALID_HANDLE );
167
168 CK_ASSERT( pkcs11_generate_key( key_type,
169 hSession,
170 &hPublicKey, &hPrivateKey ) );
171 TEST_ASSERT( hPublicKey != CK_INVALID_HANDLE );
172 TEST_ASSERT( hPrivateKey != CK_INVALID_HANDLE );
173
174 /* Prepare the mbed TLS contexts */
175 TEST_ASSERT( mbedtls_pk_setup( &transparent_ctx,
176 mbedtls_pk_info_from_type( key_type ) ) == 0 );
177 TEST_ASSERT( mbedtls_pk_setup_pkcs11( &pkcs11_ctx,
178 hSession,
179 hPublicKey,
180 hPrivateKey ) == 0 );
181
182 /* Retrieve the public key from the token */
183 switch( key_type )
184 {
185#if defined(MBEDTLS_RSA_C)
186 case MBEDTLS_PK_RSA:
187 {
188 unsigned char n_buffer[RSA_KEY_SIZE_BYTES];
189 unsigned char e_buffer[RSA_KEY_SIZE_BYTES];
190 CK_ATTRIBUTE public_attributes[] = {
191 {CKA_MODULUS, n_buffer, sizeof( n_buffer )},
192 {CKA_PUBLIC_EXPONENT, e_buffer, sizeof( e_buffer )},
193 };
194 CK_ULONG *n_length = &public_attributes[0].ulValueLen;
195 CK_ULONG *e_length = &public_attributes[1].ulValueLen;
196 mbedtls_rsa_context *rsa_ctx = mbedtls_pk_rsa( transparent_ctx );
197
198 CK_ASSERT( C_GetAttributeValue( hSession, hPublicKey,
199 public_attributes, ARRAY_LENGTH( public_attributes ) ) );
200 TEST_ASSERT( mbedtls_mpi_read_binary( &rsa_ctx->N,
201 n_buffer, *n_length ) == 0 );
202 TEST_ASSERT( mbedtls_mpi_read_binary( &rsa_ctx->E,
203 e_buffer, *e_length ) == 0 );
204 rsa_ctx->len = mbedtls_mpi_size( &rsa_ctx->N );
205 }
206 break;
207#endif /* MBEDTLS_RSA_C */
208
209 default:
210 TEST_ASSERT( !"Unsupported key type in test data" );
211 break;
212 }
213
214 /* Sign with the token and verify in software */
215 TEST_ASSERT( mbedtls_pk_sign( &pkcs11_ctx, MBEDTLS_MD_SHA256,
216 hash_value, 32,
217 sig_buffer, &sig_length,
218 NULL, NULL ) == 0 );
219 TEST_ASSERT( mbedtls_pk_verify( &transparent_ctx, MBEDTLS_MD_SHA256,
220 hash_value, 32,
221 sig_buffer, sig_length ) == 0 );
222
223exit:
224 if( hPublicKey != CK_INVALID_HANDLE )
225 C_DestroyObject( hSession, hPublicKey );
226 if( hPrivateKey != CK_INVALID_HANDLE )
227 C_DestroyObject( hSession, hPrivateKey );
228 C_CloseSession( hSession );
229 C_Finalize( NULL_PTR );
230 mbedtls_pk_free( &pkcs11_ctx );
231 mbedtls_pk_free( &transparent_ctx );
232}
233/* END_CASE */
234
235/* BEGIN_CASE depends_on:MBEDTLS_PK_C:MBEDTLS_SHA256_C */
236void pk_import_sign( char *file )
237{
238 mbedtls_pk_context pkcs11_ctx;
239 mbedtls_pk_context transparent_ctx;
240 CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
241 CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE;
242 CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
243 unsigned char hash_value[32] = "Fake hash, it doesn't matter....";
244 unsigned char sig_buffer[4096];
245 size_t sig_length = sizeof( sig_buffer );
246
247 mbedtls_pk_init( &pkcs11_ctx );
248 mbedtls_pk_init( &transparent_ctx );
249
250 /* Read a transparent key */
251 TEST_ASSERT( mbedtls_pk_parse_keyfile( &transparent_ctx, file, NULL ) == 0 );
252
253 /* Initialize cryptoki and import the key into the token */
254 hSession = pkcs11_init( );
255 TEST_ASSERT( hSession != CK_INVALID_HANDLE );
256
257 TEST_ASSERT( mbedtls_pk_import_to_pkcs11( &transparent_ctx,
258 MBEDTLS_PK_FLAG_SIGN |
259 MBEDTLS_PK_FLAG_VERIFY,
260 hSession,
261 &hPublicKey,
262 &hPrivateKey ) == 0 );
263 TEST_ASSERT( hPublicKey != CK_INVALID_HANDLE );
264 TEST_ASSERT( hPrivateKey != CK_INVALID_HANDLE );
265 TEST_ASSERT( mbedtls_pk_setup_pkcs11( &pkcs11_ctx,
266 hSession,
267 hPublicKey,
268 hPrivateKey ) == 0 );
269
270 /* Sign with the token and verify in software */
271 TEST_ASSERT( sizeof( sig_buffer ) >= mbedtls_pk_signature_size( &pkcs11_ctx ) );
272 TEST_ASSERT( mbedtls_pk_sign( &pkcs11_ctx, MBEDTLS_MD_SHA256,
273 hash_value, 32,
274 sig_buffer, &sig_length,
275 NULL, NULL ) == 0 );
276 TEST_ASSERT( mbedtls_pk_verify( &transparent_ctx, MBEDTLS_MD_SHA256,
277 hash_value, 32,
278 sig_buffer, sig_length ) == 0 );
279
280exit:
281 if( hPublicKey != CK_INVALID_HANDLE )
282 C_DestroyObject( hSession, hPublicKey );
283 if( hPrivateKey != CK_INVALID_HANDLE )
284 C_DestroyObject( hSession, hPrivateKey );
285 C_CloseSession( hSession );
286 C_Finalize( NULL_PTR );
287 mbedtls_pk_free( &pkcs11_ctx );
288 mbedtls_pk_free( &transparent_ctx );
289}
290/* END_CASE */
Andrzej Kurek79f4e0e2018-01-24 08:15:51 -0500291
292/* BEGIN_CASE depends_on:MBEDTLS_PK_C:MBEDTLS_SHA256_C */
293void pk_import_sign_verify( char *file )
294 {
Andrzej Kurek686a05e2018-03-02 17:11:39 -0500295 /* Sign with cryptoki, convert to Mbed TLS format and save,
Andrzej Kurek79f4e0e2018-01-24 08:15:51 -0500296 verify by cryptoki with a conversion to a raw, concatenated
297 format by the engine. */
298 mbedtls_pk_context pkcs11_ctx;
299 mbedtls_pk_context transparent_ctx;
300 CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
301 CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE;
302 CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
303 unsigned char hash_value[32] = "Fake hash, it doesn't matter....";
304 unsigned char sig_buffer[4096];
305 size_t sig_length = sizeof( sig_buffer );
306
307 mbedtls_pk_init( &pkcs11_ctx );
308 mbedtls_pk_init( &transparent_ctx );
309
310 /* Read a transparent key */
311 TEST_ASSERT( mbedtls_pk_parse_keyfile( &transparent_ctx, file, NULL ) == 0 );
312
313 /* Initialize cryptoki and import the key into the token */
314 hSession = pkcs11_init( );
315 TEST_ASSERT( hSession != CK_INVALID_HANDLE );
316
317 TEST_ASSERT( mbedtls_pk_import_to_pkcs11( &transparent_ctx,
318 MBEDTLS_PK_FLAG_SIGN |
319 MBEDTLS_PK_FLAG_VERIFY,
320 hSession,
321 &hPublicKey,
322 &hPrivateKey ) == 0 );
323 TEST_ASSERT( hPublicKey != CK_INVALID_HANDLE );
324 TEST_ASSERT( hPrivateKey != CK_INVALID_HANDLE );
325 TEST_ASSERT( mbedtls_pk_setup_pkcs11( &pkcs11_ctx,
326 hSession,
327 hPublicKey,
328 hPrivateKey ) == 0 );
329
330 /* Sign with the token and verify with cryptoki */
331 TEST_ASSERT( sizeof( sig_buffer ) >= mbedtls_pk_signature_size( &pkcs11_ctx ) );
332 TEST_ASSERT( mbedtls_pk_sign( &pkcs11_ctx, MBEDTLS_MD_SHA256,
333 hash_value, 32,
334 sig_buffer, &sig_length,
335 NULL, NULL ) == 0 );
336 TEST_ASSERT( mbedtls_pk_verify( &pkcs11_ctx, MBEDTLS_MD_SHA256,
337 hash_value, 32,
338 sig_buffer, sig_length ) == 0 );
339
340exit:
Andrzej Kurek686a05e2018-03-02 17:11:39 -0500341 mbedtls_pk_free( &pkcs11_ctx );
342 mbedtls_pk_free( &transparent_ctx );
Andrzej Kurek79f4e0e2018-01-24 08:15:51 -0500343 if( hPublicKey != CK_INVALID_HANDLE )
344 C_DestroyObject( hSession, hPublicKey );
345 if( hPrivateKey != CK_INVALID_HANDLE )
346 C_DestroyObject( hSession, hPrivateKey );
347 C_CloseSession( hSession );
348 C_Finalize( NULL_PTR );
Andrzej Kurek79f4e0e2018-01-24 08:15:51 -0500349}
350/* END_CASE */
351
352/* BEGIN_CASE depends_on:MBEDTLS_PK_C:MBEDTLS_SHA256_C */
353void pk_import_verify_signed( char *file )
354{
355 /* Sign with mbedTLS, verify by cryptoki with a conversion
356 to a raw, concatenated format by the engine. */
357 mbedtls_pk_context pkcs11_ctx;
358 mbedtls_pk_context transparent_ctx;
359 CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
360 CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE;
361 CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
362 unsigned char hash_value[32] = "Fake hash, it doesn't matter....";
363 unsigned char sig_buffer[4096];
364 size_t sig_length = sizeof( sig_buffer );
365
366 mbedtls_pk_init( &pkcs11_ctx );
367 mbedtls_pk_init( &transparent_ctx );
368
369 /* Read a transparent key */
370 TEST_ASSERT( mbedtls_pk_parse_keyfile( &transparent_ctx, file, NULL ) == 0 );
371
372 /* Initialize cryptoki and import the key into the token */
373 hSession = pkcs11_init( );
374 TEST_ASSERT( hSession != CK_INVALID_HANDLE );
375
376 TEST_ASSERT( mbedtls_pk_import_to_pkcs11( &transparent_ctx,
Andrzej Kurek79f4e0e2018-01-24 08:15:51 -0500377 MBEDTLS_PK_FLAG_VERIFY,
378 hSession,
379 &hPublicKey,
380 NULL ) == 0 );
381 TEST_ASSERT( hPublicKey != CK_INVALID_HANDLE );
382 TEST_ASSERT( mbedtls_pk_setup_pkcs11( &pkcs11_ctx,
383 hSession,
384 hPublicKey,
385 CK_INVALID_HANDLE ) == 0 );
386
387 /* Sign with the token and verify with cryptoki */
388 TEST_ASSERT( sizeof( sig_buffer ) >= mbedtls_pk_signature_size( &pkcs11_ctx ) );
389 TEST_ASSERT( mbedtls_pk_sign( &transparent_ctx, MBEDTLS_MD_SHA256,
390 hash_value, 32,
391 sig_buffer, &sig_length,
392 NULL, NULL ) == 0 );
393 TEST_ASSERT( mbedtls_pk_verify( &pkcs11_ctx, MBEDTLS_MD_SHA256,
394 hash_value, 32,
395 sig_buffer, sig_length ) == 0 );
396
397exit:
398 if( hPublicKey != CK_INVALID_HANDLE )
399 C_DestroyObject( hSession, hPublicKey );
400 if( hPrivateKey != CK_INVALID_HANDLE )
401 C_DestroyObject( hSession, hPrivateKey );
402 C_CloseSession( hSession );
403 C_Finalize( NULL_PTR );
404 mbedtls_pk_free( &pkcs11_ctx );
405 mbedtls_pk_free( &transparent_ctx );
406}
407/* END_CASE */
408
Andrzej Kurek686a05e2018-03-02 17:11:39 -0500409/* BEGIN_CASE depends_on:MBEDTLS_PK_C:MBEDTLS_RSA_C */
Andrzej Kurek79f4e0e2018-01-24 08:15:51 -0500410void pk_rsa_hardcoded_verify( char *message_hex_string, int digest,
411 int mod, int radix_N, char *input_N, int radix_E,
412 char *input_E, char *result_hex_str, int result )
413{
414 unsigned char message_str[1000];
415 unsigned char hash_result[1000];
416 unsigned char result_str[1000];
417 mbedtls_rsa_context *rsa;
418 mbedtls_pk_context transparent_ctx;
419 int msg_len;
420
421 mbedtls_pk_context pkcs11_ctx;
422 CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
423 CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE;
424 CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
425
426 mbedtls_pk_init( &transparent_ctx );
427
428 memset( message_str, 0x00, 1000 );
429 memset( hash_result, 0x00, 1000 );
430 memset( result_str, 0x00, 1000 );
431
432 TEST_ASSERT( mbedtls_pk_setup( &transparent_ctx, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
433 rsa = mbedtls_pk_rsa( transparent_ctx );
434
435 rsa->len = mod / 8;
436 TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
437 TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
438
439 msg_len = unhexify( message_str, message_hex_string );
440 unhexify( result_str, result_hex_str );
441
442 if( mbedtls_md_info_from_type( digest ) != NULL )
443 TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 );
444
445 // PKCS11 part
446 mbedtls_pk_init( &pkcs11_ctx );
447
448 /* Initialize cryptoki and import the key into the token */
449 hSession = pkcs11_init( );
450 TEST_ASSERT( hSession != CK_INVALID_HANDLE );
451 TEST_ASSERT( mbedtls_pk_import_to_pkcs11( &transparent_ctx,
452 MBEDTLS_PK_FLAG_SIGN |
453 MBEDTLS_PK_FLAG_VERIFY,
454 hSession,
455 &hPublicKey,
456 NULL ) == 0 );
457 TEST_ASSERT( hPublicKey != CK_INVALID_HANDLE );
458 TEST_ASSERT( mbedtls_pk_setup_pkcs11( &pkcs11_ctx,
459 hSession,
460 hPublicKey,
461 CK_INVALID_HANDLE ) == 0 );
462
463 TEST_ASSERT( mbedtls_pk_verify( &pkcs11_ctx, digest, hash_result, 0,
464 result_str, mbedtls_pk_get_len( &transparent_ctx ) ) == result );
465
466exit:
467 if( hPublicKey != CK_INVALID_HANDLE )
468 C_DestroyObject( hSession, hPublicKey );
469 if( hPrivateKey != CK_INVALID_HANDLE )
470 C_DestroyObject( hSession, hPrivateKey );
471 C_CloseSession( hSession );
472 C_Finalize( NULL_PTR );
473 mbedtls_pk_free( &pkcs11_ctx );
474 mbedtls_pk_free( &transparent_ctx );
475}
476/* END_CASE */