18
18
* This is probably a bug in the library. */
19
19
#define PSA_ERROR_DETECTED_BY_DRIVER ((psa_status_t)( -500 ))
20
20
21
- /** Like #TEST_ASSERT for use in a driver method.
21
+ /** Like #TEST_ASSERT for use in a driver method, with no cleanup.
22
+ *
23
+ * If an error happens, this macro returns from the calling function.
22
24
*
23
25
* Use this macro to assert on guarantees provided by the core.
24
26
*/
25
- #define DRIVER_ASSERT ( TEST ) \
27
+ #define DRIVER_ASSERT_RETURN ( TEST ) \
26
28
do { \
27
29
if( ! (TEST) ) \
28
30
{ \
31
33
} \
32
34
} while( 0 )
33
35
36
+ /** Like #TEST_ASSERT for use in a driver method, with cleanup.
37
+ *
38
+ * In case of error, this macro sets `status` and jumps to the
39
+ * label `exit`.
40
+ *
41
+ * Use this macro to assert on guarantees provided by the core.
42
+ */
43
+ #define DRIVER_ASSERT( TEST ) \
44
+ do { \
45
+ if( ! (TEST) ) \
46
+ { \
47
+ test_fail( #TEST, __LINE__, __FILE__ ); \
48
+ status = PSA_ERROR_DETECTED_BY_DRIVER; \
49
+ goto exit; \
50
+ } \
51
+ } while( 0 )
52
+
53
+ /** Like #PSA_ASSERT for a PSA API call that calls a driver underneath.
54
+ *
55
+ * Run the code \p expr. If this returns \p expected_status,
56
+ * do nothing. If this returns #PSA_ERROR_DETECTED_BY_DRIVER,
57
+ * jump directly to the `exit` label. If this returns any other
58
+ * status, call test_fail() then jump to `exit`.
59
+ *
60
+ * The special case for #PSA_ERROR_DETECTED_BY_DRIVER is because in this
61
+ * case, the test driver code is expected to have called test_fail()
62
+ * already, so we make sure not to overwrite the failure information.
63
+ */
64
+ #define PSA_ASSERT_VIA_DRIVER( expr, expected_status ) \
65
+ do { \
66
+ psa_status_t PSA_ASSERT_VIA_DRIVER_status = ( expr ); \
67
+ if( PSA_ASSERT_VIA_DRIVER_status == PSA_ERROR_DETECTED_BY_DRIVER ) \
68
+ goto exit; \
69
+ if( PSA_ASSERT_VIA_DRIVER_status != ( expected_status ) ) \
70
+ { \
71
+ test_fail( #expr, __LINE__, __FILE__ ); \
72
+ goto exit; \
73
+ } \
74
+ } while( 0 )
75
+
34
76
35
77
36
78
/****************************************************************/
@@ -84,11 +126,11 @@ static psa_status_t null_generate( psa_drv_se_context_t *context,
84
126
(void) slot_number;
85
127
(void) attributes;
86
128
87
- DRIVER_ASSERT ( *pubkey_length == 0 );
129
+ DRIVER_ASSERT_RETURN ( *pubkey_length == 0 );
88
130
if( ! PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
89
131
{
90
- DRIVER_ASSERT ( pubkey == NULL );
91
- DRIVER_ASSERT ( pubkey_size == 0 );
132
+ DRIVER_ASSERT_RETURN ( pubkey == NULL );
133
+ DRIVER_ASSERT_RETURN ( pubkey_size == 0 );
92
134
}
93
135
94
136
return( PSA_SUCCESS );
@@ -122,6 +164,42 @@ static void ram_slots_reset( void )
122
164
ram_min_slot = 0;
123
165
}
124
166
167
+ /* This function does everything except actually generating key material.
168
+ * After calling it, you must copy the desired key material to
169
+ * ram_slots[slot_number].content. */
170
+ static psa_status_t ram_fake_generate( psa_drv_se_context_t *context,
171
+ psa_key_slot_number_t slot_number,
172
+ const psa_key_attributes_t *attributes,
173
+ uint8_t *pubkey,
174
+ size_t pubkey_size,
175
+ size_t *pubkey_length )
176
+ {
177
+ (void) context;
178
+
179
+ DRIVER_ASSERT_RETURN( *pubkey_length == 0 );
180
+ if( ! PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
181
+ {
182
+ DRIVER_ASSERT_RETURN( pubkey == NULL );
183
+ DRIVER_ASSERT_RETURN( pubkey_size == 0 );
184
+ }
185
+
186
+ {
187
+ /* Check that the key can be stored in the memory slot.
188
+ * This check only works for key in a "raw" representation:
189
+ * symmetric keys or ECC are ok, but not RSA or FFDH. */
190
+ size_t required_storage =
191
+ PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) );
192
+ size_t available_storage = sizeof( ram_slots[slot_number].content );
193
+ if( required_storage > available_storage )
194
+ return( PSA_ERROR_INSUFFICIENT_STORAGE );
195
+ }
196
+
197
+ ram_slots[slot_number].lifetime = psa_get_key_lifetime( attributes );
198
+ ram_slots[slot_number].type = psa_get_key_type( attributes );
199
+ ram_slots[slot_number].bits = psa_get_key_bits( attributes );
200
+ return( PSA_SUCCESS );
201
+ }
202
+
125
203
static psa_status_t ram_import( psa_drv_se_context_t *context,
126
204
psa_key_slot_number_t slot_number,
127
205
const psa_key_attributes_t *attributes,
@@ -130,7 +208,7 @@ static psa_status_t ram_import( psa_drv_se_context_t *context,
130
208
size_t *bits )
131
209
{
132
210
(void) context;
133
- DRIVER_ASSERT ( slot_number < ARRAY_LENGTH( ram_slots ) );
211
+ DRIVER_ASSERT_RETURN ( slot_number < ARRAY_LENGTH( ram_slots ) );
134
212
if( data_length > sizeof( ram_slots[slot_number].content ) )
135
213
return( PSA_ERROR_INSUFFICIENT_STORAGE );
136
214
ram_slots[slot_number].lifetime = psa_get_key_lifetime( attributes );
@@ -149,7 +227,7 @@ static psa_status_t ram_export( psa_drv_se_context_t *context,
149
227
{
150
228
size_t actual_size;
151
229
(void) context;
152
- DRIVER_ASSERT ( slot_number < ARRAY_LENGTH( ram_slots ) );
230
+ DRIVER_ASSERT_RETURN ( slot_number < ARRAY_LENGTH( ram_slots ) );
153
231
actual_size = PSA_BITS_TO_BYTES( ram_slots[slot_number].bits );
154
232
if( actual_size > data_size )
155
233
return( PSA_ERROR_BUFFER_TOO_SMALL );
@@ -163,8 +241,8 @@ static psa_status_t ram_destroy( psa_drv_se_context_t *context,
163
241
psa_key_slot_number_t slot_number )
164
242
{
165
243
ram_slot_usage_t *slot_usage = persistent_data;
166
- DRIVER_ASSERT ( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
167
- DRIVER_ASSERT ( slot_number < ARRAY_LENGTH( ram_slots ) );
244
+ DRIVER_ASSERT_RETURN ( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
245
+ DRIVER_ASSERT_RETURN ( slot_number < ARRAY_LENGTH( ram_slots ) );
168
246
memset( &ram_slots[slot_number], 0, sizeof( ram_slots[slot_number] ) );
169
247
*slot_usage &= ~(ram_slot_usage_t)( 1 << slot_number );
170
248
return( PSA_SUCCESS );
@@ -177,7 +255,7 @@ static psa_status_t ram_allocate( psa_drv_se_context_t *context,
177
255
{
178
256
ram_slot_usage_t *slot_usage = persistent_data;
179
257
(void) attributes;
180
- DRIVER_ASSERT ( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
258
+ DRIVER_ASSERT_RETURN ( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
181
259
for( *slot_number = ram_min_slot;
182
260
*slot_number < ARRAY_LENGTH( ram_slots );
183
261
++( *slot_number ) )
@@ -188,6 +266,76 @@ static psa_status_t ram_allocate( psa_drv_se_context_t *context,
188
266
return( PSA_ERROR_INSUFFICIENT_STORAGE );
189
267
}
190
268
269
+ static psa_status_t ram_sign( psa_drv_se_context_t *context,
270
+ psa_key_slot_number_t slot_number,
271
+ psa_algorithm_t alg,
272
+ const uint8_t *hash,
273
+ size_t hash_length,
274
+ uint8_t *signature,
275
+ size_t signature_size,
276
+ size_t *signature_length )
277
+ {
278
+ ram_slot_t *slot;
279
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
280
+ psa_key_handle_t handle = 0;
281
+ psa_status_t status = PSA_ERROR_GENERIC_ERROR;
282
+
283
+ (void) context;
284
+ DRIVER_ASSERT_RETURN( slot_number < ARRAY_LENGTH( ram_slots ) );
285
+ slot = &ram_slots[slot_number];
286
+
287
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
288
+ psa_set_key_algorithm( &attributes, alg );
289
+ psa_set_key_type( &attributes, slot->type );
290
+ DRIVER_ASSERT( psa_import_key( &attributes,
291
+ slot->content,
292
+ PSA_BITS_TO_BYTES( slot->bits ),
293
+ &handle ) == PSA_SUCCESS );
294
+ status = psa_asymmetric_sign( handle, alg,
295
+ hash, hash_length,
296
+ signature, signature_size,
297
+ signature_length );
298
+
299
+ exit:
300
+ psa_destroy_key( handle );
301
+ return( status );
302
+ }
303
+
304
+ static psa_status_t ram_verify( psa_drv_se_context_t *context,
305
+ psa_key_slot_number_t slot_number,
306
+ psa_algorithm_t alg,
307
+ const uint8_t *hash,
308
+ size_t hash_length,
309
+ const uint8_t *signature,
310
+ size_t signature_length )
311
+ {
312
+ ram_slot_t *slot;
313
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
314
+ psa_key_handle_t handle = 0;
315
+ psa_status_t status = PSA_ERROR_GENERIC_ERROR;
316
+
317
+ (void) context;
318
+ DRIVER_ASSERT_RETURN( slot_number < ARRAY_LENGTH( ram_slots ) );
319
+ slot = &ram_slots[slot_number];
320
+
321
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
322
+ psa_set_key_algorithm( &attributes, alg );
323
+ psa_set_key_type( &attributes, slot->type );
324
+ DRIVER_ASSERT( psa_import_key( &attributes,
325
+ slot->content,
326
+ PSA_BITS_TO_BYTES( slot->bits ),
327
+ &handle ) ==
328
+ PSA_SUCCESS );
329
+ status = psa_asymmetric_verify( handle, alg,
330
+ hash, hash_length,
331
+ signature, signature_length );
332
+
333
+ exit:
334
+ psa_destroy_key( handle );
335
+ return( status );
336
+ }
337
+
338
+
191
339
192
340
193
341
/****************************************************************/
@@ -573,7 +721,6 @@ void import_key_smoke( int type_arg, int alg_arg,
573
721
574
722
exit:
575
723
PSA_DONE( );
576
- ram_slots_reset( );
577
724
psa_purge_storage( );
578
725
}
579
726
/* END_CASE */
@@ -610,7 +757,6 @@ void generate_key_not_supported( int type_arg, int bits_arg )
610
757
611
758
exit:
612
759
PSA_DONE( );
613
- ram_slots_reset( );
614
760
psa_purge_storage( );
615
761
}
616
762
/* END_CASE */
@@ -667,6 +813,126 @@ void generate_key_smoke( int type_arg, int bits_arg, int alg_arg )
667
813
PSA_ASSERT( psa_destroy_key( handle ) );
668
814
669
815
exit:
816
+ PSA_DONE( );
817
+ psa_purge_storage( );
818
+ }
819
+ /* END_CASE */
820
+
821
+ /* BEGIN_CASE */
822
+ void sign_verify( int sign_in_driver,
823
+ int type_arg, int alg_arg,
824
+ int bits_arg, data_t *key_material,
825
+ data_t *input )
826
+ {
827
+ psa_key_type_t type = type_arg;
828
+ psa_algorithm_t alg = alg_arg;
829
+ size_t bits = bits_arg;
830
+ /* Pass bits=0 to import, bits>0 to fake-generate */
831
+ int generating = ( bits != 0 );
832
+
833
+ psa_drv_se_t driver;
834
+ psa_drv_se_key_management_t key_management;
835
+ psa_drv_se_asymmetric_t asymmetric;
836
+
837
+ psa_key_lifetime_t lifetime = 2;
838
+ psa_key_id_t id = 1;
839
+ psa_key_handle_t drv_handle = 0; /* key managed by the driver */
840
+ psa_key_handle_t sw_handle = 0; /* transparent key */
841
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
842
+ uint8_t signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE];
843
+ size_t signature_length;
844
+
845
+ memset( &driver, 0, sizeof( driver ) );
846
+ memset( &key_management, 0, sizeof( key_management ) );
847
+ driver.hal_version = PSA_DRV_SE_HAL_VERSION;
848
+ driver.key_management = &key_management;
849
+ driver.asymmetric = &asymmetric;
850
+ driver.persistent_data_size = sizeof( psa_key_slot_number_t );
851
+ driver.persistent_data_size = sizeof( ram_slot_usage_t );
852
+ key_management.p_allocate = ram_allocate;
853
+ key_management.p_destroy = ram_destroy;
854
+ if( generating )
855
+ key_management.p_generate = ram_fake_generate;
856
+ else
857
+ key_management.p_import = ram_import;
858
+ if( sign_in_driver )
859
+ asymmetric.p_sign = ram_sign;
860
+ asymmetric.p_verify = ram_verify;
861
+
862
+ PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
863
+ PSA_ASSERT( psa_crypto_init( ) );
864
+
865
+ /* Create two keys with the same key material: a transparent key,
866
+ * and one that goes through the driver. */
867
+ psa_set_key_usage_flags( &attributes,
868
+ PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
869
+ psa_set_key_algorithm( &attributes, alg );
870
+ psa_set_key_type( &attributes, type );
871
+ PSA_ASSERT( psa_import_key( &attributes,
872
+ key_material->x, key_material->len,
873
+ &sw_handle ) );
874
+ psa_set_key_id( &attributes, id );
875
+ psa_set_key_lifetime( &attributes, lifetime );
876
+ if( generating )
877
+ {
878
+ psa_set_key_bits( &attributes, bits );
879
+ PSA_ASSERT( psa_generate_key( &attributes, &drv_handle ) );
880
+ /* Since we called a generate method that does not actually
881
+ * generate material, store the desired result of generation in
882
+ * the mock secure element storage. */
883
+ PSA_ASSERT( psa_get_key_attributes( drv_handle, &attributes ) );
884
+ TEST_ASSERT( key_material->len == PSA_BITS_TO_BYTES( bits ) );
885
+ memcpy( ram_slots[ram_min_slot].content, key_material->x,
886
+ key_material->len );
887
+ }
888
+ else
889
+ {
890
+ PSA_ASSERT( psa_import_key( &attributes,
891
+ key_material->x, key_material->len,
892
+ &drv_handle ) );
893
+ }
894
+
895
+ /* Sign with the chosen key. */
896
+ if( sign_in_driver )
897
+ PSA_ASSERT_VIA_DRIVER(
898
+ psa_asymmetric_sign( drv_handle,
899
+ alg,
900
+ input->x, input->len,
901
+ signature, sizeof( signature ),
902
+ &signature_length ),
903
+ PSA_SUCCESS );
904
+ else
905
+ PSA_ASSERT( psa_asymmetric_sign( sw_handle,
906
+ alg,
907
+ input->x, input->len,
908
+ signature, sizeof( signature ),
909
+ &signature_length ) );
910
+
911
+ /* Verify with both keys. */
912
+ PSA_ASSERT( psa_asymmetric_verify( sw_handle, alg,
913
+ input->x, input->len,
914
+ signature, signature_length ) );
915
+ PSA_ASSERT_VIA_DRIVER(
916
+ psa_asymmetric_verify( drv_handle, alg,
917
+ input->x, input->len,
918
+ signature, signature_length ),
919
+ PSA_SUCCESS );
920
+
921
+ /* Change the signature and verify again. */
922
+ signature[0] ^= 1;
923
+ TEST_EQUAL( psa_asymmetric_verify( sw_handle, alg,
924
+ input->x, input->len,
925
+ signature, signature_length ),
926
+ PSA_ERROR_INVALID_SIGNATURE );
927
+ PSA_ASSERT_VIA_DRIVER(
928
+ psa_asymmetric_verify( drv_handle, alg,
929
+ input->x, input->len,
930
+ signature, signature_length ),
931
+ PSA_ERROR_INVALID_SIGNATURE );
932
+
933
+ exit:
934
+ psa_destroy_key( drv_handle );
935
+ psa_destroy_key( sw_handle );
670
936
PSA_DONE( );
671
937
ram_slots_reset( );
672
938
psa_purge_storage( );
0 commit comments