1 /*
2 * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <string.h>
9 #include <stdbool.h>
10 #include "crypto_tests_common.h"
11
psa_key_interface_test(const psa_key_type_t key_type,struct test_result_t * ret)12 void psa_key_interface_test(const psa_key_type_t key_type,
13 struct test_result_t *ret)
14 {
15 psa_status_t status = PSA_SUCCESS;
16 uint32_t i = 0;
17 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
18 const uint8_t data[] = "THIS IS MY KEY1";
19 uint8_t exported_data[sizeof(data)] = {0};
20 size_t exported_data_size = 0;
21 psa_key_attributes_t key_attributes = psa_key_attributes_init();
22 psa_key_attributes_t retrieved_attributes = psa_key_attributes_init();
23
24 /* Setup the key policy */
25 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT);
26 psa_set_key_type(&key_attributes, key_type);
27
28 status = psa_import_key(&key_attributes, data, sizeof(data),
29 &key_id_local);
30 if (status != PSA_SUCCESS) {
31 TEST_FAIL("Error importing a key");
32 return;
33 }
34
35 status = psa_get_key_attributes(key_id_local, &retrieved_attributes);
36 if (status != PSA_SUCCESS) {
37 TEST_FAIL("Error getting key metadata");
38 return;
39 }
40
41 if (psa_get_key_bits(&retrieved_attributes) != BIT_SIZE_TEST_KEY) {
42 TEST_FAIL("The number of key bits is different from expected");
43 return;
44 }
45
46 if (psa_get_key_type(&retrieved_attributes) != key_type) {
47 TEST_FAIL("The type of the key is different from expected");
48 return;
49 }
50
51 psa_reset_key_attributes(&retrieved_attributes);
52
53 status = psa_export_key(key_id_local,
54 exported_data,
55 sizeof(data),
56 &exported_data_size);
57
58 if (status != PSA_SUCCESS) {
59 TEST_FAIL("Error exporting a key");
60 return;
61 }
62
63 if (exported_data_size != BYTE_SIZE_TEST_KEY) {
64 TEST_FAIL("Number of bytes of exported key different from expected");
65 return;
66 }
67
68 /* Check that the exported key is the same as the imported one */
69 for (i=0; i<exported_data_size; i++) {
70 if (exported_data[i] != data[i]) {
71 TEST_FAIL("Exported key doesn't match the imported key");
72 return;
73 }
74 }
75
76 status = psa_destroy_key(key_id_local);
77 if (status != PSA_SUCCESS) {
78 TEST_FAIL("Error destroying the key");
79 return;
80 }
81
82 status = psa_get_key_attributes(key_id_local, &retrieved_attributes);
83 if (status != PSA_ERROR_INVALID_HANDLE) {
84 TEST_FAIL("Key ID should be invalid now");
85 return;
86 }
87
88 psa_reset_key_attributes(&retrieved_attributes);
89
90 ret->val = TEST_PASSED;
91 }
92
psa_cipher_padded_modes_test(const psa_key_type_t key_type,const psa_algorithm_t alg,uint8_t len,struct test_result_t * ret)93 void psa_cipher_padded_modes_test(const psa_key_type_t key_type,
94 const psa_algorithm_t alg,
95 uint8_t len,
96 struct test_result_t *ret)
97 {
98 psa_cipher_operation_t handle = psa_cipher_operation_init();
99 psa_cipher_operation_t handle_dec = psa_cipher_operation_init();
100 psa_status_t status = PSA_SUCCESS;
101 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
102 const uint8_t data[] = "THIS IS MY KEY1";
103 const size_t iv_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type);
104 const uint8_t iv[] = "012345678901234";
105 const uint8_t plain_text[PLAIN_DATA_SIZE_PAD_TEST] =
106 "Little text, full!!";
107 uint8_t decrypted_data[ENC_DEC_BUFFER_SIZE_PAD_TEST] = {0};
108 size_t output_length = 0, total_output_length = 0;
109 uint8_t encrypted_data[ENC_DEC_BUFFER_SIZE_PAD_TEST] = {0};
110 uint32_t comp_result;
111 psa_key_attributes_t key_attributes = psa_key_attributes_init();
112 psa_key_usage_t usage = (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
113 bool bAbortDecryption = false;
114
115 if (iv_length != sizeof(iv)) {
116 /* Whenever this condition is hit, it's likely the test requires
117 * refactoring to remove any hardcoded behaviour
118 */
119 TEST_FAIL("Hardcoded IV does not match cipher block length");
120 return;
121 }
122
123 if (len > sizeof(plain_text)) {
124 TEST_FAIL("Requested input length is greater than supported");
125 return;
126 }
127
128 ret->val = TEST_PASSED;
129
130 /* Setup the key policy */
131 psa_set_key_usage_flags(&key_attributes, usage);
132 psa_set_key_algorithm(&key_attributes, alg);
133 psa_set_key_type(&key_attributes, key_type);
134
135 /* Import a key */
136 status = psa_import_key(&key_attributes, data, sizeof(data), &key_id_local);
137 if (status != PSA_SUCCESS) {
138 TEST_FAIL("Error importing a key");
139 return;
140 }
141
142 status = psa_get_key_attributes(key_id_local, &key_attributes);
143 if (status != PSA_SUCCESS) {
144 TEST_FAIL("Error getting key metadata");
145 goto destroy_key;
146 }
147
148 if (psa_get_key_bits(&key_attributes) != BIT_SIZE_TEST_KEY) {
149 TEST_FAIL("The number of key bits is different from expected");
150 goto destroy_key;
151 }
152
153 if (psa_get_key_type(&key_attributes) != key_type) {
154 TEST_FAIL("The type of the key is different from expected");
155 goto destroy_key;
156 }
157
158 /* Setup the encryption object */
159 status = psa_cipher_encrypt_setup(&handle, key_id_local, alg);
160 if (status != PSA_SUCCESS) {
161 if (status == PSA_ERROR_NOT_SUPPORTED) {
162 TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
163 } else {
164 TEST_FAIL("Error setting up cipher operation object");
165 }
166 goto destroy_key;
167 }
168
169 /* Set the IV */
170 status = psa_cipher_set_iv(&handle, iv, iv_length);
171 if (status != PSA_SUCCESS) {
172 TEST_FAIL("Error setting the IV on the cipher operation object");
173 goto abort;
174 }
175
176 /* Encrypt one chunk of information */
177 if (len < BYTE_SIZE_CHUNK) {
178 status = psa_cipher_update(&handle, plain_text,
179 len,
180 encrypted_data,
181 sizeof(encrypted_data),
182 &output_length);
183
184 if (status != PSA_SUCCESS) {
185 TEST_FAIL("Error encrypting one chunk of information");
186 goto abort;
187 }
188
189 /* When encrypting less than a block, the output is produced only
190 * when performing the following finish operation
191 */
192 if (output_length != 0) {
193 TEST_FAIL("Expected encrypted length is different from expected");
194 goto abort;
195 }
196
197 status = psa_cipher_finish(&handle, encrypted_data,
198 sizeof(encrypted_data),
199 &output_length);
200
201 if (status != PSA_SUCCESS) {
202 TEST_FAIL("Error finalising the cipher operation");
203 goto abort;
204 }
205
206 } else if (len < 2 * BYTE_SIZE_CHUNK) {
207 status = psa_cipher_update(&handle, plain_text,
208 BYTE_SIZE_CHUNK,
209 encrypted_data,
210 sizeof(encrypted_data),
211 &output_length);
212
213 if (status != PSA_SUCCESS) {
214 TEST_FAIL("Error encrypting one chunk of information");
215 goto abort;
216 }
217
218 /* When encrypting one block, the output is produced right away */
219 if (output_length != BYTE_SIZE_CHUNK) {
220 TEST_FAIL("Expected encrypted length is different from expected");
221 goto abort;
222 }
223
224 total_output_length += output_length;
225 status = psa_cipher_update(&handle, &plain_text[BYTE_SIZE_CHUNK],
226 len % BYTE_SIZE_CHUNK,
227 &encrypted_data[total_output_length],
228 sizeof(encrypted_data) - total_output_length,
229 &output_length);
230 if (status != PSA_SUCCESS) {
231 TEST_FAIL("Error encrypting one chunk of information");
232 goto abort;
233 }
234
235 /* When encrypting less than a block, the output is zero */
236 if (output_length != 0) {
237 TEST_FAIL("Expected encrypted length is different from expected");
238 goto abort;
239 }
240
241 /* The output is then produced only when calling finish if the previous
242 * update did not produce any output - We need to take padding into
243 * account
244 */
245 total_output_length += output_length;
246 status = psa_cipher_finish(&handle, &encrypted_data[total_output_length],
247 sizeof(encrypted_data) - total_output_length,
248 &output_length);
249
250 total_output_length += output_length;
251 }
252
253 /* Setup the decryption object */
254 status = psa_cipher_decrypt_setup(&handle_dec, key_id_local, alg);
255 if (status != PSA_SUCCESS) {
256 TEST_FAIL("Error setting up cipher operation object");
257 goto destroy_key;
258 }
259
260 /* From now on, in case of failure we want to abort the decryption op */
261 bAbortDecryption = true;
262
263 /* Set the IV for decryption */
264 status = psa_cipher_set_iv(&handle_dec, iv, iv_length);
265 if (status != PSA_SUCCESS) {
266 TEST_FAIL("Error setting the IV for decryption");
267 goto abort;
268 }
269
270 /* Reset total output length */
271 total_output_length = 0;
272 if (len < BYTE_SIZE_CHUNK) {
273 status = psa_cipher_update(&handle_dec,
274 encrypted_data,
275 BYTE_SIZE_CHUNK,
276 decrypted_data,
277 sizeof(decrypted_data),
278 &output_length);
279
280 if (status != PSA_SUCCESS) {
281 TEST_FAIL("Error decrypting one chunk of information");
282 goto abort;
283 }
284
285 /* Doesn't produce output on the first cipher update */
286 if (output_length != 0) {
287 TEST_FAIL("Expected decrypted length is different from expected");
288 goto abort;
289 }
290
291 status = psa_cipher_finish(&handle_dec, decrypted_data,
292 sizeof(decrypted_data),
293 &output_length);
294
295 if (status != PSA_SUCCESS) {
296 TEST_FAIL("Error finalising the cipher operation");
297 goto abort;
298 }
299
300 if (output_length != len) {
301 TEST_FAIL("Expected decrypted length is different from expected");
302 goto destroy_key;
303 }
304
305 } else if (len < 2*BYTE_SIZE_CHUNK) {
306 status = psa_cipher_update(&handle_dec, encrypted_data,
307 BYTE_SIZE_CHUNK,
308 decrypted_data,
309 sizeof(decrypted_data),
310 &output_length);
311
312 if (status != PSA_SUCCESS) {
313 TEST_FAIL("Error encrypting one chunk of information");
314 goto abort;
315 }
316
317 /* Doesn't produce output on the first cipher update */
318 if (output_length != 0) {
319 TEST_FAIL("Expected decrypted length is different from expected");
320 goto abort;
321 }
322
323 total_output_length += output_length;
324 status = psa_cipher_update(&handle_dec,
325 &encrypted_data[BYTE_SIZE_CHUNK],
326 BYTE_SIZE_CHUNK,
327 &decrypted_data[total_output_length],
328 sizeof(decrypted_data) - total_output_length,
329 &output_length);
330
331 if (status != PSA_SUCCESS) {
332 TEST_FAIL("Error decrypting one chunk of information");
333 goto abort;
334 }
335
336 /* We now get the output corresponding to the previous block */
337 if (output_length != BYTE_SIZE_CHUNK) {
338 TEST_FAIL("Expected decrypted length is different from expected");
339 goto abort;
340 }
341
342 total_output_length += output_length;
343 status = psa_cipher_finish(&handle_dec,
344 &decrypted_data[total_output_length],
345 sizeof(decrypted_data) - total_output_length,
346 &output_length);
347 if (status != PSA_SUCCESS) {
348 TEST_FAIL("Error finalising the cipher operation");
349 goto abort;
350 }
351
352 total_output_length += output_length;
353 if (total_output_length != len) {
354 TEST_FAIL("Expected decrypted length is different from expected");
355 goto destroy_key;
356 }
357 }
358
359 /* Check that the plain text matches the decrypted data */
360 comp_result = memcmp(plain_text, decrypted_data, len);
361 if (comp_result != 0) {
362 TEST_FAIL("Decrypted data doesn't match with plain text");
363 goto destroy_key;
364 }
365
366 /* Go directly to destroy key from here */
367 goto destroy_key;
368
369 abort:
370 /* Abort the operation */
371 status = bAbortDecryption ? psa_cipher_abort(&handle_dec) :
372 psa_cipher_abort(&handle);
373 if (status != PSA_SUCCESS) {
374 TEST_FAIL("Error aborting the operation");
375 }
376 destroy_key:
377 /* Destroy the key */
378 status = psa_destroy_key(key_id_local);
379 if (status != PSA_SUCCESS) {
380 TEST_FAIL("Error destroying a key");
381 }
382 }
383
384 #ifdef TFM_CRYPTO_TEST_CHACHA20
385 /* Chacha20 test vectors are taken directly from RFC7539 */
386 static const uint8_t chacha20_testKey[] = {
387 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
388 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
389 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
390 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
391 };
392
393 static const uint8_t chacha20_testNonce[] = {
394 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x4a,
396 0x00, 0x00, 0x00, 0x00
397 };
398
399 /* The initial counter of the Chacha20 RFC7539 test vectors is 1, while the PSA
400 * APIs assume it to be zero. This means that this expected ciphertext is not
401 * the same as the one presented in the RFC
402 */
403 static const uint8_t chacha20_testCiphertext_expected[] = {
404 0xe3, 0x64, 0x7a, 0x29, 0xde, 0xd3, 0x15, 0x28, 0xef, 0x56, 0xba, 0xc7,
405 0x0f, 0x7a, 0x7a, 0xc3, 0xb7, 0x35, 0xc7, 0x44, 0x4d, 0xa4, 0x2d, 0x99,
406 0x82, 0x3e, 0xf9, 0x93, 0x8c, 0x8e, 0xbf, 0xdc, 0xf0, 0x5b, 0xb7, 0x1a,
407 0x82, 0x2c, 0x62, 0x98, 0x1a, 0xa1, 0xea, 0x60, 0x8f, 0x47, 0x93, 0x3f,
408 0x2e, 0xd7, 0x55, 0xb6, 0x2d, 0x93, 0x12, 0xae, 0x72, 0x03, 0x76, 0x74,
409 0xf3, 0xe9, 0x3e, 0x24, 0x4c, 0x23, 0x28, 0xd3, 0x2f, 0x75, 0xbc, 0xc1,
410 0x5b, 0xb7, 0x57, 0x4f, 0xde, 0x0c, 0x6f, 0xcd, 0xf8, 0x7b, 0x7a, 0xa2,
411 0x5b, 0x59, 0x72, 0x97, 0x0c, 0x2a, 0xe6, 0xcc, 0xed, 0x86, 0xa1, 0x0b,
412 0xe9, 0x49, 0x6f, 0xc6, 0x1c, 0x40, 0x7d, 0xfd, 0xc0, 0x15, 0x10, 0xed,
413 0x8f, 0x4e, 0xb3, 0x5d, 0x0d, 0x62
414 };
415 #endif /* TFM_CRYPTO_TEST_CHACHA20 */
416
417 #if defined(TFM_CRYPTO_TEST_CHACHA20) || \
418 defined(TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305)
419 /* The plaintext of the vectors is the same for both Chacha20 and
420 * Chacha20-Poly1305
421 */
422 static const uint8_t chacha20_testPlaintext[] = {
423 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47,
424 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
425 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66,
426 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
427 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79,
428 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
429 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20,
430 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
431 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20,
432 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e
433 };
434 /* To hold intermediate results in both Chacha20 and Chacha20-Poly1305 */
435 static uint8_t chacha20_testCiphertext[sizeof(chacha20_testPlaintext)] = {0};
436 static uint8_t chacha20_testDecryptedtext[sizeof(chacha20_testPlaintext)] = {0};
437 #endif /* TFM_CRYPTO_TEST_CHACHA20 || TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305 */
438
439 #ifdef TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305
440 /* Chacha20-Poly1305 test vectors are taken directly from RFC7539 */
441 static const uint8_t chacha20poly1305_testKey[] = {
442 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
443 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
444 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
445 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
446 };
447
448 static const uint8_t chacha20poly1305_testNonce[] = {
449 0x07, 0x00, 0x00, 0x00, /* constant */
450 0x40, 0x41, 0x42, 0x43, /* IV[0] */
451 0x44, 0x45, 0x46, 0x47 /* IV[1] */
452 };
453
454 static const uint8_t chacha20poly1305_testAad[] = {
455 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7
456 };
457
458 static const uint8_t chacha20poly1305_testCiphertext_expected[] = {
459 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc,
460 0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
461 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e,
462 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
463 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6,
464 0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
465 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4,
466 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
467 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65,
468 0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16
469 };
470
471 static const uint8_t chacha20poly1305_testTag_expected[] = {
472 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
473 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
474 };
475 #endif /* TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305 */
476
477 #ifdef TFM_CRYPTO_TEST_CHACHA20
psa_cipher_rfc7539_test(struct test_result_t * ret)478 void psa_cipher_rfc7539_test(struct test_result_t *ret)
479 {
480 psa_cipher_operation_t handle = psa_cipher_operation_init();
481 psa_cipher_operation_t handle_dec = psa_cipher_operation_init();
482 psa_status_t status = PSA_SUCCESS;
483 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
484 psa_key_attributes_t key_attributes = psa_key_attributes_init();
485 psa_key_usage_t usage = (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
486 const psa_key_type_t key_type = PSA_KEY_TYPE_CHACHA20;
487 const psa_algorithm_t alg = PSA_ALG_STREAM_CIPHER;
488 bool bAbortDecryption = false;
489 /* Variables required during multipart update */
490 size_t data_left = sizeof(chacha20_testPlaintext);
491 size_t lengths[] = {42, 24, 48};
492 size_t start_idx = 0;
493 size_t output_length = 0; size_t total_output_length = 0;
494 int comp_result;
495
496 ret->val = TEST_PASSED;
497
498 /* Setup the key policy */
499 psa_set_key_usage_flags(&key_attributes, usage);
500 psa_set_key_algorithm(&key_attributes, alg);
501 psa_set_key_type(&key_attributes, key_type);
502
503 status = psa_import_key(&key_attributes, chacha20_testKey,
504 sizeof(chacha20_testKey), &key_id_local);
505
506 if (status != PSA_SUCCESS) {
507 TEST_FAIL("Error importing a key");
508 return;
509 }
510
511 /* Setup the encryption object */
512 status = psa_cipher_encrypt_setup(&handle, key_id_local, alg);
513 if (status != PSA_SUCCESS) {
514 TEST_FAIL("Encryption setup shouldn't fail");
515 goto destroy_key;
516 }
517
518 /* Set the IV */
519 status = psa_cipher_set_iv(&handle,
520 chacha20_testNonce, sizeof(chacha20_testNonce));
521 if (status != PSA_SUCCESS) {
522 TEST_FAIL("Error setting the IV on the cipher operation object");
523 goto abort;
524 }
525
526 for (int i=0; i<sizeof(lengths)/sizeof(size_t); i++) {
527 /* Encrypt one chunk of information */
528 status = psa_cipher_update(
529 &handle,
530 &chacha20_testPlaintext[start_idx],
531 lengths[i],
532 &chacha20_testCiphertext[total_output_length],
533 sizeof(chacha20_testCiphertext) - total_output_length,
534 &output_length);
535
536 if (status != PSA_SUCCESS) {
537 TEST_FAIL("Error encrypting one chunk of information");
538 goto abort;
539 }
540
541 if (output_length != lengths[i]) {
542 TEST_FAIL("Expected encrypted length is different from expected");
543 goto abort;
544 }
545
546 data_left -= lengths[i];
547 total_output_length += output_length;
548
549 start_idx += lengths[i];
550 }
551
552 /* Finalise the cipher operation */
553 status = psa_cipher_finish(
554 &handle,
555 &chacha20_testCiphertext[total_output_length],
556 sizeof(chacha20_testCiphertext) - total_output_length,
557 &output_length);
558
559 if (status != PSA_SUCCESS) {
560 TEST_FAIL("Error finalising the cipher operation");
561 goto abort;
562 }
563
564 if (output_length != 0) {
565 TEST_FAIL("Un-padded mode final output length unexpected");
566 goto abort;
567 }
568
569 /* Add the last output produced, it might be encrypted padding */
570 total_output_length += output_length;
571
572 /* Compare encrypted data produced with single-shot and multipart APIs */
573 comp_result = memcmp(chacha20_testCiphertext_expected,
574 chacha20_testCiphertext,
575 total_output_length);
576 if (comp_result != 0) {
577 TEST_FAIL("Single-shot crypt doesn't match with multipart crypt");
578 goto destroy_key;
579 }
580
581 /* Setup the decryption object */
582 status = psa_cipher_decrypt_setup(&handle_dec, key_id_local, alg);
583 if (status != PSA_SUCCESS) {
584 TEST_FAIL("Error setting up cipher operation object");
585 goto destroy_key;
586 }
587
588 /* From now on, in case of failure we want to abort the decryption op */
589 bAbortDecryption = true;
590
591 /* Set the IV for decryption */
592 status = psa_cipher_set_iv(&handle_dec,
593 chacha20_testNonce, sizeof(chacha20_testNonce));
594 if (status != PSA_SUCCESS) {
595 TEST_FAIL("Error setting the IV for decryption");
596 goto abort;
597 }
598
599 /* Decrypt - total_output_length considers encrypted padding */
600 data_left = total_output_length;
601 /* Update in different chunks of plainText */
602 lengths[0] = 14; lengths[1] = 70; lengths[2] = 30;
603 start_idx = 0;
604 output_length = 0; total_output_length = 0;
605 for (int i=0; i<sizeof(lengths)/sizeof(size_t); i++) {
606 status = psa_cipher_update(
607 &handle_dec,
608 &chacha20_testCiphertext[start_idx],
609 lengths[i],
610 &chacha20_testDecryptedtext[total_output_length],
611 sizeof(chacha20_testDecryptedtext) - total_output_length,
612 &output_length);
613
614 if (status != PSA_SUCCESS) {
615 TEST_FAIL("Error decrypting one chunk of information");
616 goto abort;
617 }
618
619 if (output_length != lengths[i]) {
620 TEST_FAIL("Expected encrypted length is different from expected");
621 goto abort;
622 }
623
624 data_left -= lengths[i];
625 total_output_length += output_length;
626
627 start_idx += lengths[i];
628 }
629
630 /* Finalise the cipher operation for decryption */
631 status = psa_cipher_finish(
632 &handle_dec,
633 &chacha20_testDecryptedtext[total_output_length],
634 sizeof(chacha20_testDecryptedtext) - total_output_length,
635 &output_length);
636
637 if (status != PSA_SUCCESS) {
638 TEST_FAIL("Error finalising the cipher operation");
639 goto abort;
640 }
641
642 /* Finalize the count of output which has been produced */
643 total_output_length += output_length;
644
645 /* Check that the decrypted length is equal to the original length */
646 if (total_output_length != sizeof(chacha20_testPlaintext)) {
647 TEST_FAIL("After finalising, unexpected decrypted length");
648 goto destroy_key;
649 }
650
651 /* Check that the plain text matches the decrypted data */
652 comp_result = memcmp(chacha20_testPlaintext,
653 chacha20_testDecryptedtext,
654 sizeof(chacha20_testPlaintext));
655 if (comp_result != 0) {
656 TEST_FAIL("Decrypted data doesn't match with plain text");
657 }
658
659 /* Go directly to the destroy_key label at this point */
660 goto destroy_key;
661
662 abort:
663 /* Abort the operation */
664 status = bAbortDecryption ? psa_cipher_abort(&handle_dec) :
665 psa_cipher_abort(&handle);
666 if (status != PSA_SUCCESS) {
667 TEST_FAIL("Error aborting the operation");
668 }
669 destroy_key:
670 /* Destroy the key */
671 status = psa_destroy_key(key_id_local);
672 if (status != PSA_SUCCESS) {
673 TEST_FAIL("Error destroying a key");
674 }
675
676 return;
677 }
678 #endif /* TFM_CRYPTO_TEST_CHACHA20 */
679
680 #ifdef TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305
psa_aead_rfc7539_test(struct test_result_t * ret)681 void psa_aead_rfc7539_test(struct test_result_t *ret)
682 {
683 psa_aead_operation_t handle = psa_aead_operation_init();
684 psa_aead_operation_t handle_dec = psa_aead_operation_init();
685 psa_status_t status = PSA_SUCCESS;
686 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
687 psa_key_attributes_t key_attributes = psa_key_attributes_init();
688 psa_key_usage_t usage = (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
689 const psa_key_type_t key_type = PSA_KEY_TYPE_CHACHA20;
690 const psa_algorithm_t alg = PSA_ALG_CHACHA20_POLY1305;
691 uint8_t tag[16] = {0}; /* tag in chacha20-poly1305 is 16 bytes */
692 size_t tag_length = 0;
693 bool bAbortDecryption = false;
694 /* Variables related to multipart update */
695 size_t data_left = sizeof(chacha20_testPlaintext);
696 size_t lengths[] = {42, 24, 48};
697 size_t start_idx = 0;
698 size_t output_length = 0; size_t total_output_length = 0;
699 int comp_result;
700
701 ret->val = TEST_PASSED;
702
703 /* Setup the key policy */
704 psa_set_key_usage_flags(&key_attributes, usage);
705 psa_set_key_algorithm(&key_attributes, alg);
706 psa_set_key_type(&key_attributes, key_type);
707 status = psa_import_key(&key_attributes, chacha20poly1305_testKey,
708 sizeof(chacha20poly1305_testKey), &key_id_local);
709
710 if (status != PSA_SUCCESS) {
711 TEST_FAIL("Error importing a key");
712 return;
713 }
714
715 /* Setup the encryption object */
716 status = psa_aead_encrypt_setup(&handle, key_id_local, alg);
717 if (status != PSA_SUCCESS) {
718 TEST_FAIL("Encryption setup shouldn't fail");
719 goto destroy_key;
720 }
721
722 /* Set the IV */
723 status = psa_aead_set_nonce(&handle,
724 chacha20poly1305_testNonce,
725 sizeof(chacha20poly1305_testNonce));
726 if (status != PSA_SUCCESS) {
727 TEST_FAIL("Error setting the nonce on the aead operation object");
728 goto abort;
729 }
730
731 /* Set lengths */
732 status = psa_aead_set_lengths(&handle,
733 sizeof(chacha20poly1305_testAad),
734 sizeof(chacha20_testPlaintext));
735 if (status != PSA_SUCCESS) {
736 TEST_FAIL("Error setting the lengths on the aead operation object");
737 goto abort;
738 }
739
740 /* Update AD in one go */
741 status = psa_aead_update_ad(&handle,
742 chacha20poly1305_testAad,
743 sizeof(chacha20poly1305_testAad));
744 if (status != PSA_SUCCESS) {
745 TEST_FAIL("Error updating AD");
746 goto abort;
747 }
748
749 for (int i=0; i<sizeof(lengths)/sizeof(size_t); i++) {
750 /* Encrypt one chunk of information */
751 status = psa_aead_update(
752 &handle,
753 &chacha20_testPlaintext[start_idx],
754 lengths[i],
755 &chacha20_testCiphertext[total_output_length],
756 sizeof(chacha20_testCiphertext) - total_output_length,
757 &output_length);
758
759 if (status != PSA_SUCCESS) {
760 TEST_FAIL("Error encrypting one chunk of information");
761 goto abort;
762 }
763
764 if (output_length != lengths[i]) {
765 TEST_FAIL("Expected encrypted length is different from expected");
766 goto abort;
767 }
768
769 data_left -= lengths[i];
770 total_output_length += output_length;
771
772 start_idx += lengths[i];
773 }
774
775 /* Finalise the cipher operation */
776 status = psa_aead_finish(
777 &handle,
778 &chacha20_testCiphertext[total_output_length],
779 sizeof(chacha20_testCiphertext) - total_output_length,
780 &output_length,
781 tag,
782 sizeof(tag),
783 &tag_length);
784
785 if (status != PSA_SUCCESS) {
786 TEST_FAIL("Error finalising the cipher operation");
787 goto abort;
788 }
789
790 if (output_length != 0) {
791 TEST_FAIL("Un-padded mode final output length unexpected");
792 goto abort;
793 }
794
795 if (tag_length != 16) {
796 TEST_FAIL("Unexpected tag length different than 16");
797 goto abort;
798 }
799
800 /* Add the last output produced, it might be encrypted padding */
801 total_output_length += output_length;
802
803 /* Compare encrypted data produced with single-shot and multipart APIs */
804 comp_result = memcmp(chacha20poly1305_testCiphertext_expected,
805 chacha20_testCiphertext,
806 total_output_length);
807 if (comp_result != 0) {
808 TEST_FAIL("Encrypted data does not match reference data");
809 goto destroy_key;
810 }
811
812 comp_result = memcmp(chacha20poly1305_testTag_expected, tag, tag_length);
813 if (comp_result != 0) {
814 TEST_FAIL("Computed tag does not match reference data");
815 goto destroy_key;
816 }
817
818 /* Setup the decryption object */
819 status = psa_aead_decrypt_setup(&handle_dec, key_id_local, alg);
820 if (status != PSA_SUCCESS) {
821 TEST_FAIL("Error setting up aead operation object");
822 goto destroy_key;
823 }
824
825 /* From now on, in case of failure we want to abort the decryption op */
826 bAbortDecryption = true;
827
828 /* Set the IV for decryption */
829 status = psa_aead_set_nonce(&handle_dec,
830 chacha20poly1305_testNonce,
831 sizeof(chacha20poly1305_testNonce));
832 if (status != PSA_SUCCESS) {
833 TEST_FAIL("Error setting the nonce for decryption");
834 goto abort;
835 }
836
837 /* Set lengths */
838 status = psa_aead_set_lengths(&handle_dec,
839 sizeof(chacha20poly1305_testAad),
840 sizeof(chacha20_testPlaintext));
841 if (status != PSA_SUCCESS) {
842 TEST_FAIL("Error setting the lengths on the aead operation object");
843 goto abort;
844 }
845
846 /* Update AD in one go */
847 status = psa_aead_update_ad(&handle_dec,
848 chacha20poly1305_testAad,
849 sizeof(chacha20poly1305_testAad));
850 if (status != PSA_SUCCESS) {
851 TEST_FAIL("Error updating AD");
852 goto abort;
853 }
854
855 /* Decrypt - total_output_length considers encrypted padding */
856 data_left = total_output_length;
857 /* Update in different chunks of plainText */
858 lengths[0] = 14; lengths[1] = 70; lengths[2] = 30;
859 start_idx = 0;
860 output_length = 0; total_output_length = 0;
861 for (int i=0; i<sizeof(lengths)/sizeof(size_t); i++) {
862 status = psa_aead_update(
863 &handle_dec,
864 &chacha20_testCiphertext[start_idx],
865 lengths[i],
866 &chacha20_testDecryptedtext[total_output_length],
867 sizeof(chacha20_testDecryptedtext) - total_output_length,
868 &output_length);
869
870 if (status != PSA_SUCCESS) {
871 TEST_FAIL("Error decrypting one chunk of information");
872 goto abort;
873 }
874
875 if (output_length != lengths[i]) {
876 TEST_FAIL("Expected encrypted length is different from expected");
877 goto abort;
878 }
879
880 data_left -= lengths[i];
881 total_output_length += output_length;
882
883 start_idx += lengths[i];
884 }
885
886 /* Finalise the cipher operation for decryption (destroys decrypted data) */
887 status = psa_aead_verify(
888 &handle_dec,
889 &chacha20_testDecryptedtext[total_output_length],
890 sizeof(chacha20_testDecryptedtext) - total_output_length,
891 &output_length,
892 tag,
893 tag_length);
894
895 if (status != PSA_SUCCESS) {
896 TEST_FAIL("Error verifying the aead operation");
897 goto abort;
898 }
899
900 /* Finalize the count of output which has been produced */
901 total_output_length += output_length;
902
903 /* Check that the decrypted length is equal to the original length */
904 if (total_output_length != sizeof(chacha20_testPlaintext)) {
905 TEST_FAIL("After finalising, unexpected decrypted length");
906 goto destroy_key;
907 }
908
909 /* Check that the plain text matches the decrypted data */
910 comp_result = memcmp(chacha20_testPlaintext,
911 chacha20_testDecryptedtext,
912 sizeof(chacha20_testPlaintext));
913 if (comp_result != 0) {
914 TEST_FAIL("Decrypted data doesn't match with plain text");
915 }
916
917 /* Go directly to the destroy_key label at this point */
918 goto destroy_key;
919
920 abort:
921 /* Abort the operation */
922 status = bAbortDecryption ? psa_aead_abort(&handle_dec) :
923 psa_aead_abort(&handle);
924 if (status != PSA_SUCCESS) {
925 TEST_FAIL("Error aborting the operation");
926 }
927 destroy_key:
928 /* Destroy the key */
929 status = psa_destroy_key(key_id_local);
930 if (status != PSA_SUCCESS) {
931 TEST_FAIL("Error destroying a key");
932 }
933
934 return;
935 }
936 #endif /* TFM_CRYPTO_TEST_ALG_CHACHA20_POLY1305 */
937
psa_cipher_test(const psa_key_type_t key_type,const psa_algorithm_t alg,const uint8_t * key,size_t key_bits,struct test_result_t * ret)938 void psa_cipher_test(const psa_key_type_t key_type,
939 const psa_algorithm_t alg,
940 const uint8_t *key,
941 size_t key_bits,
942 struct test_result_t *ret)
943 {
944 psa_cipher_operation_t handle = psa_cipher_operation_init();
945 psa_cipher_operation_t handle_dec = psa_cipher_operation_init();
946 psa_status_t status = PSA_SUCCESS;
947 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
948 size_t iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
949 uint8_t iv[16] = {0};
950 const uint8_t plain_text[PLAIN_DATA_SIZE] =
951 "This is my plaintext to encrypt, 48 bytes long!";
952 uint8_t decrypted_data[ENC_DEC_BUFFER_SIZE] = {0};
953 size_t output_length = 0, total_output_length = 0;
954 union {
955 uint8_t encrypted_data[ENC_DEC_BUFFER_SIZE];
956 uint8_t encrypted_data_pad[ENC_DEC_BUFFER_SIZE_PAD_MODES];
957 } input = {0};
958 uint32_t comp_result;
959 psa_key_attributes_t key_attributes = psa_key_attributes_init();
960 psa_key_usage_t usage = (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
961 bool bAbortDecryption = false;
962 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
963 uint8_t encrypted_data_single_shot[ENC_DEC_BUFFER_SIZE];
964 #endif
965
966 if (iv_length > 16) {
967 TEST_FAIL("Unexpected IV length greater than 16 for this alg/key type");
968 return;
969 }
970
971 ret->val = TEST_PASSED;
972
973 /* Setup the key policy */
974 psa_set_key_usage_flags(&key_attributes, usage);
975 psa_set_key_algorithm(&key_attributes, alg);
976 psa_set_key_type(&key_attributes, key_type);
977
978 /* Import a key */
979 status = psa_import_key(&key_attributes, key, PSA_BITS_TO_BYTES(key_bits),
980 &key_id_local);
981
982 if (status != PSA_SUCCESS) {
983 TEST_FAIL("Error importing a key");
984 return;
985 }
986
987 status = psa_get_key_attributes(key_id_local, &key_attributes);
988 if (status != PSA_SUCCESS) {
989 TEST_FAIL("Error getting key metadata");
990 goto destroy_key;
991 }
992
993 if (psa_get_key_bits(&key_attributes) != key_bits) {
994 TEST_FAIL("The number of key bits is different from expected");
995 goto destroy_key;
996 }
997
998 if (psa_get_key_type(&key_attributes) != key_type) {
999 TEST_FAIL("The type of the key is different from expected");
1000 goto destroy_key;
1001 }
1002
1003 psa_reset_key_attributes(&key_attributes);
1004
1005 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
1006 /* Encrypt single part functions */
1007 status = psa_cipher_encrypt(key_id_local, alg, plain_text,
1008 sizeof(plain_text),
1009 input.encrypted_data_pad,
1010 sizeof(input.encrypted_data_pad),
1011 &output_length);
1012
1013 if (status != PSA_SUCCESS) {
1014 TEST_FAIL("Error encrypting with the single-shot API");
1015 goto destroy_key;
1016 }
1017
1018 /* Store a copy of the encrypted data for later checking it against
1019 * multipart results
1020 */
1021 memcpy(encrypted_data_single_shot, &input.encrypted_data_pad[iv_length],
1022 output_length-iv_length);
1023
1024 /* Make sure to use the randomly generated IV for the multipart flow */
1025 for (int i=0; i<iv_length; i++) {
1026 iv[i] = input.encrypted_data_pad[i];
1027 }
1028
1029 status = psa_cipher_decrypt(key_id_local, alg,
1030 input.encrypted_data_pad,
1031 output_length,
1032 decrypted_data, ENC_DEC_BUFFER_SIZE,
1033 &output_length);
1034 if (status != PSA_SUCCESS) {
1035 TEST_FAIL("Error decrypting with the single shot API");
1036 goto destroy_key;
1037 }
1038
1039 if (sizeof(plain_text) != output_length) {
1040 TEST_FAIL("Unexpected output length");
1041 goto destroy_key;
1042 }
1043
1044 /* Check that the plain text matches the decrypted data */
1045 comp_result = memcmp(plain_text, decrypted_data, sizeof(plain_text));
1046 if (comp_result != 0) {
1047 TEST_FAIL("Decrypted data doesn't match with plain text");
1048 goto destroy_key;
1049 }
1050
1051 /* Clear inputs/outputs before moving to multipart tests */
1052
1053 /* Clear intermediate buffers for additional single-shot API tests */
1054 memset(input.encrypted_data_pad, 0, sizeof(input.encrypted_data_pad));
1055 memset(decrypted_data, 0, sizeof(decrypted_data));
1056 #endif /* TFM_CRYPTO_TEST_SINGLE_PART_FUNCS */
1057
1058 /* Replicate the same test as above, but now using the multipart APIs */
1059
1060 /* Setup the encryption object */
1061 status = psa_cipher_encrypt_setup(&handle, key_id_local, alg);
1062 if (status != PSA_SUCCESS) {
1063 if (status == PSA_ERROR_NOT_SUPPORTED) {
1064 TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
1065 } else {
1066 TEST_FAIL("Error setting up cipher operation object");
1067 }
1068 goto destroy_key;
1069 }
1070
1071 /* Set the IV */
1072 if (alg != PSA_ALG_ECB_NO_PADDING) {
1073 status = psa_cipher_set_iv(&handle, iv, iv_length);
1074 if (status != PSA_SUCCESS) {
1075 TEST_FAIL("Error setting the IV on the cipher operation object");
1076 goto abort;
1077 }
1078 }
1079
1080 size_t data_left = sizeof(plain_text);
1081 while (data_left) {
1082 /* Encrypt one chunk of information */
1083 status = psa_cipher_update(&handle, &plain_text[total_output_length],
1084 BYTE_SIZE_CHUNK,
1085 &input.encrypted_data[total_output_length],
1086 ENC_DEC_BUFFER_SIZE - total_output_length,
1087 &output_length);
1088
1089 if (status != PSA_SUCCESS) {
1090 TEST_FAIL("Error encrypting one chunk of information");
1091 goto abort;
1092 }
1093
1094 if (output_length != BYTE_SIZE_CHUNK) {
1095 TEST_FAIL("Expected encrypted length is different from expected");
1096 goto abort;
1097 }
1098
1099 data_left -= BYTE_SIZE_CHUNK;
1100 total_output_length += output_length;
1101 }
1102
1103 /* Finalise the cipher operation */
1104 status = psa_cipher_finish(&handle,
1105 &input.encrypted_data[total_output_length],
1106 ENC_DEC_BUFFER_SIZE - total_output_length,
1107 &output_length);
1108
1109 if (status != PSA_SUCCESS) {
1110 TEST_FAIL("Error finalising the cipher operation");
1111 goto abort;
1112 }
1113
1114 if (alg == PSA_ALG_CBC_PKCS7) {
1115 /* Finalisation produces an output for padded modes, which is the
1116 * encryption of the padded data added
1117 */
1118 if (output_length != BYTE_SIZE_CHUNK) {
1119 TEST_FAIL("Padded mode final output length unexpected");
1120 goto abort;
1121 }
1122 } else {
1123 if (output_length != 0) {
1124 TEST_FAIL("Un-padded mode final output length unexpected");
1125 goto abort;
1126 }
1127 }
1128
1129 /* Add the last output produced, it might be encrypted padding */
1130 total_output_length += output_length;
1131
1132 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
1133 /* Compare encrypted data produced with single-shot and multipart APIs */
1134 comp_result = memcmp(encrypted_data_single_shot,
1135 input.encrypted_data,
1136 total_output_length);
1137 if (comp_result != 0) {
1138 TEST_FAIL("Single-shot crypt doesn't match with multipart crypt");
1139 goto destroy_key;
1140 }
1141 #endif /* TFM_CRYPTO_TEST_SINGLE_PART_FUNCS */
1142
1143 /* Setup the decryption object */
1144 status = psa_cipher_decrypt_setup(&handle_dec, key_id_local, alg);
1145 if (status != PSA_SUCCESS) {
1146 TEST_FAIL("Error setting up cipher operation object");
1147 goto destroy_key;
1148 }
1149
1150 /* From now on, in case of failure we want to abort the decryption op */
1151 bAbortDecryption = true;
1152
1153 /* Set the IV for decryption */
1154 if (alg != PSA_ALG_ECB_NO_PADDING) {
1155 status = psa_cipher_set_iv(&handle_dec, iv, iv_length);
1156 if (status != PSA_SUCCESS) {
1157 TEST_FAIL("Error setting the IV for decryption");
1158 goto abort;
1159 }
1160 }
1161
1162 /* Padded mode output is produced one block later */
1163 bool bIsLagging = false;
1164 if (alg == PSA_ALG_CBC_PKCS7) {
1165 bIsLagging = true; /* Padded modes lag by 1 block */
1166 }
1167
1168 /* Decrypt - total_output_length considers encrypted padding */
1169 data_left = total_output_length;
1170 total_output_length = 0;
1171 size_t message_start = 0;
1172 while (data_left) {
1173 status = psa_cipher_update(&handle_dec,
1174 &input.encrypted_data[message_start],
1175 BYTE_SIZE_CHUNK,
1176 &decrypted_data[total_output_length],
1177 (ENC_DEC_BUFFER_SIZE - total_output_length),
1178 &output_length);
1179
1180 if (status != PSA_SUCCESS) {
1181 TEST_FAIL("Error decrypting one chunk of information");
1182 goto abort;
1183 }
1184
1185 if (!bIsLagging && output_length != BYTE_SIZE_CHUNK) {
1186 TEST_FAIL("Expected encrypted length is different from expected");
1187 goto abort;
1188 }
1189
1190 message_start += BYTE_SIZE_CHUNK;
1191 data_left -= BYTE_SIZE_CHUNK;
1192 total_output_length += output_length;
1193 bIsLagging = false;
1194 }
1195
1196 /* Finalise the cipher operation for decryption (destroys decrypted data) */
1197 status = psa_cipher_finish(&handle_dec, &decrypted_data[total_output_length],
1198 BYTE_SIZE_CHUNK,
1199 &output_length);
1200
1201 if (status != PSA_SUCCESS) {
1202 TEST_FAIL("Error finalising the cipher operation");
1203 goto abort;
1204 }
1205
1206 /* Finalize the count of output which has been produced */
1207 total_output_length += output_length;
1208
1209 /* Check that the decrypted length is equal to the original length */
1210 if (total_output_length != 3*BYTE_SIZE_CHUNK) {
1211 TEST_FAIL("After finalising, unexpected decrypted length");
1212 goto destroy_key;
1213 }
1214
1215 /* Check that the plain text matches the decrypted data */
1216 comp_result = memcmp(plain_text, decrypted_data, sizeof(plain_text));
1217 if (comp_result != 0) {
1218 TEST_FAIL("Decrypted data doesn't match with plain text");
1219 }
1220
1221 /* Go directly to the destroy_key label at this point */
1222 goto destroy_key;
1223
1224 abort:
1225 /* Abort the operation */
1226 status = bAbortDecryption ? psa_cipher_abort(&handle_dec) :
1227 psa_cipher_abort(&handle);
1228 if (status != PSA_SUCCESS) {
1229 TEST_FAIL("Error aborting the operation");
1230 }
1231 destroy_key:
1232 /* Destroy the key */
1233 status = psa_destroy_key(key_id_local);
1234 if (status != PSA_SUCCESS) {
1235 TEST_FAIL("Error destroying a key");
1236 }
1237 }
1238
psa_invalid_cipher_test(const psa_key_type_t key_type,const psa_algorithm_t alg,const size_t key_size,struct test_result_t * ret)1239 void psa_invalid_cipher_test(const psa_key_type_t key_type,
1240 const psa_algorithm_t alg,
1241 const size_t key_size,
1242 struct test_result_t *ret)
1243 {
1244 psa_status_t status;
1245 psa_cipher_operation_t handle = psa_cipher_operation_init();
1246 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
1247 uint8_t data[TEST_MAX_KEY_LENGTH];
1248 psa_key_attributes_t key_attributes = psa_key_attributes_init();
1249 psa_key_usage_t usage = (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
1250
1251 /* Setup the key policy */
1252 psa_set_key_usage_flags(&key_attributes, usage);
1253 psa_set_key_algorithm(&key_attributes, alg);
1254 psa_set_key_type(&key_attributes, key_type);
1255
1256 /* Fill the key data */
1257 (void)memset(data, 'A', key_size);
1258
1259 /* Import a key */
1260 status = psa_import_key(&key_attributes, data, key_size, &key_id_local);
1261 if (status != PSA_SUCCESS) {
1262 TEST_FAIL("Error importing a key");
1263 return;
1264 }
1265
1266 /* Setup the encryption object */
1267 status = psa_cipher_encrypt_setup(&handle, key_id_local, alg);
1268 if (status == PSA_SUCCESS) {
1269 TEST_FAIL("Should not successfully setup an invalid cipher");
1270 (void)psa_destroy_key(key_id_local);
1271 return;
1272 }
1273
1274 /* Destroy the key */
1275 status = psa_destroy_key(key_id_local);
1276 if (status != PSA_SUCCESS) {
1277 TEST_FAIL("Error destroying a key");
1278 return;
1279 }
1280
1281 ret->val = TEST_PASSED;
1282 }
1283
psa_unsupported_hash_test(const psa_algorithm_t alg,struct test_result_t * ret)1284 void psa_unsupported_hash_test(const psa_algorithm_t alg,
1285 struct test_result_t *ret)
1286 {
1287 psa_status_t status;
1288 psa_hash_operation_t handle = PSA_HASH_OPERATION_INIT;
1289
1290 /* Setup the hash object for the unsupported hash algorithm */
1291 status = psa_hash_setup(&handle, alg);
1292 if (status != PSA_ERROR_NOT_SUPPORTED) {
1293 TEST_FAIL("Should not successfully setup an unsupported hash alg");
1294 return;
1295 }
1296
1297 ret->val = TEST_PASSED;
1298 }
1299
1300 /*
1301 * \brief This is the list of algorithms supported by the current
1302 * configuration of the crypto engine used by the crypto
1303 * service. In case the crypto engine default capabilities
1304 * is changed, this list needs to be updated accordingly
1305 */
1306 static const psa_algorithm_t hash_alg[] = {
1307 PSA_ALG_SHA_224,
1308 PSA_ALG_SHA_256,
1309 PSA_ALG_SHA_384,
1310 PSA_ALG_SHA_512,
1311 };
1312
1313 static const uint8_t hash_val[][PSA_HASH_LENGTH(PSA_ALG_SHA_512)] = {
1314 {0x00, 0xD2, 0x90, 0xE2, 0x0E, 0x4E, 0xC1, 0x7E, /*!< SHA-224 */
1315 0x7A, 0x95, 0xF5, 0x10, 0x5C, 0x76, 0x74, 0x04,
1316 0x6E, 0xB5, 0x56, 0x5E, 0xE5, 0xE7, 0xBA, 0x15,
1317 0x6C, 0x23, 0x47, 0xF3},
1318 {0x6B, 0x22, 0x09, 0x2A, 0x37, 0x1E, 0xF5, 0x14, /*!< SHA-256 */
1319 0xF7, 0x39, 0x4D, 0xCF, 0xAD, 0x4D, 0x17, 0x46,
1320 0x66, 0xCB, 0x33, 0xA0, 0x39, 0xD8, 0x41, 0x4E,
1321 0xF1, 0x2A, 0xD3, 0x4D, 0x69, 0xC3, 0xB5, 0x3E},
1322 {0x64, 0x79, 0x11, 0xBB, 0x47, 0x4E, 0x47, 0x59, /*!< SHA-384 */
1323 0x3E, 0x4D, 0xBC, 0x60, 0xA5, 0xF9, 0xBF, 0x9C,
1324 0xC0, 0xBA, 0x55, 0x0F, 0x93, 0xCA, 0x72, 0xDF,
1325 0x57, 0x1E, 0x50, 0x56, 0xF9, 0x4A, 0x01, 0xD6,
1326 0xA5, 0x6F, 0xF7, 0x62, 0x34, 0x4F, 0x48, 0xFD,
1327 0x9D, 0x15, 0x07, 0x42, 0xB7, 0x72, 0x94, 0xB8},
1328 {0xB4, 0x1C, 0xA3, 0x6C, 0xA9, 0x67, 0x1D, 0xAD, /*!< SHA-512 */
1329 0x34, 0x1F, 0xBE, 0x1B, 0x83, 0xC4, 0x40, 0x2A,
1330 0x47, 0x42, 0x79, 0xBB, 0x21, 0xCA, 0xF0, 0x60,
1331 0xE4, 0xD2, 0x6E, 0x9B, 0x70, 0x12, 0x34, 0x3F,
1332 0x55, 0x2C, 0x09, 0x31, 0x0A, 0x5B, 0x40, 0x21,
1333 0x01, 0xA8, 0x3B, 0x58, 0xE7, 0x48, 0x13, 0x1A,
1334 0x7E, 0xCD, 0xE1, 0xD2, 0x46, 0x10, 0x58, 0x34,
1335 0x49, 0x14, 0x4B, 0xAA, 0x89, 0xA9, 0xF5, 0xB1},
1336 };
1337
psa_hash_test(const psa_algorithm_t alg,struct test_result_t * ret)1338 void psa_hash_test(const psa_algorithm_t alg,
1339 struct test_result_t *ret)
1340 {
1341 const char *msg =
1342 "This is my test message, please generate a hash for this.";
1343 /* Length of each chunk in the multipart API */
1344 const size_t msg_size[] = {25, 32};
1345 const uint32_t msg_num = sizeof(msg_size)/sizeof(msg_size[0]);
1346 uint32_t idx, start_idx = 0;
1347
1348 psa_status_t status;
1349 psa_hash_operation_t handle = psa_hash_operation_init();
1350
1351 /* Setup the hash object for the desired hash*/
1352 status = psa_hash_setup(&handle, alg);
1353
1354 if (status != PSA_SUCCESS) {
1355 if (status == PSA_ERROR_NOT_SUPPORTED) {
1356 TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
1357 return;
1358 }
1359
1360 TEST_FAIL("Error setting up hash operation object");
1361 return;
1362 }
1363
1364 /* Update object with all the chunks of message */
1365 for (idx=0; idx<msg_num; idx++) {
1366 status = psa_hash_update(&handle,
1367 (const uint8_t *)&msg[start_idx],
1368 msg_size[idx]);
1369 if (status != PSA_SUCCESS) {
1370 TEST_FAIL("Error updating the hash operation object");
1371 return;
1372 }
1373 start_idx += msg_size[idx];
1374 }
1375
1376 /* Cycle until idx points to the correct index in the algorithm table */
1377 for (idx=0; hash_alg[idx] != alg; idx++);
1378
1379 /* Finalise and verify that the hash is as expected */
1380 status = psa_hash_verify(&handle, hash_val[idx], PSA_HASH_LENGTH(alg));
1381 if (status != PSA_SUCCESS) {
1382 TEST_FAIL("Error verifying the hash operation object");
1383 return;
1384 }
1385
1386 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
1387 /* Do the same as above with the single shot APIs */
1388 status = psa_hash_compare(alg,
1389 (const uint8_t *)msg, strlen(msg),
1390 hash_val[idx], PSA_HASH_LENGTH(alg));
1391 if (status != PSA_SUCCESS) {
1392 TEST_FAIL("Error using the single shot API");
1393 return;
1394 }
1395 #endif
1396
1397 ret->val = TEST_PASSED;
1398 }
1399
psa_unsupported_mac_test(const psa_key_type_t key_type,const psa_algorithm_t alg,struct test_result_t * ret)1400 void psa_unsupported_mac_test(const psa_key_type_t key_type,
1401 const psa_algorithm_t alg,
1402 struct test_result_t *ret)
1403 {
1404 psa_status_t status;
1405 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
1406 psa_mac_operation_t handle = PSA_MAC_OPERATION_INIT;
1407 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
1408 const uint8_t data[] = "THIS IS MY KEY1";
1409
1410 ret->val = TEST_PASSED;
1411
1412 /* Setup the key policy */
1413 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH);
1414 psa_set_key_algorithm(&key_attributes, alg);
1415 psa_set_key_type(&key_attributes, key_type);
1416
1417 /* Import key */
1418 status = psa_import_key(&key_attributes, data, sizeof(data), &key_id_local);
1419 if (status != PSA_SUCCESS) {
1420 TEST_FAIL("Error importing a key");
1421 return;
1422 }
1423
1424 /* Setup the mac object for the unsupported mac algorithm */
1425 status = psa_mac_verify_setup(&handle, key_id_local, alg);
1426 if (status != PSA_ERROR_NOT_SUPPORTED) {
1427 TEST_FAIL("Should not successfully setup an unsupported MAC alg");
1428 /* Do not return, to ensure key is destroyed */
1429 }
1430
1431 /* Destroy the key */
1432 status = psa_destroy_key(key_id_local);
1433 if (status != PSA_SUCCESS) {
1434 TEST_FAIL("Error destroying the key");
1435 }
1436 }
1437
1438 static const uint8_t hmac_val[][PSA_HASH_LENGTH(PSA_ALG_SHA_512)] = {
1439 {0xc1, 0x9f, 0x19, 0xac, 0x05, 0x65, 0x5f, 0x02, /*!< SHA-224 */
1440 0x1b, 0x64, 0x32, 0xd9, 0xb1, 0x49, 0xba, 0x75,
1441 0x05, 0x60, 0x52, 0x4e, 0x78, 0xfa, 0x61, 0xc9,
1442 0x37, 0x5d, 0x7f, 0x58},
1443 {0x94, 0x37, 0xbe, 0xb5, 0x7f, 0x7c, 0x5c, 0xb0, /*!< SHA-256 */
1444 0x0a, 0x92, 0x4d, 0xd3, 0xba, 0x7e, 0xb1, 0x1a,
1445 0xdb, 0xa2, 0x25, 0xb2, 0x82, 0x8e, 0xdf, 0xbb,
1446 0x61, 0xbf, 0x91, 0x1d, 0x28, 0x23, 0x4a, 0x04},
1447 {0x94, 0x21, 0x9b, 0xc3, 0xd5, 0xed, 0xe6, 0xee, /*!< SHA-384 */
1448 0x42, 0x10, 0x5a, 0x58, 0xa4, 0x4d, 0x67, 0x87,
1449 0x16, 0xa2, 0xa7, 0x6c, 0x2e, 0xc5, 0x85, 0xb7,
1450 0x6a, 0x4c, 0x90, 0xb2, 0x73, 0xee, 0x58, 0x3c,
1451 0x59, 0x16, 0x67, 0xf3, 0x6f, 0x30, 0x99, 0x1c,
1452 0x2a, 0xf7, 0xb1, 0x5f, 0x45, 0x83, 0xf5, 0x9f},
1453 {0x8f, 0x76, 0xef, 0x12, 0x0b, 0x92, 0xc2, 0x06, /*!< SHA-512 */
1454 0xce, 0x01, 0x18, 0x75, 0x84, 0x96, 0xd9, 0x6f,
1455 0x23, 0x88, 0xd4, 0xf8, 0xcf, 0x79, 0xf8, 0xcf,
1456 0x27, 0x12, 0x9f, 0xa6, 0x7e, 0x87, 0x9a, 0x68,
1457 0xee, 0xe2, 0xe7, 0x1d, 0x4b, 0xf2, 0x87, 0xc0,
1458 0x05, 0x6a, 0xbd, 0x7f, 0x9d, 0xff, 0xaa, 0xf3,
1459 0x9a, 0x1c, 0xb7, 0xb7, 0xbd, 0x03, 0x61, 0xa3,
1460 0xa9, 0x6a, 0x5d, 0xb2, 0x81, 0xe1, 0x6f, 0x1f},
1461 };
1462
1463 static const uint8_t long_key_hmac_val[PSA_HASH_LENGTH(PSA_ALG_SHA_224)] = {
1464 0x47, 0xa3, 0x42, 0xb1, 0x2f, 0x52, 0xd3, 0x8f, /*!< SHA-224 */
1465 0x1e, 0x02, 0x4a, 0x46, 0x73, 0x0b, 0x77, 0xc1,
1466 0x5e, 0x93, 0x31, 0xa9, 0x3e, 0xc2, 0x81, 0xb5,
1467 0x3d, 0x07, 0x6f, 0x31
1468 };
1469
psa_mac_test(const psa_algorithm_t alg,const uint8_t * key,size_t key_bits,struct test_result_t * ret)1470 void psa_mac_test(const psa_algorithm_t alg,
1471 const uint8_t *key,
1472 size_t key_bits,
1473 struct test_result_t *ret)
1474 {
1475 const char *msg =
1476 "This is my test message, please generate a hmac for this.";
1477 /* Length of each chunk in the multipart API */
1478 const size_t msg_size[] = {25, 32};
1479 const uint32_t msg_num = sizeof(msg_size)/sizeof(msg_size[0]);
1480 uint32_t idx, start_idx = 0;
1481 uint8_t *hmac_res;
1482
1483 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
1484 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
1485 psa_status_t status;
1486 psa_mac_operation_t handle = psa_mac_operation_init();
1487 psa_key_attributes_t key_attributes = psa_key_attributes_init();
1488 psa_key_attributes_t retrieved_attributes = psa_key_attributes_init();
1489 psa_key_usage_t usage = PSA_KEY_USAGE_VERIFY_HASH;
1490
1491 ret->val = TEST_PASSED;
1492
1493 /* Setup the key policy */
1494 psa_set_key_usage_flags(&key_attributes, usage);
1495 psa_set_key_algorithm(&key_attributes, alg);
1496 psa_set_key_type(&key_attributes, key_type);
1497
1498 /* Import key */
1499 status = psa_import_key(&key_attributes, key, PSA_BITS_TO_BYTES(key_bits),
1500 &key_id_local);
1501
1502 if (status != PSA_SUCCESS) {
1503 TEST_FAIL("Error importing a key");
1504 return;
1505 }
1506
1507 status = psa_get_key_attributes(key_id_local, &retrieved_attributes);
1508 if (status != PSA_SUCCESS) {
1509 TEST_FAIL("Error getting key metadata");
1510 goto destroy_key_mac;
1511 }
1512
1513 if (psa_get_key_bits(&retrieved_attributes) != key_bits) {
1514 TEST_FAIL("The number of key bits is different from expected");
1515 goto destroy_key_mac;
1516 }
1517
1518 if (psa_get_key_type(&retrieved_attributes) != key_type) {
1519 TEST_FAIL("The type of the key is different from expected");
1520 goto destroy_key_mac;
1521 }
1522
1523 psa_reset_key_attributes(&retrieved_attributes);
1524
1525 /* Setup the mac object for hmac */
1526 status = psa_mac_verify_setup(&handle, key_id_local, alg);
1527 if (status != PSA_SUCCESS) {
1528 TEST_FAIL("Error setting up mac operation object");
1529 goto destroy_key_mac;
1530 }
1531
1532 /* Update object with all the chunks of message */
1533 for (idx=0; idx<msg_num; idx++) {
1534 status = psa_mac_update(&handle,
1535 (const uint8_t *)&msg[start_idx],
1536 msg_size[idx]);
1537 if (status != PSA_SUCCESS) {
1538 TEST_FAIL("Error during mac operation");
1539 goto destroy_key_mac;
1540 }
1541 start_idx += msg_size[idx];
1542 }
1543
1544 /* Cycle until idx points to the correct index in the algorithm table */
1545 for (idx=0; hash_alg[idx] != PSA_ALG_HMAC_GET_HASH(alg); idx++);
1546
1547 if (key_bits == BIT_SIZE_TEST_LONG_KEY) {
1548 hmac_res = (uint8_t *)long_key_hmac_val;
1549 } else {
1550 hmac_res = (uint8_t *)hmac_val[idx];
1551 }
1552
1553 /* Finalise and verify the mac value */
1554 status = psa_mac_verify_finish(&handle, hmac_res,
1555 PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)));
1556 if (status != PSA_SUCCESS) {
1557 TEST_FAIL("Error during finalising the mac operation");
1558 goto destroy_key_mac;
1559 }
1560
1561 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
1562 /* Do the same as above with the single shot APIs */
1563 status = psa_mac_verify(key_id_local, alg,
1564 (const uint8_t *)msg, strlen(msg),
1565 hmac_res,
1566 PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)));
1567 if (status != PSA_SUCCESS) {
1568 TEST_FAIL("Error using the single shot API");
1569 }
1570 #endif
1571
1572 destroy_key_mac:
1573 /* Destroy the key */
1574 status = psa_destroy_key(key_id_local);
1575 if (status != PSA_SUCCESS) {
1576 TEST_FAIL("Error destroying the key");
1577 }
1578 }
1579
psa_aead_test(const psa_key_type_t key_type,const psa_algorithm_t alg,const uint8_t * key,size_t key_bits,struct test_result_t * ret)1580 void psa_aead_test(const psa_key_type_t key_type,
1581 const psa_algorithm_t alg,
1582 const uint8_t *key,
1583 size_t key_bits,
1584 struct test_result_t *ret)
1585 {
1586 psa_aead_operation_t encop = psa_aead_operation_init();
1587 psa_aead_operation_t decop = psa_aead_operation_init();
1588 psa_status_t status = PSA_SUCCESS;
1589 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
1590 const size_t nonce_length = 12;
1591 const uint8_t nonce[] = "01234567890";
1592 const uint8_t plain_text[MAX_PLAIN_DATA_SIZE_AEAD] =
1593 "This is my plaintext message and it's made of 68 characters...!1234";
1594 const uint8_t associated_data[] =
1595 "This is my associated data to authenticate";
1596 uint8_t decrypted_data[MAX_PLAIN_DATA_SIZE_AEAD] = {0};
1597 uint8_t encrypted_data[ENC_DEC_BUFFER_SIZE_AEAD] = {0};
1598 size_t encrypted_data_length = 0, decrypted_data_length = 0;
1599 size_t total_output_length = 0, total_encrypted_length = 0;
1600 uint32_t comp_result;
1601 psa_key_attributes_t key_attributes = psa_key_attributes_init();
1602 psa_key_attributes_t retrieved_attributes = psa_key_attributes_init();
1603 psa_key_usage_t usage = (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
1604 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
1605 uint8_t encrypted_data_single_shot[ENC_DEC_BUFFER_SIZE_AEAD] = {0};
1606 #endif
1607
1608 /* Variables required for multipart operations */
1609 uint8_t *tag = &encrypted_data[MAX_PLAIN_DATA_SIZE_AEAD];
1610 size_t tag_size = PSA_AEAD_TAG_LENGTH(key_type,
1611 psa_get_key_bits(&key_attributes),
1612 alg);
1613 size_t tag_length = 0;
1614
1615 ret->val = TEST_PASSED;
1616
1617 /* Setup the key policy */
1618 psa_set_key_usage_flags(&key_attributes, usage);
1619 psa_set_key_algorithm(&key_attributes, alg);
1620 psa_set_key_type(&key_attributes, key_type);
1621
1622 /* Import a key */
1623 status = psa_import_key(&key_attributes, key, PSA_BITS_TO_BYTES(key_bits),
1624 &key_id_local);
1625
1626 if (status != PSA_SUCCESS) {
1627 TEST_FAIL("Error importing a key");
1628 return;
1629 }
1630
1631 status = psa_get_key_attributes(key_id_local, &retrieved_attributes);
1632 if (status != PSA_SUCCESS) {
1633 TEST_FAIL("Error getting key metadata");
1634 goto destroy_key_aead;
1635 }
1636
1637 if (psa_get_key_bits(&retrieved_attributes) != key_bits) {
1638 TEST_FAIL("The number of key bits is different from expected");
1639 goto destroy_key_aead;
1640 }
1641
1642 if (psa_get_key_type(&retrieved_attributes) != key_type) {
1643 TEST_FAIL("The type of the key is different from expected");
1644 goto destroy_key_aead;
1645 }
1646
1647 psa_reset_key_attributes(&retrieved_attributes);
1648
1649 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
1650 /* Perform AEAD encryption */
1651 status = psa_aead_encrypt(key_id_local, alg, nonce, nonce_length,
1652 associated_data,
1653 sizeof(associated_data),
1654 plain_text,
1655 sizeof(plain_text),
1656 encrypted_data,
1657 sizeof(encrypted_data),
1658 &encrypted_data_length);
1659
1660 if (status != PSA_SUCCESS) {
1661 if (status == PSA_ERROR_NOT_SUPPORTED) {
1662 TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
1663 goto destroy_key_aead;
1664 }
1665
1666 TEST_FAIL("Error performing AEAD encryption");
1667 goto destroy_key_aead;
1668 }
1669
1670 if (encrypted_data_length
1671 != PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, sizeof(plain_text))) {
1672 TEST_FAIL("Encrypted data length is different than expected");
1673 goto destroy_key_aead;
1674 }
1675
1676 /* Store a copy of the encrypted data for later checking it against
1677 * multipart results
1678 */
1679 if (encrypted_data_length > ENC_DEC_BUFFER_SIZE_AEAD) {
1680 TEST_FAIL("Encrypted data length is above the maximum expected value");
1681 goto destroy_key_aead;
1682 }
1683 memcpy(encrypted_data_single_shot, encrypted_data, encrypted_data_length);
1684
1685 /* Perform AEAD decryption */
1686 status = psa_aead_decrypt(key_id_local, alg, nonce, nonce_length,
1687 associated_data,
1688 sizeof(associated_data),
1689 encrypted_data,
1690 encrypted_data_length,
1691 decrypted_data,
1692 sizeof(decrypted_data),
1693 &decrypted_data_length);
1694
1695 if (status != PSA_SUCCESS) {
1696 if (status == PSA_ERROR_NOT_SUPPORTED) {
1697 TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
1698 } else {
1699 TEST_FAIL("Error performing AEAD decryption");
1700 }
1701
1702 goto destroy_key_aead;
1703 }
1704
1705 if (sizeof(plain_text) != decrypted_data_length) {
1706 TEST_FAIL("Decrypted data length is different from plain text");
1707 goto destroy_key_aead;
1708 }
1709
1710 /* Check that the decrypted data is the same as the original data */
1711 comp_result = memcmp(plain_text, decrypted_data, sizeof(plain_text));
1712 if (comp_result != 0) {
1713 TEST_FAIL("Decrypted data doesn't match with plain text");
1714 goto destroy_key_aead;
1715 }
1716 #endif /* TFM_CRYPTO_TEST_SINGLE_PART_FUNCS */
1717
1718 /* Setup the encryption object */
1719 status = psa_aead_encrypt_setup(&encop, key_id_local, alg);
1720 if (status != PSA_SUCCESS) {
1721 /* Implementations using the PSA Crypto Driver APIs, that don't
1722 * support multipart API flows, will return PSA_ERROR_NOT_SUPPORTED
1723 * when calling psa_aead_encrypt_setup(). In this case, it's fine
1724 * just to skip the multipart APIs test flow from this point on
1725 */
1726 if (status == PSA_ERROR_NOT_SUPPORTED) {
1727 TEST_LOG("psa_aead_encrypt_setup(): Algorithm NOT SUPPORTED by"\
1728 " the implementation - skip multipart API flow\r\n");
1729 } else {
1730 TEST_FAIL("Error setting up encryption object");
1731 }
1732 goto destroy_key_aead;
1733 }
1734
1735 /* Set lengths */
1736 status = psa_aead_set_lengths(&encop,
1737 sizeof(associated_data),
1738 sizeof(plain_text));
1739 if (status != PSA_SUCCESS) {
1740 /* Implementations using the mbed TLS _ALT APIs, that don't support
1741 * multipart API flows in CCM mode, will return PSA_ERROR_NOT_SUPPORTED
1742 * when calling psa_aead_set_lengths(). In this case, it's fine just
1743 * to skip the multipart APIs test flow from this point on
1744 */
1745 if (PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CCM
1746 && status == PSA_ERROR_NOT_SUPPORTED) {
1747 TEST_LOG("psa_aead_set_lengths(): Algorithm NOT SUPPORTED by the "\
1748 "implementation - skip multipart API flow\r\n");
1749 } else {
1750 TEST_FAIL("Error setting lengths");
1751 }
1752 status = psa_aead_abort(&encop);
1753 if (status != PSA_SUCCESS) {
1754 TEST_FAIL("Error aborting the operation");
1755 }
1756 goto destroy_key_aead;
1757 }
1758
1759 /* Set nonce */
1760 status = psa_aead_set_nonce(&encop, nonce, nonce_length);
1761 if (status != PSA_SUCCESS) {
1762 /* Implementations using the mbed TLS _ALT APIs, that don't support
1763 * multipart API flows in GCM, will return PSA_ERROR_NOT_SUPPORTED when
1764 * calling psa_aead_set_nonce(). In this case, it's fine just to skip
1765 * the multipart APIs test flow from this point on
1766 */
1767 if (PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_GCM
1768 && status == PSA_ERROR_NOT_SUPPORTED) {
1769 TEST_LOG("psa_aead_set_nonce(): Algorithm NOT SUPPORTED by the "\
1770 "implementation - skip multipart API flow\r\n");
1771 } else {
1772 TEST_FAIL("Error setting nonce");
1773 }
1774 status = psa_aead_abort(&encop);
1775 if (status != PSA_SUCCESS) {
1776 TEST_FAIL("Error aborting the operation");
1777 }
1778 goto destroy_key_aead;
1779 }
1780
1781 /* Update additional data */
1782 status = psa_aead_update_ad(&encop,
1783 associated_data,
1784 sizeof(associated_data));
1785 if (status != PSA_SUCCESS) {
1786 TEST_FAIL("Error updating additional data");
1787 status = psa_aead_abort(&encop);
1788 if (status != PSA_SUCCESS) {
1789 TEST_FAIL("Error aborting the operation");
1790 }
1791 goto destroy_key_aead;
1792 }
1793
1794 /* Encrypt one chunk of information at a time */
1795 for (size_t i = 0; i <= sizeof(plain_text)/BYTE_SIZE_CHUNK; i++) {
1796
1797 size_t size_to_encrypt =
1798 (sizeof(plain_text) - i*BYTE_SIZE_CHUNK) > BYTE_SIZE_CHUNK ?
1799 BYTE_SIZE_CHUNK : (sizeof(plain_text) - i*BYTE_SIZE_CHUNK);
1800
1801 status = psa_aead_update(&encop,
1802 plain_text + i*BYTE_SIZE_CHUNK,
1803 size_to_encrypt,
1804 encrypted_data + total_encrypted_length,
1805 sizeof(encrypted_data) -
1806 total_encrypted_length,
1807 &encrypted_data_length);
1808
1809 if (status != PSA_SUCCESS) {
1810 TEST_FAIL("Error encrypting one chunk of information");
1811 status = psa_aead_abort(&encop);
1812 if (status != PSA_SUCCESS) {
1813 TEST_FAIL("Error aborting the operation");
1814 }
1815 goto destroy_key_aead;
1816 }
1817 total_encrypted_length += encrypted_data_length;
1818 }
1819
1820 /* Finish the aead operation */
1821 status = psa_aead_finish(&encop,
1822 encrypted_data + total_encrypted_length,
1823 sizeof(encrypted_data) - total_encrypted_length,
1824 &encrypted_data_length,
1825 tag,
1826 tag_size,
1827 &tag_length);
1828 if (status != PSA_SUCCESS) {
1829 TEST_FAIL("Error finalising the AEAD operation");
1830 status = psa_aead_abort(&encop);
1831 if (status != PSA_SUCCESS) {
1832 TEST_FAIL("Error aborting the operation");
1833 }
1834 goto destroy_key_aead;
1835 }
1836 total_encrypted_length += encrypted_data_length;
1837
1838 #ifdef TFM_CRYPTO_TEST_SINGLE_PART_FUNCS
1839 /* Compare tag between single part and multipart case */
1840 comp_result = memcmp(
1841 &encrypted_data_single_shot[total_encrypted_length],
1842 tag, tag_length);
1843 if (comp_result != 0) {
1844 TEST_FAIL("Single shot tag does not match with multipart");
1845 goto destroy_key_aead;
1846 }
1847
1848 /* Compare encrypted data between single part and multipart case */
1849 comp_result = memcmp(
1850 encrypted_data_single_shot,
1851 encrypted_data, total_encrypted_length);
1852 if (comp_result != 0) {
1853 TEST_FAIL("Single shot encrypted data does not match with multipart");
1854 goto destroy_key_aead;
1855 }
1856 #endif /* TFM_CRYPTO_TEST_SINGLE_PART_FUNCS */
1857
1858 /* Setup up the decryption object */
1859 status = psa_aead_decrypt_setup(&decop, key_id_local, alg);
1860 if (status != PSA_SUCCESS) {
1861 TEST_FAIL("Error setting uup AEAD object");
1862 goto destroy_key_aead;
1863 }
1864
1865 /* Set lengths */
1866 status = psa_aead_set_lengths(&decop,
1867 sizeof(associated_data),
1868 sizeof(plain_text));
1869 if (status != PSA_SUCCESS) {
1870 TEST_FAIL("Error setting lengths");
1871 status = psa_aead_abort(&decop);
1872 if (status != PSA_SUCCESS) {
1873 TEST_FAIL("Error aborting the operation");
1874 }
1875 goto destroy_key_aead;
1876 }
1877
1878 /* Set nonce */
1879 status = psa_aead_set_nonce(&decop, nonce, nonce_length);
1880 if (status != PSA_SUCCESS) {
1881 TEST_FAIL("Error setting nonce");
1882 status = psa_aead_abort(&decop);
1883 if (status != PSA_SUCCESS) {
1884 TEST_FAIL("Error aborting the operation");
1885 }
1886 goto destroy_key_aead;
1887 }
1888
1889 /* Update additional data */
1890 status = psa_aead_update_ad(&decop,
1891 associated_data,
1892 sizeof(associated_data));
1893 if (status != PSA_SUCCESS) {
1894 TEST_FAIL("Error updating additional data");
1895 status = psa_aead_abort(&decop);
1896 if (status != PSA_SUCCESS) {
1897 TEST_FAIL("Error aborting the operation");
1898 }
1899 goto destroy_key_aead;
1900 }
1901
1902 /* Decrypt */
1903 for (size_t i = 0; i <= total_encrypted_length/BYTE_SIZE_CHUNK; i++) {
1904
1905 size_t size_to_decrypt =
1906 (total_encrypted_length - i*BYTE_SIZE_CHUNK) > BYTE_SIZE_CHUNK ?
1907 BYTE_SIZE_CHUNK : (total_encrypted_length - i*BYTE_SIZE_CHUNK);
1908
1909 status = psa_aead_update(&decop,
1910 encrypted_data + i*BYTE_SIZE_CHUNK,
1911 size_to_decrypt,
1912 decrypted_data + total_output_length,
1913 sizeof(decrypted_data)
1914 - total_output_length,
1915 &decrypted_data_length);
1916
1917 if (status != PSA_SUCCESS) {
1918 TEST_FAIL("Error during decryption");
1919 status = psa_aead_abort(&decop);
1920 if (status != PSA_SUCCESS) {
1921 TEST_FAIL("Error aborting the operation");
1922 }
1923 goto destroy_key_aead;
1924 }
1925 total_output_length += decrypted_data_length;
1926 }
1927
1928 /* Verify the AEAD operation */
1929 status = psa_aead_verify(&decop,
1930 decrypted_data + total_output_length,
1931 sizeof(decrypted_data) - total_output_length,
1932 &decrypted_data_length,
1933 tag,
1934 tag_size);
1935 if (status != PSA_SUCCESS) {
1936 TEST_FAIL("Error verifying the AEAD operation");
1937 status = psa_aead_abort(&decop);
1938 if (status != PSA_SUCCESS) {
1939 TEST_FAIL("Error aborting the operation");
1940 }
1941 goto destroy_key_aead;
1942 }
1943 total_output_length += decrypted_data_length;
1944
1945 if (total_output_length != sizeof(plain_text)) {
1946 TEST_FAIL("Total decrypted length does not match size of plain text");
1947 status = psa_aead_abort(&decop);
1948 if (status != PSA_SUCCESS) {
1949 TEST_FAIL("Error aborting the operation");
1950 }
1951 goto destroy_key_aead;
1952 }
1953
1954 /* Check that the decrypted data is the same as the original data */
1955 comp_result = memcmp(plain_text, decrypted_data, sizeof(plain_text));
1956 if (comp_result != 0) {
1957 TEST_FAIL("Decrypted data doesn't match with plain text");
1958 }
1959
1960 destroy_key_aead:
1961 /* Destroy the key */
1962 status = psa_destroy_key(key_id_local);
1963 if (status != PSA_SUCCESS) {
1964 TEST_FAIL("Error destroying a key");
1965 }
1966 }
1967
1968 /*
1969 * The list of available AES cipher/AEAD mode for test.
1970 * Not all the modes can be available in some use cases and configurations.
1971 */
1972 static const psa_algorithm_t test_aes_mode_array[] = {
1973 #ifdef TFM_CRYPTO_TEST_ALG_CBC
1974 PSA_ALG_CBC_NO_PADDING,
1975 #endif
1976 #ifdef TFM_CRYPTO_TEST_ALG_CCM
1977 PSA_ALG_CCM,
1978 #endif
1979 #ifdef TFM_CRYPTO_TEST_ALG_CFB
1980 PSA_ALG_CFB,
1981 #endif
1982 #ifdef TFM_CRYPTO_TEST_ALG_ECB
1983 PSA_ALG_ECB_NO_PADDING,
1984 #endif
1985 #ifdef TFM_CRYPTO_TEST_ALG_CTR
1986 PSA_ALG_CTR,
1987 #endif
1988 #ifdef TFM_CRYPTO_TEST_ALG_OFB
1989 PSA_ALG_OFB,
1990 #endif
1991 #ifdef TFM_CRYPTO_TEST_ALG_GCM
1992 PSA_ALG_GCM,
1993 #endif
1994 /* In case no AES algorithm is available */
1995 PSA_ALG_VENDOR_FLAG,
1996 };
1997
1998 /* Number of available AES cipher modes */
1999 #define NR_TEST_AES_MODE (sizeof(test_aes_mode_array) / \
2000 sizeof(test_aes_mode_array[0]) - 1)
2001
psa_invalid_key_length_test(struct test_result_t * ret)2002 void psa_invalid_key_length_test(struct test_result_t *ret)
2003 {
2004 psa_status_t status;
2005 psa_key_attributes_t key_attributes = psa_key_attributes_init();
2006 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
2007 const uint8_t data[19] = {0};
2008
2009 if (NR_TEST_AES_MODE < 1) {
2010 TEST_FAIL("A cipher mode in AES is required in current test case");
2011 return;
2012 }
2013
2014 /* Setup the key policy */
2015 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT);
2016 psa_set_key_algorithm(&key_attributes, test_aes_mode_array[0]);
2017 psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
2018
2019 /* AES does not support 152-bit keys */
2020 status = psa_import_key(&key_attributes, data, sizeof(data), &key_id_local);
2021 if (status != PSA_ERROR_INVALID_ARGUMENT) {
2022 TEST_FAIL("Should not successfully import with an invalid key length");
2023 return;
2024 }
2025
2026 ret->val = TEST_PASSED;
2027 }
2028
psa_policy_key_interface_test(struct test_result_t * ret)2029 void psa_policy_key_interface_test(struct test_result_t *ret)
2030 {
2031 psa_algorithm_t alg = test_aes_mode_array[0];
2032 psa_algorithm_t alg_out;
2033 psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_VOLATILE;
2034 psa_key_lifetime_t lifetime_out;
2035 psa_key_attributes_t key_attributes = psa_key_attributes_init();
2036 psa_key_usage_t usage = PSA_KEY_USAGE_EXPORT;
2037 psa_key_usage_t usage_out;
2038
2039 if (NR_TEST_AES_MODE < 1) {
2040 TEST_FAIL("A cipher mode in AES is required in current test case");
2041 return;
2042 }
2043
2044 /* Verify that initialised policy forbids all usage */
2045 usage_out = psa_get_key_usage_flags(&key_attributes);
2046 if (usage_out != 0) {
2047 TEST_FAIL("Unexpected usage value");
2048 return;
2049 }
2050
2051 alg_out = psa_get_key_algorithm(&key_attributes);
2052 if (alg_out != 0) {
2053 TEST_FAIL("Unexpected algorithm value");
2054 return;
2055 }
2056
2057 /* Set the key policy values */
2058 psa_set_key_usage_flags(&key_attributes, usage);
2059 psa_set_key_algorithm(&key_attributes, alg);
2060
2061 /* Check that the key policy has the correct usage */
2062 usage_out = psa_get_key_usage_flags(&key_attributes);
2063 if (usage_out != usage) {
2064 TEST_FAIL("Unexpected usage value");
2065 return;
2066 }
2067
2068 /* Check that the key policy has the correct algorithm */
2069 alg_out = psa_get_key_algorithm(&key_attributes);
2070 if (alg_out != alg) {
2071 TEST_FAIL("Unexpected algorithm value");
2072 return;
2073 }
2074
2075 /* Check the key has the correct key lifetime */
2076 lifetime_out = psa_get_key_lifetime(&key_attributes);
2077
2078 if (lifetime_out != lifetime) {
2079 TEST_FAIL("Unexpected key lifetime value");
2080 return;
2081 }
2082
2083 ret->val = TEST_PASSED;
2084 }
2085
psa_policy_invalid_policy_usage_test(struct test_result_t * ret)2086 void psa_policy_invalid_policy_usage_test(struct test_result_t *ret)
2087 {
2088 psa_status_t status;
2089 psa_algorithm_t alg, not_permit_alg;
2090 psa_cipher_operation_t handle = psa_cipher_operation_init();
2091 psa_key_attributes_t key_attributes = psa_key_attributes_init();
2092 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
2093 psa_key_usage_t usage = (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
2094 size_t data_len;
2095 const uint8_t data[] = "THIS IS MY KEY1";
2096 uint8_t data_out[sizeof(data)];
2097 uint8_t i, j;
2098
2099 ret->val = TEST_PASSED;
2100
2101 if (NR_TEST_AES_MODE < 2) {
2102 TEST_LOG("Two cipher modes are required. Skip this test case\r\n");
2103 return;
2104 }
2105
2106 /*
2107 * Search for two modes for test. Both modes should be Cipher algorithms.
2108 * Otherwise, cipher setup may fail before policy permission check.
2109 */
2110 for (i = 0; i < NR_TEST_AES_MODE - 1; i++) {
2111 if (PSA_ALG_IS_CIPHER(test_aes_mode_array[i])) {
2112 alg = test_aes_mode_array[i];
2113 break;
2114 }
2115 }
2116
2117 for (j = i + 1; j < NR_TEST_AES_MODE; j++) {
2118 if (PSA_ALG_IS_CIPHER(test_aes_mode_array[j])) {
2119 not_permit_alg = test_aes_mode_array[j];
2120 break;
2121 }
2122 }
2123
2124 if (j == NR_TEST_AES_MODE) {
2125 TEST_LOG("Unable to find two Cipher algs. Skip this test case.\r\n");
2126 return;
2127 }
2128
2129 /* Setup the key policy */
2130 psa_set_key_usage_flags(&key_attributes, usage);
2131 psa_set_key_algorithm(&key_attributes, alg);
2132 psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
2133
2134 /* Import the key after having set the policy */
2135 status = psa_import_key(&key_attributes, data, sizeof(data), &key_id_local);
2136 if (status != PSA_SUCCESS) {
2137 TEST_FAIL("Failed to import a key");
2138 return;
2139 }
2140
2141 /* Setup a cipher permitted by the key policy */
2142 status = psa_cipher_encrypt_setup(&handle, key_id_local, alg);
2143 if (status != PSA_SUCCESS) {
2144 TEST_FAIL("Failed to setup cipher operation");
2145 goto destroy_key;
2146 }
2147
2148 status = psa_cipher_abort(&handle);
2149 if (status != PSA_SUCCESS) {
2150 TEST_FAIL("Failed to abort cipher operation");
2151 goto destroy_key;
2152 }
2153
2154 /* Attempt to setup a cipher with an alg not permitted by the policy */
2155 status = psa_cipher_encrypt_setup(&handle, key_id_local, not_permit_alg);
2156 if (status != PSA_ERROR_NOT_PERMITTED) {
2157 TEST_FAIL("Was able to setup cipher operation with wrong alg");
2158 goto destroy_key;
2159 }
2160
2161 /* Attempt to export the key, which is forbidden by the key policy */
2162 status = psa_export_key(key_id_local, data_out,
2163 sizeof(data_out), &data_len);
2164 if (status != PSA_ERROR_NOT_PERMITTED) {
2165 TEST_FAIL("Should not be able to export key without correct usage");
2166 goto destroy_key;
2167 }
2168
2169 destroy_key:
2170 status = psa_destroy_key(key_id_local);
2171 if (status != PSA_SUCCESS) {
2172 TEST_FAIL("Failed to destroy key");
2173 }
2174 }
2175
psa_persistent_key_test(psa_key_id_t key_id,struct test_result_t * ret)2176 void psa_persistent_key_test(psa_key_id_t key_id, struct test_result_t *ret)
2177 {
2178 psa_status_t status;
2179 int comp_result;
2180 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
2181 psa_algorithm_t alg = test_aes_mode_array[0];
2182 psa_key_usage_t usage = PSA_KEY_USAGE_EXPORT;
2183 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
2184 size_t data_len;
2185 const uint8_t data[] = "THIS IS MY KEY1";
2186 uint8_t data_out[sizeof(data)] = {0};
2187
2188 if (NR_TEST_AES_MODE < 1) {
2189 TEST_FAIL("A cipher mode in AES is required in current test case");
2190 return;
2191 }
2192
2193 /* Setup the key attributes with a key ID to create a persistent key */
2194 psa_set_key_id(&key_attributes, key_id);
2195 psa_set_key_usage_flags(&key_attributes, usage);
2196 psa_set_key_algorithm(&key_attributes, alg);
2197 psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
2198
2199 /* Import key data to create the persistent key */
2200 status = psa_import_key(&key_attributes, data, sizeof(data), &key_id_local);
2201 #ifdef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
2202 if (status != PSA_SUCCESS) {
2203 TEST_FAIL("Failed to import a key");
2204 return;
2205 }
2206 #else
2207 if (status != PSA_ERROR_NOT_SUPPORTED) {
2208 TEST_FAIL("When ITS partition is not enabled, \
2209 import should return NOT_SUPPORTED");
2210 return;
2211 }
2212 TEST_LOG("psa_import_key(): ITS partition is not enabled - skip\r\n");
2213 ret->val = TEST_PASSED;
2214 return;
2215 #endif /* TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
2216
2217 if (key_id_local != key_id) {
2218 TEST_FAIL("After importing key_id_local and key_id must match");
2219 return;
2220 }
2221
2222 /* Close the persistent key through the key ID */
2223 status = psa_close_key(key_id_local);
2224 if (status != PSA_SUCCESS) {
2225 TEST_FAIL("Failed to close a persistent key");
2226 return;
2227 }
2228
2229 /* Open the previsously-created persistent key */
2230 status = psa_open_key(key_id, &key_id_local);
2231 if (status != PSA_SUCCESS) {
2232 TEST_FAIL("Failed to open a persistent key");
2233 return;
2234 }
2235
2236 /* Export the persistent key */
2237 status = psa_export_key(key_id_local, data_out,
2238 sizeof(data_out), &data_len);
2239 if (status != PSA_SUCCESS) {
2240 TEST_FAIL("Failed to export a persistent key");
2241 return;
2242 }
2243
2244 if (data_len != sizeof(data)) {
2245 TEST_FAIL("Number of bytes of exported key different from expected");
2246 return;
2247 }
2248
2249 /* Check that the exported key is the same as the imported one */
2250 comp_result = memcmp(data_out, data, sizeof(data));
2251 if (comp_result != 0) {
2252 TEST_FAIL("Exported key does not match the imported key");
2253 return;
2254 }
2255
2256 /* Destroy the persistent key */
2257 status = psa_destroy_key(key_id_local);
2258 if (status != PSA_SUCCESS) {
2259 TEST_FAIL("Failed to destroy a persistent key");
2260 return;
2261 }
2262
2263 ret->val = TEST_PASSED;
2264 }
2265
2266 #define KEY_DERIV_OUTPUT_LEN 32
2267 #define KEY_DERIV_SECRET_LEN 16
2268 #define KEY_DERIV_PEER_LEN 16
2269 #define KEY_DERIV_LABEL_INFO_LEN 8
2270 #define KEY_DERIV_SEED_SALT_LEN 8
2271 #define KEY_DERIV_RAW_MAX_PEER_LEN 100
2272 #define KEY_DERIV_RAW_OUTPUT_LEN 48
2273
2274 /* Pair of ECC test keys that are generated using openssl with the following
2275 * parameters:
2276 *
2277 * openssl ecparam -outform der -out test_prime256v1 -name prime256v1 -genkey
2278 *
2279 */
2280 /* An example of a 32 bytes / 256 bits ECDSA private key */
2281 static const uint8_t ecdsa_private_key[] = {
2282 0xED, 0x8F, 0xAA, 0x23, 0xE2, 0x8B, 0x1F, 0x51,
2283 0x63, 0x4F, 0x8E, 0xC9, 0xDC, 0x24, 0x92, 0x0F,
2284 0x3D, 0xA1, 0x7B, 0x47, 0x68, 0x38, 0xE3, 0x0D,
2285 0x10, 0x4A, 0x6D, 0xA7, 0x2D, 0x48, 0xA4, 0x18
2286 };
2287 /* Corresponding public key in uncompressed form, i.e. 0x04 X Y */
2288 static const uint8_t ecdsa_public_key[] = {
2289 0x04, 0x41, 0xC6, 0xFC, 0xC5, 0xA4, 0xBB, 0x70,
2290 0x45, 0xA7, 0xB2, 0x5E, 0x50, 0xB3, 0x2E, 0xD0,
2291 0x2A, 0x8D, 0xA8, 0x8E, 0x1B, 0x34, 0xC2, 0x71,
2292 0x57, 0x38, 0x5C, 0x45, 0xAB, 0xF2, 0x51, 0x7B,
2293 0x17, 0x5A, 0xC5, 0x05, 0xA9, 0x9E, 0x4B, 0x7D,
2294 0xDD, 0xD7, 0xBF, 0xBB, 0x45, 0x51, 0x92, 0x7D,
2295 0x33, 0x33, 0x8B, 0x1B, 0x70, 0x5A, 0xFD, 0x2B,
2296 0xF2, 0x7A, 0xA4, 0xBD, 0x37, 0x50, 0xED, 0x34,
2297 0x9F
2298 };
2299
2300 /* Buffer to hold the peer key of the key agreement process */
2301 static uint8_t raw_agreement_peer_key[KEY_DERIV_RAW_MAX_PEER_LEN] = {0};
2302
2303 static uint8_t key_deriv_secret[KEY_DERIV_SECRET_LEN];
2304 static uint8_t key_deriv_label_info[KEY_DERIV_LABEL_INFO_LEN];
2305 static uint8_t key_deriv_seed_salt[KEY_DERIV_SEED_SALT_LEN];
2306
psa_key_agreement_test(psa_algorithm_t deriv_alg,struct test_result_t * ret)2307 void psa_key_agreement_test(psa_algorithm_t deriv_alg,
2308 struct test_result_t *ret)
2309 {
2310 psa_status_t status;
2311 psa_key_type_t key_type;
2312 psa_key_id_t input_key_id_local = PSA_KEY_ID_NULL;
2313 psa_key_attributes_t input_key_attr = PSA_KEY_ATTRIBUTES_INIT;
2314 uint8_t raw_agreement_output_buffer[KEY_DERIV_RAW_OUTPUT_LEN] = {0};
2315 size_t raw_agreement_output_size = 0;
2316 size_t public_key_length = 0;
2317
2318 if (!PSA_ALG_IS_RAW_KEY_AGREEMENT(deriv_alg)) {
2319 TEST_FAIL("Unsupported key agreement algorithm");
2320 return;
2321 }
2322
2323 psa_set_key_usage_flags(&input_key_attr, PSA_KEY_USAGE_DERIVE);
2324 psa_set_key_algorithm(&input_key_attr, deriv_alg);
2325 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
2326 psa_set_key_type(&input_key_attr, key_type);
2327
2328 status = psa_import_key(&input_key_attr, ecdsa_private_key,
2329 sizeof(ecdsa_private_key), &input_key_id_local);
2330 if (status != PSA_SUCCESS) {
2331 TEST_FAIL("Error importing the private key");
2332 return;
2333 }
2334
2335 /* For simplicity, as the peer key use the public part of private key */
2336 status = psa_export_public_key(input_key_id_local,
2337 raw_agreement_peer_key,
2338 KEY_DERIV_RAW_MAX_PEER_LEN,
2339 &public_key_length);
2340 if (status != PSA_SUCCESS) {
2341 TEST_FAIL("Error extracting the public key as peer key");
2342 goto destroy_key;
2343 }
2344
2345 status = psa_raw_key_agreement(deriv_alg,
2346 input_key_id_local,
2347 raw_agreement_peer_key,
2348 public_key_length,
2349 raw_agreement_output_buffer,
2350 KEY_DERIV_RAW_OUTPUT_LEN,
2351 &raw_agreement_output_size);
2352 if (status != PSA_SUCCESS) {
2353 TEST_FAIL("Error performing single step raw key agreement");
2354 goto destroy_key;
2355 }
2356
2357 if (raw_agreement_output_size != sizeof(ecdsa_private_key)) {
2358 TEST_FAIL("Agreed key size is different than expected!");
2359 goto destroy_key;
2360 }
2361
2362 ret->val = TEST_PASSED;
2363
2364 destroy_key:
2365 psa_destroy_key(input_key_id_local);
2366
2367 return;
2368 }
2369
psa_key_derivation_test(psa_algorithm_t deriv_alg,struct test_result_t * ret)2370 void psa_key_derivation_test(psa_algorithm_t deriv_alg,
2371 struct test_result_t *ret)
2372 {
2373 psa_key_id_t input_key_id_local = PSA_KEY_ID_NULL,
2374 output_key_id_local = PSA_KEY_ID_NULL;
2375 psa_key_attributes_t input_key_attr = PSA_KEY_ATTRIBUTES_INIT;
2376 psa_key_attributes_t output_key_attr = PSA_KEY_ATTRIBUTES_INIT;
2377 psa_key_derivation_operation_t deriv_ops;
2378 psa_status_t status;
2379 uint8_t counter = 0xA5;
2380 psa_key_type_t key_type;
2381
2382 /* Prepare the parameters */
2383 memset(key_deriv_secret, counter, KEY_DERIV_SECRET_LEN);
2384 memset(key_deriv_label_info, counter++, KEY_DERIV_LABEL_INFO_LEN);
2385 memset(key_deriv_seed_salt, counter++, KEY_DERIV_SEED_SALT_LEN);
2386
2387 deriv_ops = psa_key_derivation_operation_init();
2388
2389 psa_set_key_usage_flags(&input_key_attr, PSA_KEY_USAGE_DERIVE);
2390 psa_set_key_algorithm(&input_key_attr, deriv_alg);
2391 key_type = PSA_KEY_TYPE_DERIVE;
2392 psa_set_key_type(&input_key_attr, key_type);
2393 status = psa_import_key(&input_key_attr, key_deriv_secret,
2394 KEY_DERIV_SECRET_LEN, &input_key_id_local);
2395
2396 if (status != PSA_SUCCESS) {
2397 TEST_FAIL("Failed to import secret");
2398 return;
2399 }
2400
2401 status = psa_key_derivation_setup(&deriv_ops, deriv_alg);
2402 if (status != PSA_SUCCESS) {
2403 TEST_FAIL("Failed to setup derivation operation");
2404 goto destroy_key;
2405 }
2406
2407 if (PSA_ALG_IS_TLS12_PRF(deriv_alg) ||
2408 PSA_ALG_IS_TLS12_PSK_TO_MS(deriv_alg)) {
2409 status = psa_key_derivation_input_bytes(&deriv_ops,
2410 PSA_KEY_DERIVATION_INPUT_SEED,
2411 key_deriv_seed_salt,
2412 KEY_DERIV_SEED_SALT_LEN);
2413 if (status != PSA_SUCCESS) {
2414 TEST_FAIL("Failed to input seed");
2415 goto deriv_abort;
2416 }
2417
2418 status = psa_key_derivation_input_key(&deriv_ops,
2419 PSA_KEY_DERIVATION_INPUT_SECRET,
2420 input_key_id_local);
2421 if (status != PSA_SUCCESS) {
2422 TEST_FAIL("Failed to input key");
2423 goto deriv_abort;
2424 }
2425
2426 status = psa_key_derivation_input_bytes(&deriv_ops,
2427 PSA_KEY_DERIVATION_INPUT_LABEL,
2428 key_deriv_label_info,
2429 KEY_DERIV_LABEL_INFO_LEN);
2430 if (status != PSA_SUCCESS) {
2431 TEST_FAIL("Failed to input label");
2432 goto deriv_abort;
2433 }
2434 } else if (PSA_ALG_IS_HKDF(deriv_alg)) {
2435 status = psa_key_derivation_input_bytes(&deriv_ops,
2436 PSA_KEY_DERIVATION_INPUT_SALT,
2437 key_deriv_seed_salt,
2438 KEY_DERIV_SEED_SALT_LEN);
2439 if (status != PSA_SUCCESS) {
2440 TEST_FAIL("Failed to input salt");
2441 goto deriv_abort;
2442 }
2443
2444 status = psa_key_derivation_input_key(&deriv_ops,
2445 PSA_KEY_DERIVATION_INPUT_SECRET,
2446 input_key_id_local);
2447 if (status != PSA_SUCCESS) {
2448 TEST_FAIL("Failed to input key");
2449 goto deriv_abort;
2450 }
2451
2452 status = psa_key_derivation_input_bytes(&deriv_ops,
2453 PSA_KEY_DERIVATION_INPUT_INFO,
2454 key_deriv_label_info,
2455 KEY_DERIV_LABEL_INFO_LEN);
2456 if (status != PSA_SUCCESS) {
2457 TEST_FAIL("Failed to input info");
2458 goto deriv_abort;
2459 }
2460 } else {
2461 TEST_FAIL("Unsupported derivation algorithm");
2462 goto deriv_abort;
2463 }
2464
2465 if (NR_TEST_AES_MODE < 1) {
2466 TEST_LOG("No AES algorithm to verify. Output raw data instead\r\n");
2467 psa_set_key_type(&output_key_attr, PSA_KEY_TYPE_RAW_DATA);
2468 } else {
2469 psa_set_key_usage_flags(&output_key_attr, PSA_KEY_USAGE_ENCRYPT);
2470 psa_set_key_algorithm(&output_key_attr, test_aes_mode_array[0]);
2471 psa_set_key_type(&output_key_attr, PSA_KEY_TYPE_AES);
2472 }
2473 psa_set_key_bits(&output_key_attr,
2474 PSA_BYTES_TO_BITS(KEY_DERIV_OUTPUT_LEN));
2475
2476 status = psa_key_derivation_output_key(&output_key_attr, &deriv_ops,
2477 &output_key_id_local);
2478 if (status != PSA_SUCCESS) {
2479 TEST_FAIL("Failed to output key");
2480 goto deriv_abort;
2481 }
2482
2483 ret->val = TEST_PASSED;
2484
2485 deriv_abort:
2486 psa_key_derivation_abort(&deriv_ops);
2487 destroy_key:
2488 psa_destroy_key(input_key_id_local);
2489 if (output_key_id_local) {
2490 psa_destroy_key(output_key_id_local);
2491 }
2492
2493 return;
2494 }
2495
2496 /* Key is generated using psa_generate_key then psa_export_key, using the
2497 * key attributes given in the test function */
2498 static const uint8_t rsa_key_pair[] = {
2499 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xd1, 0xd9,
2500 0xa2, 0x11, 0x6f, 0x2c, 0x56, 0x3b, 0x10, 0x01, 0xb8, 0x96, 0xa1, 0x8c, 0x79,
2501 0xfa, 0x3c, 0x9a, 0x45, 0xe8, 0x03, 0xdb, 0x45, 0x66, 0xd1, 0x75, 0xf3, 0xd8,
2502 0x3a, 0x10, 0xb3, 0x0f, 0x6c, 0x61, 0x78, 0x05, 0x21, 0xd6, 0x9a, 0x32, 0x25,
2503 0xf0, 0x04, 0xd8, 0x1b, 0xf7, 0xa4, 0xd7, 0x0d, 0xd6, 0x00, 0xa4, 0x95, 0x92,
2504 0xeb, 0x24, 0x1e, 0x37, 0xb5, 0x22, 0x9e, 0x7d, 0x22, 0x31, 0x6d, 0xd8, 0xf3,
2505 0x2e, 0x4f, 0x8a, 0x94, 0x6f, 0xe6, 0x4e, 0x60, 0xa9, 0xed, 0x85, 0x70, 0x5b,
2506 0xa3, 0x32, 0xbd, 0x8c, 0x1b, 0x11, 0xe4, 0x99, 0xce, 0x1f, 0xb9, 0x1f, 0xe1,
2507 0xa8, 0x3a, 0x45, 0x55, 0xdd, 0x63, 0x94, 0x01, 0x99, 0xb7, 0xf7, 0x70, 0x7a,
2508 0xf6, 0x49, 0xf3, 0x2e, 0xd3, 0xd7, 0x61, 0xfe, 0x81, 0x59, 0xd2, 0xe1, 0x45,
2509 0x57, 0xfd, 0x1e, 0xfe, 0x87, 0x97, 0xbf, 0x40, 0x09, 0x02, 0x03, 0x01, 0x00,
2510 0x01, 0x02, 0x81, 0x80, 0x03, 0x8d, 0x79, 0x2a, 0x6d, 0x64, 0xe5, 0x42, 0xd3,
2511 0xb7, 0x0b, 0xbe, 0x75, 0x16, 0xb1, 0x3b, 0xf4, 0xc9, 0xb1, 0xd4, 0x47, 0x38,
2512 0x6f, 0x98, 0xd9, 0x83, 0xf3, 0x30, 0x5e, 0x6f, 0x48, 0xf0, 0xc2, 0x67, 0x76,
2513 0x06, 0x34, 0x37, 0xf3, 0x5d, 0x54, 0xfa, 0x16, 0xc2, 0xe7, 0xda, 0x4d, 0xee,
2514 0x9c, 0x1b, 0xda, 0xdf, 0xee, 0x6e, 0x51, 0xcf, 0xc7, 0x39, 0x2f, 0x36, 0x5a,
2515 0x53, 0x89, 0x00, 0x20, 0x5d, 0x0c, 0x14, 0x2c, 0xb1, 0x0b, 0xa1, 0x7f, 0xcf,
2516 0xee, 0x48, 0x34, 0x01, 0x93, 0xb2, 0x67, 0x0b, 0x6b, 0xaa, 0xd8, 0xc6, 0x03,
2517 0x67, 0xe3, 0xda, 0x64, 0xb4, 0xd1, 0x89, 0x9e, 0x46, 0xc5, 0xdd, 0x6c, 0x8a,
2518 0xb6, 0x92, 0x0a, 0x24, 0xb7, 0x2d, 0x4a, 0x36, 0x7b, 0x5e, 0x3b, 0x98, 0x42,
2519 0x5d, 0xa8, 0x58, 0xfe, 0x02, 0xd3, 0x5d, 0x1a, 0xc8, 0x02, 0xef, 0xc3, 0x4b,
2520 0xe7, 0x59, 0x02, 0x41, 0x00, 0xf5, 0x8d, 0x58, 0xb0, 0x5e, 0x82, 0x17, 0x8b,
2521 0xa7, 0x31, 0xed, 0x0b, 0xb2, 0x1c, 0x38, 0x7c, 0x07, 0x31, 0x15, 0xe3, 0x74,
2522 0xc4, 0x7d, 0xd8, 0xd7, 0x29, 0xfe, 0x84, 0xa0, 0x8d, 0x81, 0xdd, 0x6c, 0xb4,
2523 0x27, 0x41, 0xe3, 0x82, 0xa1, 0x6c, 0xa9, 0x3e, 0x93, 0xe8, 0xfd, 0x3c, 0xa4,
2524 0xd1, 0x06, 0xb9, 0x9e, 0x07, 0x38, 0x51, 0xa4, 0x45, 0x3d, 0xff, 0x6d, 0x62,
2525 0x39, 0xa3, 0x11, 0x5d, 0x02, 0x41, 0x00, 0xda, 0xc7, 0x67, 0xe8, 0xf0, 0xa2,
2526 0xe3, 0xe7, 0x7d, 0x6c, 0xf4, 0xcc, 0x6d, 0x87, 0xf9, 0x76, 0xea, 0x61, 0xb4,
2527 0xfa, 0xce, 0x05, 0x5e, 0xee, 0x5c, 0x12, 0x53, 0x88, 0xda, 0xc9, 0xc6, 0x81,
2528 0x7d, 0x5c, 0xd3, 0x89, 0x1f, 0x2f, 0x7f, 0x1f, 0x11, 0x11, 0xd6, 0xd6, 0x45,
2529 0x44, 0xe9, 0x1d, 0x35, 0x55, 0x1b, 0x02, 0xaf, 0xd4, 0xa5, 0xd1, 0xc2, 0xe7,
2530 0x55, 0x35, 0x00, 0xf8, 0x62, 0x9d, 0x02, 0x41, 0x00, 0xbc, 0xe8, 0x90, 0x29,
2531 0xa7, 0x9b, 0xa7, 0xe7, 0x9d, 0xaa, 0x50, 0x36, 0xa6, 0x41, 0x05, 0xc7, 0x8d,
2532 0x74, 0xda, 0xe5, 0x11, 0x69, 0x35, 0x74, 0x44, 0x1c, 0x1f, 0x9e, 0x03, 0x32,
2533 0xba, 0x8d, 0x11, 0xdb, 0x0b, 0x34, 0xaa, 0x86, 0x4e, 0x10, 0x1d, 0xa8, 0x71,
2534 0xfc, 0x56, 0x0e, 0x78, 0xb2, 0x02, 0xdd, 0x7c, 0x51, 0x0b, 0xa7, 0xeb, 0x9c,
2535 0x05, 0x95, 0x63, 0x9e, 0xa4, 0xbe, 0xea, 0x55, 0x02, 0x41, 0x00, 0x94, 0x8a,
2536 0xc9, 0x79, 0x76, 0x51, 0x12, 0xae, 0x6d, 0x11, 0x9a, 0x50, 0x66, 0x99, 0xe8,
2537 0xfe, 0x1d, 0x7b, 0x43, 0x96, 0xfa, 0x64, 0xd9, 0x24, 0xbb, 0xac, 0xd1, 0xbc,
2538 0xdc, 0xd8, 0x1d, 0x08, 0x74, 0x66, 0x9f, 0x55, 0xbd, 0xaf, 0xd0, 0xfe, 0xf5,
2539 0xe7, 0x07, 0xd8, 0x29, 0xe5, 0xf4, 0xe5, 0x18, 0xfd, 0xf4, 0xbd, 0xe9, 0x46,
2540 0x57, 0x63, 0xc9, 0x92, 0xa9, 0xde, 0xb8, 0x0e, 0xed, 0x5d, 0x02, 0x40, 0x39,
2541 0x30, 0x79, 0xb5, 0xe1, 0x22, 0xa7, 0x0e, 0xff, 0x96, 0x56, 0x7e, 0x16, 0xf3,
2542 0x4c, 0xbd, 0x81, 0x94, 0x14, 0x53, 0xd4, 0x9b, 0xb6, 0xfa, 0xf9, 0x18, 0xf5,
2543 0x4b, 0xe3, 0x5f, 0xb1, 0x87, 0x54, 0x67, 0x61, 0xc4, 0x05, 0x05, 0x01, 0x26,
2544 0x89, 0xb0, 0xa3, 0x8b, 0xde, 0x18, 0xdb, 0x3f, 0x37, 0x09, 0x35, 0x65, 0x17,
2545 0x9c, 0x37, 0xbe, 0x40, 0xed, 0xc6, 0x5c, 0xf8, 0x7e, 0x4b, 0x04};
2546
2547 #define PLAIN_TEXT_SIZE 16
2548 #define RSA_KEY_SIZE 128
2549
psa_asymmetric_encryption_test(psa_algorithm_t alg,struct test_result_t * ret)2550 void psa_asymmetric_encryption_test(psa_algorithm_t alg,
2551 struct test_result_t *ret)
2552 {
2553 psa_status_t status = PSA_SUCCESS;
2554 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
2555 const uint8_t plain_text[] = "This is a test.";
2556 uint8_t encrypted_data[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] = {0};
2557 size_t encrypted_size;
2558 size_t encrypted_length = 0;
2559 uint8_t decrypted_data[PLAIN_TEXT_SIZE] = {0};
2560 size_t decrypted_size = PLAIN_TEXT_SIZE;
2561 size_t decrypted_length = 0;
2562 const uint8_t * key_pair;
2563 size_t key_size;
2564 uint32_t comp_result;
2565
2566 psa_key_attributes_t key_attributes = psa_key_attributes_init();
2567
2568 /* Setup key attributes */
2569 psa_set_key_usage_flags(&key_attributes,
2570 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
2571 psa_set_key_algorithm(&key_attributes, alg);
2572
2573 if (PSA_ALG_IS_RSA_OAEP(alg) || alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
2574 psa_set_key_type(&key_attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
2575 encrypted_size = RSA_KEY_SIZE;
2576 key_pair = rsa_key_pair;
2577 key_size = sizeof(rsa_key_pair);
2578 } else {
2579 TEST_FAIL("Unsupported asymmetric encryption algorithm");
2580 return;
2581 }
2582
2583 status = psa_import_key(&key_attributes, key_pair, key_size, &key_id_local);
2584 if (status != PSA_SUCCESS) {
2585 TEST_FAIL("Error importing a key");
2586 return;
2587 }
2588
2589 status = psa_asymmetric_encrypt(key_id_local, alg, plain_text,
2590 sizeof(plain_text), NULL, 0, encrypted_data,
2591 encrypted_size, &encrypted_length);
2592 if (status != PSA_SUCCESS) {
2593 TEST_FAIL("Error encrypting the plaintext");
2594 goto destroy_key;
2595 }
2596
2597 if (encrypted_size != encrypted_length) {
2598 TEST_FAIL("Unexpected encrypted length");
2599 goto destroy_key;
2600 }
2601
2602 status = psa_asymmetric_decrypt(key_id_local, alg, encrypted_data,
2603 encrypted_size, NULL, 0, decrypted_data,
2604 decrypted_size, &decrypted_length);
2605 if (status != PSA_SUCCESS) {
2606 TEST_FAIL("Error during asymmetric decryption");
2607 goto destroy_key;
2608 }
2609
2610 if (decrypted_size != decrypted_length) {
2611 TEST_FAIL("Unexpected decrypted length");
2612 goto destroy_key;
2613 }
2614
2615 /* Check that the plain text matches the decrypted data */
2616 comp_result = memcmp(plain_text, decrypted_data, sizeof(plain_text));
2617 if (comp_result != 0) {
2618 TEST_FAIL("Decrypted data doesn't match with plain text");
2619 goto destroy_key;
2620 }
2621
2622 ret->val = TEST_PASSED;
2623 destroy_key:
2624 /* Destroy the key */
2625 status = psa_destroy_key(key_id_local);
2626 if (status != PSA_SUCCESS) {
2627 TEST_FAIL("Error destroying a key");
2628 }
2629 }
2630
2631 #define SIGNATURE_BUFFER_SIZE \
2632 (PSA_ECDSA_SIGNATURE_SIZE(PSA_BYTES_TO_BITS(sizeof(ecdsa_private_key))))
2633
psa_sign_verify_message_test(psa_algorithm_t alg,struct test_result_t * ret)2634 void psa_sign_verify_message_test(psa_algorithm_t alg,
2635 struct test_result_t *ret)
2636 {
2637 psa_status_t status = PSA_SUCCESS;
2638 psa_key_id_t key_id_local = PSA_KEY_ID_NULL;
2639 psa_key_type_t key_type;
2640 psa_key_attributes_t input_key_attr = PSA_KEY_ATTRIBUTES_INIT;
2641 const uint8_t message[] =
2642 "This is the message that I would like to sign";
2643 uint8_t signature[SIGNATURE_BUFFER_SIZE] = {0};
2644 size_t signature_length = 0;
2645 /* The expected format of the public key is uncompressed, i.e. 0x04 X Y */
2646 uint8_t ecdsa_pub_key[
2647 PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_BYTES_TO_BITS(sizeof(ecdsa_private_key)))] = {0};
2648 size_t pub_key_length = 0;
2649 uint32_t comp_result = 0;
2650 uint8_t hash[32] = {0}; /* Support only SHA-256 based signatures in the tests for simplicity */
2651 size_t hash_length = 0;
2652
2653 /* Initialize to the passing value */
2654 ret->val = TEST_PASSED;
2655
2656 /* Set attributes and import key */
2657 psa_set_key_usage_flags(&input_key_attr,
2658 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT);
2659 psa_set_key_algorithm(&input_key_attr, alg);
2660 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
2661 psa_set_key_type(&input_key_attr, key_type);
2662
2663 status = psa_import_key(&input_key_attr, ecdsa_private_key,
2664 sizeof(ecdsa_private_key), &key_id_local);
2665 if (status != PSA_SUCCESS) {
2666 TEST_FAIL("Error importing the private key");
2667 return;
2668 }
2669
2670 status = psa_export_public_key(key_id_local, ecdsa_pub_key,
2671 sizeof(ecdsa_pub_key), &pub_key_length);
2672 if (status != PSA_SUCCESS) {
2673 TEST_FAIL("Public key export failed!");
2674 goto destroy_key;
2675 }
2676
2677 if (pub_key_length !=
2678 PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_BYTES_TO_BITS(sizeof(ecdsa_private_key)))) {
2679 TEST_FAIL("Unexpected length for the public key!");
2680 goto destroy_key;
2681 }
2682
2683 /* Check that exported key matches the reference key */
2684 comp_result = memcmp(ecdsa_pub_key, ecdsa_public_key, pub_key_length);
2685 if (comp_result != 0) {
2686 TEST_FAIL("Exported ECDSA public key does not match the reference!");
2687 goto destroy_key;
2688 }
2689
2690 status = psa_sign_message(key_id_local, alg,
2691 message, sizeof(message) - 1,
2692 signature, SIGNATURE_BUFFER_SIZE,
2693 &signature_length);
2694 if (status != PSA_SUCCESS) {
2695 TEST_FAIL("Message signing failed!");
2696 goto destroy_key;
2697 }
2698
2699 if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(
2700 PSA_BYTES_TO_BITS(
2701 sizeof(ecdsa_private_key)))) {
2702 TEST_FAIL("Unexpected signature length");
2703 goto destroy_key;
2704 }
2705
2706 status = psa_verify_message(key_id_local, alg,
2707 message, sizeof(message) - 1,
2708 signature, signature_length);
2709 if (status != PSA_SUCCESS) {
2710 TEST_FAIL(("Signature verification failed!"));
2711 goto destroy_key;
2712 }
2713
2714 destroy_key:
2715 psa_destroy_key(key_id_local);
2716
2717 if (ret->val == TEST_FAILED) {
2718 return;
2719 }
2720
2721 /* Continue with the dedicated verify hash flow */
2722 /* Set attributes and import key */
2723 psa_set_key_usage_flags(&input_key_attr, PSA_KEY_USAGE_VERIFY_HASH);
2724 psa_set_key_algorithm(&input_key_attr, alg);
2725 key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
2726 psa_set_key_type(&input_key_attr, key_type);
2727
2728 status = psa_import_key(&input_key_attr, ecdsa_public_key,
2729 sizeof(ecdsa_public_key), &key_id_local);
2730 if (status != PSA_SUCCESS) {
2731 TEST_FAIL("Error importing the public key");
2732 return;
2733 }
2734
2735 status = psa_hash_compute(PSA_ALG_GET_HASH(alg),
2736 message, sizeof(message) - 1,
2737 hash, sizeof(hash), &hash_length);
2738 if (status != PSA_SUCCESS) {
2739 TEST_FAIL("Hashing step failed!");
2740 goto destroy_public_key;
2741 }
2742
2743 if (hash_length != 32) {
2744 TEST_FAIL("Unexpected hash length in the hashing step!");
2745 goto destroy_public_key;
2746 }
2747
2748 status = psa_verify_hash(key_id_local, alg,
2749 hash, hash_length,
2750 signature, signature_length);
2751 if (status != PSA_SUCCESS) {
2752 TEST_FAIL("Signature verification failed in the verify_hash!");
2753 goto destroy_public_key;
2754 }
2755
2756 destroy_public_key:
2757 psa_destroy_key(key_id_local);
2758
2759 return;
2760 }
2761
2762 #if defined(TFM_CRYPTO_TEST_ALG_RSASSA_PSS_VERIFICATION)
2763 /* A random RSA key of length 2048 bits. PSA key format is implementation dependent
2764 * and our underlying key management interface based on mbed TLS supports only DER
2765 * format as described by relevant RFC3447. As we test only the verification path,
2766 * the key below is only the (N,E) public part in DER format
2767 * */
2768 static const uint8_t rsa_key_2048[] = {
2769 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01,
2770 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01,
2771 0x00, 0xDA, 0x4E, 0x01, 0x18, 0x21, 0x6C, 0xA2, 0xCF, 0xEE, 0xD2, 0xD1, 0x8A, 0x55, 0xE5, 0x2B,
2772 0x43, 0x02, 0x0F, 0x89, 0xEC, 0xCA, 0xE9, 0x1A, 0x2F, 0x80, 0xCE, 0x7B, 0x42, 0xDD, 0xF9, 0xD2,
2773 0xF9, 0x7B, 0xA2, 0x17, 0x97, 0x76, 0x3F, 0xE2, 0x97, 0x95, 0x0B, 0xA7, 0x77, 0x21, 0x9D, 0x18,
2774 0x16, 0x1F, 0xC1, 0x1E, 0x1D, 0xF8, 0xDE, 0xDA, 0x18, 0x98, 0xE2, 0xF5, 0xB0, 0x3D, 0x71, 0xBB,
2775 0x63, 0x54, 0x36, 0x16, 0xCB, 0x03, 0x72, 0x27, 0xAF, 0x24, 0x66, 0xE9, 0x44, 0x1E, 0xDC, 0x17,
2776 0x56, 0x2E, 0x97, 0xA4, 0xA0, 0x52, 0xB0, 0x61, 0xEF, 0x9C, 0x10, 0x01, 0x2D, 0x5D, 0x12, 0x60,
2777 0xA8, 0xA3, 0xEE, 0xEF, 0x22, 0x49, 0xDE, 0xBA, 0xC1, 0x83, 0x6F, 0x0E, 0x38, 0x10, 0x0E, 0x56,
2778 0x63, 0x6D, 0x6C, 0x44, 0xD7, 0xB1, 0xA5, 0x15, 0xB6, 0x94, 0x1D, 0xAF, 0x5A, 0xE5, 0x1C, 0x10,
2779 0x8D, 0x05, 0x67, 0x3A, 0x60, 0xBD, 0xE7, 0xCB, 0x60, 0xE0, 0x6A, 0x84, 0x96, 0x3C, 0xDB, 0xA4,
2780 0x71, 0x93, 0x7C, 0xF4, 0x25, 0x15, 0x32, 0x41, 0x1F, 0x16, 0x72, 0xB3, 0x15, 0xFB, 0x76, 0xA2,
2781 0x9E, 0x77, 0x69, 0xA3, 0x34, 0x7D, 0x8A, 0x39, 0x38, 0xA8, 0xBA, 0x44, 0xAD, 0x0C, 0x3C, 0x61,
2782 0x5C, 0x7D, 0xC7, 0xDF, 0x25, 0xEC, 0x0F, 0xC4, 0x4E, 0x81, 0x73, 0xB6, 0xC1, 0x08, 0xE6, 0xB7,
2783 0xE7, 0xD6, 0xC8, 0x14, 0xCB, 0x6E, 0x4E, 0xA4, 0x1F, 0xD7, 0x29, 0x0D, 0x08, 0x46, 0xC7, 0x2C,
2784 0xC0, 0x8E, 0x42, 0x0F, 0x49, 0xA5, 0xA6, 0xB0, 0x0E, 0x5D, 0xEC, 0x7A, 0x4A, 0x4E, 0xAE, 0xFA,
2785 0x1B, 0x5F, 0x77, 0x9F, 0x4A, 0x86, 0x66, 0x47, 0x20, 0xBC, 0x69, 0xF3, 0xD9, 0x63, 0xC1, 0xF8,
2786 0x84, 0x99, 0x12, 0x67, 0x65, 0xE1, 0x40, 0xAC, 0x42, 0x93, 0x11, 0x97, 0xF3, 0xBB, 0x93, 0xB0,
2787 0x1B, 0x02, 0x03, 0x01, 0x00, 0x01,
2788 };
2789
2790 #define SIGNATURE_OUTPUT_SIZE_RSA_2048 \
2791 PSA_SIGN_OUTPUT_SIZE(PSA_KEY_TYPE_RSA_KEY_PAIR, 2048, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256))
2792
2793 /*
2794 * Signature for the following message:
2795 * const uint8_t message[] = "This is the message that I would like to sign";
2796 *
2797 * This can be obtained by running psa_sign_message() as follows:
2798 * psa_sign_message(key_id, PSA_ALG_RSA_PSS(PSA_ALG_SHA256),
2799 * message, sizeof(message) - 1,
2800 * signature_pss_sha_256, SIGNATURE_OUTPUT_SIZE_RSA_2048,
2801 * &signature_length);
2802 *
2803 * where signature_pss_sha_256 contains the produced signature. The key_id refers here to
2804 * the full RSA_KEY_PAIR, while for the verification path we only need to keep the public part.
2805 *
2806 */
2807 const uint8_t signature_pss_sha_256[] = {
2808 0x47, 0xB5, 0x85, 0x1D, 0xE2, 0xD8, 0xFC, 0xC2, 0x69, 0x22, 0x33, 0x9C, 0xB2, 0xBA, 0x69, 0x87,
2809 0xD1, 0x9C, 0x67, 0xEE, 0xE6, 0x48, 0x27, 0xD2, 0x07, 0xA3, 0x19, 0x2E, 0x43, 0xFD, 0xCE, 0xCA,
2810 0xE7, 0x63, 0xB4, 0xC0, 0x02, 0x4D, 0x61, 0x69, 0xAA, 0x4A, 0xF7, 0xB9, 0x80, 0xC3, 0x53, 0x78,
2811 0x5D, 0xC3, 0xA4, 0x0C, 0xC3, 0x67, 0x2F, 0xB7, 0xBD, 0x73, 0xF4, 0x58, 0x95, 0x16, 0x97, 0x45,
2812 0xA1, 0x4F, 0x3F, 0xB1, 0x44, 0x08, 0x57, 0x0A, 0x87, 0xDE, 0x3F, 0xF1, 0x3A, 0xC9, 0x24, 0xE6,
2813 0xA6, 0xEB, 0x22, 0xE9, 0xC9, 0x8F, 0x7E, 0x65, 0x30, 0x36, 0x35, 0x62, 0x06, 0xDF, 0xBE, 0x1D,
2814 0xA4, 0x1C, 0x42, 0x3D, 0xAB, 0x22, 0x01, 0xDD, 0x86, 0x3D, 0x81, 0x12, 0xF5, 0x5B, 0x16, 0xFD,
2815 0xF2, 0xFE, 0x7D, 0x90, 0x60, 0x3A, 0x70, 0xCB, 0xAB, 0xE5, 0x3F, 0xA5, 0x83, 0x42, 0xD5, 0x42,
2816 0x18, 0x00, 0x5E, 0xC1, 0x4F, 0x7E, 0x3A, 0xCD, 0x42, 0xA2, 0x16, 0x40, 0xCD, 0xE6, 0xC6, 0xBC,
2817 0xDD, 0xBA, 0x11, 0xA5, 0xA9, 0x31, 0xE1, 0x3F, 0xCB, 0x92, 0x3B, 0x5D, 0xE4, 0xB1, 0xD1, 0x3A,
2818 0x5F, 0xE4, 0xCB, 0x3B, 0x61, 0xD7, 0x83, 0xCB, 0x9A, 0x7B, 0xA7, 0x71, 0x60, 0x90, 0x13, 0xC0,
2819 0x27, 0x2D, 0xD4, 0xF4, 0x32, 0xC5, 0x80, 0xEA, 0x7E, 0xA7, 0xE8, 0x74, 0x97, 0x14, 0xC3, 0xCE,
2820 0x15, 0x84, 0x5E, 0x09, 0x63, 0x08, 0xDA, 0x19, 0xB5, 0x27, 0x9F, 0xEE, 0xE4, 0xCE, 0x08, 0x5B,
2821 0x9E, 0x95, 0xCA, 0xC8, 0xC1, 0x54, 0xEE, 0x69, 0xB8, 0x25, 0xB9, 0xE6, 0xCD, 0x1C, 0x4B, 0x4E,
2822 0xA2, 0x69, 0xC2, 0xE7, 0x91, 0xA7, 0xA6, 0x5C, 0x55, 0x6A, 0xAA, 0xE9, 0x91, 0x4F, 0x0D, 0x05,
2823 0x7E, 0x49, 0x19, 0xF4, 0xE9, 0xE5, 0xB4, 0x3E, 0x5C, 0x5E, 0xFB, 0x28, 0x23, 0xE7, 0x27, 0xAE,
2824 };
2825
2826 /* A test case dedicated to RSASSA-PSA VERIFY operation */
psa_verify_rsassa_pss_test(struct test_result_t * ret)2827 void psa_verify_rsassa_pss_test(struct test_result_t *ret)
2828 {
2829 psa_status_t status = PSA_SUCCESS;
2830 psa_key_id_t key_id = PSA_KEY_ID_NULL;
2831 psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
2832 const psa_algorithm_t alg = PSA_ALG_RSA_PSS(PSA_ALG_SHA_256);
2833 uint8_t hash[32] = {0};
2834 size_t hash_length = 0;
2835
2836 const uint8_t message[] =
2837 "This is the message that I would like to sign";
2838
2839 /* Set attributes and import key */
2840 /* The verify_hash flag enables automatically verify_message as well */
2841 psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_HASH);
2842 psa_set_key_algorithm(&key_attr, alg);
2843 psa_set_key_type(&key_attr, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
2844
2845 status = psa_import_key(&key_attr,
2846 (const uint8_t *)rsa_key_2048,
2847 sizeof(rsa_key_2048),
2848 &key_id);
2849 if (status != PSA_SUCCESS) {
2850 TEST_FAIL("Error importing the private key");
2851 return;
2852 }
2853
2854 if (sizeof(signature_pss_sha_256) != SIGNATURE_OUTPUT_SIZE_RSA_2048) {
2855 TEST_FAIL("Unexpected signature length");
2856 goto destroy_key;
2857 }
2858
2859 status = psa_verify_message(key_id, alg,
2860 message, sizeof(message) - 1,
2861 signature_pss_sha_256, sizeof(signature_pss_sha_256));
2862 if (status != PSA_SUCCESS) {
2863 TEST_FAIL("Signature verification failed in the verify_message!");
2864 goto destroy_key;
2865 }
2866
2867 /* Try the same verification, but this time split the hash calculation in a
2868 * separate API call. This is useful for those protocols that require to
2869 * treat the hashing in a special way (i.e. special seeding), or need to do
2870 * hashing in multipart. For simplicity here we just use single-part hashing
2871 */
2872 status = psa_hash_compute(PSA_ALG_GET_HASH(alg),
2873 message, sizeof(message) - 1,
2874 hash, sizeof(hash), &hash_length);
2875 if (status != PSA_SUCCESS) {
2876 TEST_FAIL("Hashing step failed!");
2877 goto destroy_key;
2878 }
2879
2880 if (hash_length != 32) {
2881 TEST_FAIL("Unexpected hash length in the hashing step!");
2882 goto destroy_key;
2883 }
2884
2885 status = psa_verify_hash(key_id, alg,
2886 hash, hash_length,
2887 signature_pss_sha_256, sizeof(signature_pss_sha_256));
2888 if (status != PSA_SUCCESS) {
2889 TEST_FAIL("Signature verification failed in the verify_hash!");
2890 goto destroy_key;
2891 }
2892 ret->val = TEST_PASSED;
2893
2894 destroy_key:
2895 psa_destroy_key(key_id);
2896
2897 return;
2898 }
2899 #endif /* TFM_CRYPTO_TEST_ALG_RSASSA_PSS_VERIFICATION */
2900