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