blob: b1964a4e76d5e4382affc5ef53a7c8235a3e6237 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/* BEGIN_HEADER */
itayzafrir3e02b3b2018-06-12 17:06:52 +03002#include <stdint.h>
mohammad160327010052018-07-03 13:16:15 +03003
4#if defined(MBEDTLS_PSA_CRYPTO_SPM)
5#include "spm/psa_defs.h"
6#endif
7
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02008#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02009#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +020010#include "mbedtls/oid.h"
11
Gilles Peskinee59236f2018-01-27 23:32:46 +010012#include "psa/crypto.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +030013
Jaeden Amerof24c7f82018-06-27 17:20:43 +010014/** An invalid export length that will never be set by psa_export_key(). */
15static const size_t INVALID_EXPORT_LENGTH = ~0U;
16
Gilles Peskinef426e0f2019-02-25 17:42:03 +010017/* A hash algorithm that is known to be supported.
18 *
19 * This is used in some smoke tests.
20 */
21#if defined(MBEDTLS_MD2_C)
22#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
23#elif defined(MBEDTLS_MD4_C)
24#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
25#elif defined(MBEDTLS_MD5_C)
26#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
27/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
28 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
29 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
30 * implausible anyway. */
31#elif defined(MBEDTLS_SHA1_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
33#elif defined(MBEDTLS_SHA256_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
35#elif defined(MBEDTLS_SHA512_C)
36#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
37#elif defined(MBEDTLS_SHA3_C)
38#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
39#else
40#undef KNOWN_SUPPORTED_HASH_ALG
41#endif
42
43/* A block cipher that is known to be supported.
44 *
45 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
46 */
47#if defined(MBEDTLS_AES_C)
48#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
49#elif defined(MBEDTLS_ARIA_C)
50#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
51#elif defined(MBEDTLS_CAMELLIA_C)
52#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
53#undef KNOWN_SUPPORTED_BLOCK_CIPHER
54#endif
55
56/* A MAC mode that is known to be supported.
57 *
58 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
59 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
60 *
61 * This is used in some smoke tests.
62 */
63#if defined(KNOWN_SUPPORTED_HASH_ALG)
64#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
65#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
66#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
67#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
68#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
69#else
70#undef KNOWN_SUPPORTED_MAC_ALG
71#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
72#endif
73
74/* A cipher algorithm and key type that are known to be supported.
75 *
76 * This is used in some smoke tests.
77 */
78#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
79#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
80#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
81#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
82#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
83#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
84#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
85#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
86#else
87#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
88#endif
89#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
90#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
91#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
92#elif defined(MBEDTLS_RC4_C)
93#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
94#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
95#else
96#undef KNOWN_SUPPORTED_CIPHER_ALG
97#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
98#endif
99
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200100/** Test if a buffer contains a constant byte value.
101 *
102 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200103 *
104 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200105 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 * \param size Size of the buffer in bytes.
107 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200108 * \return 1 if the buffer is all-bits-zero.
109 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200110 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200111static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200112{
113 size_t i;
114 for( i = 0; i < size; i++ )
115 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200116 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200117 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200118 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200119 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200120}
Gilles Peskine818ca122018-06-20 18:16:48 +0200121
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200122/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
123static int asn1_write_10x( unsigned char **p,
124 unsigned char *start,
125 size_t bits,
126 unsigned char x )
127{
128 int ret;
129 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200130 if( bits == 0 )
131 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
132 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200133 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300134 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200135 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
136 *p -= len;
137 ( *p )[len-1] = x;
138 if( bits % 8 == 0 )
139 ( *p )[1] |= 1;
140 else
141 ( *p )[0] |= 1 << ( bits % 8 );
142 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
143 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
144 MBEDTLS_ASN1_INTEGER ) );
145 return( len );
146}
147
148static int construct_fake_rsa_key( unsigned char *buffer,
149 size_t buffer_size,
150 unsigned char **p,
151 size_t bits,
152 int keypair )
153{
154 size_t half_bits = ( bits + 1 ) / 2;
155 int ret;
156 int len = 0;
157 /* Construct something that looks like a DER encoding of
158 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
159 * RSAPrivateKey ::= SEQUENCE {
160 * version Version,
161 * modulus INTEGER, -- n
162 * publicExponent INTEGER, -- e
163 * privateExponent INTEGER, -- d
164 * prime1 INTEGER, -- p
165 * prime2 INTEGER, -- q
166 * exponent1 INTEGER, -- d mod (p-1)
167 * exponent2 INTEGER, -- d mod (q-1)
168 * coefficient INTEGER, -- (inverse of q) mod p
169 * otherPrimeInfos OtherPrimeInfos OPTIONAL
170 * }
171 * Or, for a public key, the same structure with only
172 * version, modulus and publicExponent.
173 */
174 *p = buffer + buffer_size;
175 if( keypair )
176 {
177 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
178 asn1_write_10x( p, buffer, half_bits, 1 ) );
179 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
180 asn1_write_10x( p, buffer, half_bits, 1 ) );
181 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
182 asn1_write_10x( p, buffer, half_bits, 1 ) );
183 MBEDTLS_ASN1_CHK_ADD( len, /* q */
184 asn1_write_10x( p, buffer, half_bits, 1 ) );
185 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
186 asn1_write_10x( p, buffer, half_bits, 3 ) );
187 MBEDTLS_ASN1_CHK_ADD( len, /* d */
188 asn1_write_10x( p, buffer, bits, 1 ) );
189 }
190 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
191 asn1_write_10x( p, buffer, 17, 1 ) );
192 MBEDTLS_ASN1_CHK_ADD( len, /* n */
193 asn1_write_10x( p, buffer, bits, 1 ) );
194 if( keypair )
195 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
196 mbedtls_asn1_write_int( p, buffer, 0 ) );
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
198 {
199 const unsigned char tag =
200 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
201 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
202 }
203 return( len );
204}
205
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100206int exercise_mac_setup( psa_key_type_t key_type,
207 const unsigned char *key_bytes,
208 size_t key_length,
209 psa_algorithm_t alg,
210 psa_mac_operation_t *operation,
211 psa_status_t *status )
212{
213 psa_key_handle_t handle = 0;
214 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
215
216 PSA_ASSERT( psa_allocate_key( &handle ) );
217 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
218 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +0200219 PSA_ASSERT( psa_import_key_to_handle( handle, key_type, key_bytes, key_length ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100220
221 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100222 /* Whether setup succeeded or failed, abort must succeed. */
223 PSA_ASSERT( psa_mac_abort( operation ) );
224 /* If setup failed, reproduce the failure, so that the caller can
225 * test the resulting state of the operation object. */
226 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100227 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100228 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
229 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100230 }
231
232 psa_destroy_key( handle );
233 return( 1 );
234
235exit:
236 psa_destroy_key( handle );
237 return( 0 );
238}
239
240int exercise_cipher_setup( psa_key_type_t key_type,
241 const unsigned char *key_bytes,
242 size_t key_length,
243 psa_algorithm_t alg,
244 psa_cipher_operation_t *operation,
245 psa_status_t *status )
246{
247 psa_key_handle_t handle = 0;
248 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
249
250 PSA_ASSERT( psa_allocate_key( &handle ) );
251 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
252 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +0200253 PSA_ASSERT( psa_import_key_to_handle( handle, key_type, key_bytes, key_length ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100254
255 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100256 /* Whether setup succeeded or failed, abort must succeed. */
257 PSA_ASSERT( psa_cipher_abort( operation ) );
258 /* If setup failed, reproduce the failure, so that the caller can
259 * test the resulting state of the operation object. */
260 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100261 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100262 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
263 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100264 }
265
266 psa_destroy_key( handle );
267 return( 1 );
268
269exit:
270 psa_destroy_key( handle );
271 return( 0 );
272}
273
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100274static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200275 psa_key_usage_t usage,
276 psa_algorithm_t alg )
277{
Jaeden Amero769ce272019-01-04 11:48:03 +0000278 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200279 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200280 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200281 size_t mac_length = sizeof( mac );
282
283 if( usage & PSA_KEY_USAGE_SIGN )
284 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100285 PSA_ASSERT( psa_mac_sign_setup( &operation,
286 handle, alg ) );
287 PSA_ASSERT( psa_mac_update( &operation,
288 input, sizeof( input ) ) );
289 PSA_ASSERT( psa_mac_sign_finish( &operation,
290 mac, sizeof( mac ),
291 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200292 }
293
294 if( usage & PSA_KEY_USAGE_VERIFY )
295 {
296 psa_status_t verify_status =
297 ( usage & PSA_KEY_USAGE_SIGN ?
298 PSA_SUCCESS :
299 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100300 PSA_ASSERT( psa_mac_verify_setup( &operation,
301 handle, alg ) );
302 PSA_ASSERT( psa_mac_update( &operation,
303 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100304 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
305 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200306 }
307
308 return( 1 );
309
310exit:
311 psa_mac_abort( &operation );
312 return( 0 );
313}
314
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100315static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200316 psa_key_usage_t usage,
317 psa_algorithm_t alg )
318{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000319 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200320 unsigned char iv[16] = {0};
321 size_t iv_length = sizeof( iv );
322 const unsigned char plaintext[16] = "Hello, world...";
323 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
324 size_t ciphertext_length = sizeof( ciphertext );
325 unsigned char decrypted[sizeof( ciphertext )];
326 size_t part_length;
327
328 if( usage & PSA_KEY_USAGE_ENCRYPT )
329 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100330 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
331 handle, alg ) );
332 PSA_ASSERT( psa_cipher_generate_iv( &operation,
333 iv, sizeof( iv ),
334 &iv_length ) );
335 PSA_ASSERT( psa_cipher_update( &operation,
336 plaintext, sizeof( plaintext ),
337 ciphertext, sizeof( ciphertext ),
338 &ciphertext_length ) );
339 PSA_ASSERT( psa_cipher_finish( &operation,
340 ciphertext + ciphertext_length,
341 sizeof( ciphertext ) - ciphertext_length,
342 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200343 ciphertext_length += part_length;
344 }
345
346 if( usage & PSA_KEY_USAGE_DECRYPT )
347 {
348 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200349 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200350 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
351 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200352 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
353 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
354 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
355 * have this macro yet. */
356 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
357 psa_get_key_type( &attributes ) );
358 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200359 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100360 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
361 handle, alg ) );
362 PSA_ASSERT( psa_cipher_set_iv( &operation,
363 iv, iv_length ) );
364 PSA_ASSERT( psa_cipher_update( &operation,
365 ciphertext, ciphertext_length,
366 decrypted, sizeof( decrypted ),
367 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200368 status = psa_cipher_finish( &operation,
369 decrypted + part_length,
370 sizeof( decrypted ) - part_length,
371 &part_length );
372 /* For a stream cipher, all inputs are valid. For a block cipher,
373 * if the input is some aribtrary data rather than an actual
374 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200375 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200376 TEST_ASSERT( status == PSA_SUCCESS ||
377 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200378 else
379 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200380 }
381
382 return( 1 );
383
384exit:
385 psa_cipher_abort( &operation );
386 return( 0 );
387}
388
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100389static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200390 psa_key_usage_t usage,
391 psa_algorithm_t alg )
392{
393 unsigned char nonce[16] = {0};
394 size_t nonce_length = sizeof( nonce );
395 unsigned char plaintext[16] = "Hello, world...";
396 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
397 size_t ciphertext_length = sizeof( ciphertext );
398 size_t plaintext_length = sizeof( ciphertext );
399
400 if( usage & PSA_KEY_USAGE_ENCRYPT )
401 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100402 PSA_ASSERT( psa_aead_encrypt( handle, alg,
403 nonce, nonce_length,
404 NULL, 0,
405 plaintext, sizeof( plaintext ),
406 ciphertext, sizeof( ciphertext ),
407 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200408 }
409
410 if( usage & PSA_KEY_USAGE_DECRYPT )
411 {
412 psa_status_t verify_status =
413 ( usage & PSA_KEY_USAGE_ENCRYPT ?
414 PSA_SUCCESS :
415 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100416 TEST_EQUAL( psa_aead_decrypt( handle, alg,
417 nonce, nonce_length,
418 NULL, 0,
419 ciphertext, ciphertext_length,
420 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100421 &plaintext_length ),
422 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200423 }
424
425 return( 1 );
426
427exit:
428 return( 0 );
429}
430
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100431static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200432 psa_key_usage_t usage,
433 psa_algorithm_t alg )
434{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200435 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
436 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200437 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200438 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100439 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
440
441 /* If the policy allows signing with any hash, just pick one. */
442 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
443 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100444#if defined(KNOWN_SUPPORTED_HASH_ALG)
445 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
446 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100447#else
448 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100449 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100450#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100451 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200452
453 if( usage & PSA_KEY_USAGE_SIGN )
454 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200455 /* Some algorithms require the payload to have the size of
456 * the hash encoded in the algorithm. Use this input size
457 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200458 if( hash_alg != 0 )
459 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100460 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
461 payload, payload_length,
462 signature, sizeof( signature ),
463 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200464 }
465
466 if( usage & PSA_KEY_USAGE_VERIFY )
467 {
468 psa_status_t verify_status =
469 ( usage & PSA_KEY_USAGE_SIGN ?
470 PSA_SUCCESS :
471 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100472 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
473 payload, payload_length,
474 signature, signature_length ),
475 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200476 }
477
478 return( 1 );
479
480exit:
481 return( 0 );
482}
483
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100484static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200485 psa_key_usage_t usage,
486 psa_algorithm_t alg )
487{
488 unsigned char plaintext[256] = "Hello, world...";
489 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
490 size_t ciphertext_length = sizeof( ciphertext );
491 size_t plaintext_length = 16;
492
493 if( usage & PSA_KEY_USAGE_ENCRYPT )
494 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100495 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
496 plaintext, plaintext_length,
497 NULL, 0,
498 ciphertext, sizeof( ciphertext ),
499 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200500 }
501
502 if( usage & PSA_KEY_USAGE_DECRYPT )
503 {
504 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100505 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200506 ciphertext, ciphertext_length,
507 NULL, 0,
508 plaintext, sizeof( plaintext ),
509 &plaintext_length );
510 TEST_ASSERT( status == PSA_SUCCESS ||
511 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
512 ( status == PSA_ERROR_INVALID_ARGUMENT ||
513 status == PSA_ERROR_INVALID_PADDING ) ) );
514 }
515
516 return( 1 );
517
518exit:
519 return( 0 );
520}
Gilles Peskine02b75072018-07-01 22:31:34 +0200521
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100522static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200523 psa_key_usage_t usage,
524 psa_algorithm_t alg )
525{
526 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
527 unsigned char label[16] = "This is a label.";
528 size_t label_length = sizeof( label );
529 unsigned char seed[16] = "abcdefghijklmnop";
530 size_t seed_length = sizeof( seed );
531 unsigned char output[1];
532
533 if( usage & PSA_KEY_USAGE_DERIVE )
534 {
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100535 if( PSA_ALG_IS_HKDF( alg ) )
536 {
537 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
538 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
539 PSA_KDF_STEP_SALT,
540 label,
541 label_length ) );
542 PSA_ASSERT( psa_key_derivation_input_key( &generator,
543 PSA_KDF_STEP_SECRET,
544 handle ) );
545 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
546 PSA_KDF_STEP_INFO,
547 seed,
548 seed_length ) );
549 }
550 else
551 {
552 // legacy
553 PSA_ASSERT( psa_key_derivation( &generator,
554 handle, alg,
555 label, label_length,
556 seed, seed_length,
557 sizeof( output ) ) );
558 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100559 PSA_ASSERT( psa_generator_read( &generator,
560 output,
561 sizeof( output ) ) );
562 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200563 }
564
565 return( 1 );
566
567exit:
568 return( 0 );
569}
570
Gilles Peskinec7998b72018-11-07 18:45:02 +0100571/* We need two keys to exercise key agreement. Exercise the
572 * private key against its own public key. */
573static psa_status_t key_agreement_with_self( psa_crypto_generator_t *generator,
Gilles Peskine969c5d62019-01-16 15:53:06 +0100574 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100575{
576 psa_key_type_t private_key_type;
577 psa_key_type_t public_key_type;
578 size_t key_bits;
579 uint8_t *public_key = NULL;
580 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200581 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinec7998b72018-11-07 18:45:02 +0100582 * psa_key_agreement fails. This isn't fully satisfactory, but it's
583 * good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200584 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200585 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100586
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200587 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
588 private_key_type = psa_get_key_type( &attributes );
589 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100590 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
591 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
592 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100593 PSA_ASSERT( psa_export_public_key( handle,
594 public_key, public_key_length,
595 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100596
Gilles Peskine969c5d62019-01-16 15:53:06 +0100597 status = psa_key_agreement( generator, PSA_KDF_STEP_SECRET, handle,
598 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100599exit:
600 mbedtls_free( public_key );
601 return( status );
602}
603
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200604/* We need two keys to exercise key agreement. Exercise the
605 * private key against its own public key. */
606static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
607 psa_key_handle_t handle )
608{
609 psa_key_type_t private_key_type;
610 psa_key_type_t public_key_type;
611 size_t key_bits;
612 uint8_t *public_key = NULL;
613 size_t public_key_length;
614 uint8_t output[1024];
615 size_t output_length;
616 /* Return GENERIC_ERROR if something other than the final call to
617 * psa_key_agreement fails. This isn't fully satisfactory, but it's
618 * good enough: callers will report it as a failed test anyway. */
619 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200620 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200621
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200622 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
623 private_key_type = psa_get_key_type( &attributes );
624 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200625 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
626 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
627 ASSERT_ALLOC( public_key, public_key_length );
628 PSA_ASSERT( psa_export_public_key( handle,
629 public_key, public_key_length,
630 &public_key_length ) );
631
632 status = psa_key_agreement_raw_shared_secret(
633 alg, handle,
634 public_key, public_key_length,
635 output, sizeof( output ), &output_length );
636exit:
637 mbedtls_free( public_key );
638 return( status );
639}
640
641static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
642 psa_key_usage_t usage,
643 psa_algorithm_t alg )
644{
645 int ok = 0;
646
647 if( usage & PSA_KEY_USAGE_DERIVE )
648 {
649 /* We need two keys to exercise key agreement. Exercise the
650 * private key against its own public key. */
651 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
652 }
653 ok = 1;
654
655exit:
656 return( ok );
657}
658
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100659static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200660 psa_key_usage_t usage,
661 psa_algorithm_t alg )
662{
663 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200664 unsigned char output[1];
665 int ok = 0;
666
667 if( usage & PSA_KEY_USAGE_DERIVE )
668 {
669 /* We need two keys to exercise key agreement. Exercise the
670 * private key against its own public key. */
Gilles Peskine969c5d62019-01-16 15:53:06 +0100671 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
672 PSA_ASSERT( key_agreement_with_self( &generator, handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +0100673 PSA_ASSERT( psa_generator_read( &generator,
674 output,
675 sizeof( output ) ) );
676 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200677 }
678 ok = 1;
679
680exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200681 return( ok );
682}
683
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200684static int is_oid_of_key_type( psa_key_type_t type,
685 const uint8_t *oid, size_t oid_length )
686{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200687 const uint8_t *expected_oid = NULL;
688 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200689#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200690 if( PSA_KEY_TYPE_IS_RSA( type ) )
691 {
692 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
693 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
694 }
695 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200696#endif /* MBEDTLS_RSA_C */
697#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200698 if( PSA_KEY_TYPE_IS_ECC( type ) )
699 {
700 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
701 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
702 }
703 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200704#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200705 {
706 char message[40];
707 mbedtls_snprintf( message, sizeof( message ),
708 "OID not known for key type=0x%08lx",
709 (unsigned long) type );
710 test_fail( message, __LINE__, __FILE__ );
711 return( 0 );
712 }
713
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200714 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200715 return( 1 );
716
717exit:
718 return( 0 );
719}
720
721static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
722 size_t min_bits, size_t max_bits,
723 int must_be_odd )
724{
725 size_t len;
726 size_t actual_bits;
727 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100728 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100729 MBEDTLS_ASN1_INTEGER ),
730 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200731 /* Tolerate a slight departure from DER encoding:
732 * - 0 may be represented by an empty string or a 1-byte string.
733 * - The sign bit may be used as a value bit. */
734 if( ( len == 1 && ( *p )[0] == 0 ) ||
735 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
736 {
737 ++( *p );
738 --len;
739 }
740 if( min_bits == 0 && len == 0 )
741 return( 1 );
742 msb = ( *p )[0];
743 TEST_ASSERT( msb != 0 );
744 actual_bits = 8 * ( len - 1 );
745 while( msb != 0 )
746 {
747 msb >>= 1;
748 ++actual_bits;
749 }
750 TEST_ASSERT( actual_bits >= min_bits );
751 TEST_ASSERT( actual_bits <= max_bits );
752 if( must_be_odd )
753 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
754 *p += len;
755 return( 1 );
756exit:
757 return( 0 );
758}
759
760static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
761 size_t *len,
762 unsigned char n, unsigned char tag )
763{
764 int ret;
765 ret = mbedtls_asn1_get_tag( p, end, len,
766 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
767 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
768 if( ret != 0 )
769 return( ret );
770 end = *p + *len;
771 ret = mbedtls_asn1_get_tag( p, end, len, tag );
772 if( ret != 0 )
773 return( ret );
774 if( *p + *len != end )
775 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
776 return( 0 );
777}
778
779static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
780 uint8_t *exported, size_t exported_length )
781{
782 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100783 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200784 else
785 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200786
787#if defined(MBEDTLS_DES_C)
788 if( type == PSA_KEY_TYPE_DES )
789 {
790 /* Check the parity bits. */
791 unsigned i;
792 for( i = 0; i < bits / 8; i++ )
793 {
794 unsigned bit_count = 0;
795 unsigned m;
796 for( m = 1; m <= 0x100; m <<= 1 )
797 {
798 if( exported[i] & m )
799 ++bit_count;
800 }
801 TEST_ASSERT( bit_count % 2 != 0 );
802 }
803 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200804 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200805#endif
806
807#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
808 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
809 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200810 uint8_t *p = exported;
811 uint8_t *end = exported + exported_length;
812 size_t len;
813 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200814 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200815 * modulus INTEGER, -- n
816 * publicExponent INTEGER, -- e
817 * privateExponent INTEGER, -- d
818 * prime1 INTEGER, -- p
819 * prime2 INTEGER, -- q
820 * exponent1 INTEGER, -- d mod (p-1)
821 * exponent2 INTEGER, -- d mod (q-1)
822 * coefficient INTEGER, -- (inverse of q) mod p
823 * }
824 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100825 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
826 MBEDTLS_ASN1_SEQUENCE |
827 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
828 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200829 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
830 goto exit;
831 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
832 goto exit;
833 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
834 goto exit;
835 /* Require d to be at least half the size of n. */
836 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
837 goto exit;
838 /* Require p and q to be at most half the size of n, rounded up. */
839 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
840 goto exit;
841 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
842 goto exit;
843 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
844 goto exit;
845 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
846 goto exit;
847 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
848 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100849 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100850 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200851 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200852#endif /* MBEDTLS_RSA_C */
853
854#if defined(MBEDTLS_ECP_C)
855 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
856 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100857 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100858 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100859 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200860 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200861#endif /* MBEDTLS_ECP_C */
862
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200863 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
864 {
865 uint8_t *p = exported;
866 uint8_t *end = exported + exported_length;
867 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200868#if defined(MBEDTLS_RSA_C)
869 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
870 {
871 /* RSAPublicKey ::= SEQUENCE {
872 * modulus INTEGER, -- n
873 * publicExponent INTEGER } -- e
874 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100875 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
876 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100877 MBEDTLS_ASN1_CONSTRUCTED ),
878 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100879 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200880 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
881 goto exit;
882 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
883 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100884 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200885 }
886 else
887#endif /* MBEDTLS_RSA_C */
888#if defined(MBEDTLS_ECP_C)
889 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
890 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000891 /* The representation of an ECC public key is:
892 * - The byte 0x04;
893 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
894 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
895 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000896 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100897 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
898 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200899 }
900 else
901#endif /* MBEDTLS_ECP_C */
902 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100903 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200904 mbedtls_snprintf( message, sizeof( message ),
905 "No sanity check for public key type=0x%08lx",
906 (unsigned long) type );
907 test_fail( message, __LINE__, __FILE__ );
908 return( 0 );
909 }
910 }
911 else
912
913 {
914 /* No sanity checks for other types */
915 }
916
917 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200918
919exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200920 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200921}
922
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100923static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200924 psa_key_usage_t usage )
925{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200926 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200927 uint8_t *exported = NULL;
928 size_t exported_size = 0;
929 size_t exported_length = 0;
930 int ok = 0;
931
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200932 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200933
934 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200935 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200936 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100937 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
938 PSA_ERROR_NOT_PERMITTED );
Gilles Peskined14664a2018-08-10 19:07:32 +0200939 return( 1 );
940 }
941
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200942 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
943 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200944 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200945
Gilles Peskine8817f612018-12-18 00:18:46 +0100946 PSA_ASSERT( psa_export_key( handle,
947 exported, exported_size,
948 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200949 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
950 psa_get_key_bits( &attributes ),
951 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200952
953exit:
954 mbedtls_free( exported );
955 return( ok );
956}
957
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100958static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200959{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200960 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200961 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200962 uint8_t *exported = NULL;
963 size_t exported_size = 0;
964 size_t exported_length = 0;
965 int ok = 0;
966
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
968 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200969 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100970 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100971 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200972 return( 1 );
973 }
974
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200975 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
976 psa_get_key_type( &attributes ) );
977 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
978 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200979 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200980
Gilles Peskine8817f612018-12-18 00:18:46 +0100981 PSA_ASSERT( psa_export_public_key( handle,
982 exported, exported_size,
983 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200984 ok = exported_key_sanity_check( public_type,
985 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200986 exported, exported_length );
987
988exit:
989 mbedtls_free( exported );
990 return( ok );
991}
992
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100993/** Do smoke tests on a key.
994 *
995 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
996 * sign/verify, or derivation) that is permitted according to \p usage.
997 * \p usage and \p alg should correspond to the expected policy on the
998 * key.
999 *
1000 * Export the key if permitted by \p usage, and check that the output
1001 * looks sensible. If \p usage forbids export, check that
1002 * \p psa_export_key correctly rejects the attempt. If the key is
1003 * asymmetric, also check \p psa_export_public_key.
1004 *
1005 * If the key fails the tests, this function calls the test framework's
1006 * `test_fail` function and returns false. Otherwise this function returns
1007 * true. Therefore it should be used as follows:
1008 * ```
1009 * if( ! exercise_key( ... ) ) goto exit;
1010 * ```
1011 *
1012 * \param handle The key to exercise. It should be capable of performing
1013 * \p alg.
1014 * \param usage The usage flags to assume.
1015 * \param alg The algorithm to exercise.
1016 *
1017 * \retval 0 The key failed the smoke tests.
1018 * \retval 1 The key passed the smoke tests.
1019 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001020static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001021 psa_key_usage_t usage,
1022 psa_algorithm_t alg )
1023{
1024 int ok;
1025 if( alg == 0 )
1026 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1027 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001029 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001030 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001031 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001032 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001033 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001034 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001035 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001036 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001037 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001038 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001039 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1040 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001041 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001042 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001043 else
1044 {
1045 char message[40];
1046 mbedtls_snprintf( message, sizeof( message ),
1047 "No code to exercise alg=0x%08lx",
1048 (unsigned long) alg );
1049 test_fail( message, __LINE__, __FILE__ );
1050 ok = 0;
1051 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001052
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001053 ok = ok && exercise_export_key( handle, usage );
1054 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001055
Gilles Peskine02b75072018-07-01 22:31:34 +02001056 return( ok );
1057}
1058
Gilles Peskine10df3412018-10-25 22:35:43 +02001059static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1060 psa_algorithm_t alg )
1061{
1062 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1063 {
1064 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1065 PSA_KEY_USAGE_VERIFY :
1066 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1067 }
1068 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1069 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1070 {
1071 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1072 PSA_KEY_USAGE_ENCRYPT :
1073 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1074 }
1075 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1076 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1077 {
1078 return( PSA_KEY_USAGE_DERIVE );
1079 }
1080 else
1081 {
1082 return( 0 );
1083 }
1084
1085}
Darryl Green0c6575a2018-11-07 16:05:30 +00001086
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001087static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1088{
1089 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1090 uint8_t buffer[1];
1091 size_t length;
1092 int ok = 0;
1093
1094 psa_make_key_persistent( &attributes, 0x6964, PSA_KEY_LIFETIME_PERSISTENT );
1095 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1096 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1097 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1098 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1099 PSA_ERROR_INVALID_HANDLE );
1100 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1101 TEST_EQUAL( psa_get_key_attributes_lifetime( &attributes ), 0 );
1102 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1103 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1104 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1105 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1106
1107 TEST_EQUAL( psa_export_key( handle,
1108 buffer, sizeof( buffer ), &length ),
1109 PSA_ERROR_INVALID_HANDLE );
1110 TEST_EQUAL( psa_export_public_key( handle,
1111 buffer, sizeof( buffer ), &length ),
1112 PSA_ERROR_INVALID_HANDLE );
1113
1114 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1115 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1116
1117 ok = 1;
1118
1119exit:
1120 psa_reset_key_attributes( &attributes );
1121 return( ok );
1122}
1123
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001124/* An overapproximation of the amount of storage needed for a key of the
1125 * given type and with the given content. The API doesn't make it easy
1126 * to find a good value for the size. The current implementation doesn't
1127 * care about the value anyway. */
1128#define KEY_BITS_FROM_DATA( type, data ) \
1129 ( data )->len
1130
Darryl Green0c6575a2018-11-07 16:05:30 +00001131typedef enum {
1132 IMPORT_KEY = 0,
1133 GENERATE_KEY = 1,
1134 DERIVE_KEY = 2
1135} generate_method;
1136
Gilles Peskinee59236f2018-01-27 23:32:46 +01001137/* END_HEADER */
1138
1139/* BEGIN_DEPENDENCIES
1140 * depends_on:MBEDTLS_PSA_CRYPTO_C
1141 * END_DEPENDENCIES
1142 */
1143
1144/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001145void static_checks( )
1146{
1147 size_t max_truncated_mac_size =
1148 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1149
1150 /* Check that the length for a truncated MAC always fits in the algorithm
1151 * encoding. The shifted mask is the maximum truncated value. The
1152 * untruncated algorithm may be one byte larger. */
1153 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1154}
1155/* END_CASE */
1156
1157/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001158void attributes_set_get( int id_arg, int lifetime_arg,
1159 int usage_flags_arg, int alg_arg,
1160 int type_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001161{
Gilles Peskine4747d192019-04-17 15:05:45 +02001162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001163 psa_key_id_t id = id_arg;
1164 psa_key_lifetime_t lifetime = lifetime_arg;
1165 psa_key_usage_t usage_flags = usage_flags_arg;
1166 psa_algorithm_t alg = alg_arg;
1167 psa_key_type_t type = type_arg;
1168
1169 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1170 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1171 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1172 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1173 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1174
1175 psa_make_key_persistent( &attributes, id, lifetime );
1176 psa_set_key_usage_flags( &attributes, usage_flags );
1177 psa_set_key_algorithm( &attributes, alg );
1178 psa_set_key_type( &attributes, type );
1179
1180 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1181 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1182 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1183 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1184 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1185
1186 psa_reset_key_attributes( &attributes );
1187
1188 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1189 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1190 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1191 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1192 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1193}
1194/* END_CASE */
1195
1196/* BEGIN_CASE */
1197void import( data_t *data, int type_arg, int expected_status_arg )
1198{
1199 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1200 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001201 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001202 psa_key_type_t type = type_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001203 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001204 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001205
Gilles Peskine8817f612018-12-18 00:18:46 +01001206 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001207
Gilles Peskine4747d192019-04-17 15:05:45 +02001208 psa_set_key_type( &attributes, type );
1209 status = psa_import_key( &attributes, &handle, data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001210 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001211 if( status != PSA_SUCCESS )
1212 goto exit;
1213
1214 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1215 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1216
1217 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001218 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001219
1220exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001221 psa_destroy_key( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001222 mbedtls_psa_crypto_free( );
1223}
1224/* END_CASE */
1225
1226/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001227void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1228{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001229 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001230 size_t bits = bits_arg;
1231 psa_status_t expected_status = expected_status_arg;
1232 psa_status_t status;
1233 psa_key_type_t type =
1234 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1235 size_t buffer_size = /* Slight overapproximations */
1236 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001237 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001238 unsigned char *p;
1239 int ret;
1240 size_t length;
1241
Gilles Peskine8817f612018-12-18 00:18:46 +01001242 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001243 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001244
1245 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1246 bits, keypair ) ) >= 0 );
1247 length = ret;
1248
1249 /* Try importing the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001250 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02001251 status = psa_import_key_to_handle( handle, type, p, length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001252 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001253 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001254 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001255
1256exit:
1257 mbedtls_free( buffer );
1258 mbedtls_psa_crypto_free( );
1259}
1260/* END_CASE */
1261
1262/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001263void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001264 int type_arg,
1265 int alg_arg,
1266 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001267 int expected_bits,
1268 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001269 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001270 int canonical_input )
1271{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001272 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001273 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001274 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001275 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001276 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001277 unsigned char *exported = NULL;
1278 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001279 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001280 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001281 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001282 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001283 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001284
Moran Pekercb088e72018-07-17 17:36:59 +03001285 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001286 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001287 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001288 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001289 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001290
Gilles Peskine4747d192019-04-17 15:05:45 +02001291 psa_set_key_usage_flags( &attributes, usage_arg );
1292 psa_set_key_algorithm( &attributes, alg );
1293 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001294
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001295 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001296 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001297
1298 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001299 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1300 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1301 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001302
1303 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001304 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001305 exported, export_size,
1306 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001307 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001308
1309 /* The exported length must be set by psa_export_key() to a value between 0
1310 * and export_size. On errors, the exported length must be 0. */
1311 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1312 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1313 TEST_ASSERT( exported_length <= export_size );
1314
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001315 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001316 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001318 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001319 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001320 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001321 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001322
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001323 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001324 goto exit;
1325
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001326 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001327 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001328 else
1329 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001330 psa_key_handle_t handle2;
Gilles Peskine4747d192019-04-17 15:05:45 +02001331 PSA_ASSERT( psa_import_key( &attributes, &handle2,
1332 exported, exported_length ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001333 PSA_ASSERT( psa_export_key( handle2,
1334 reexported,
1335 export_size,
1336 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001337 ASSERT_COMPARE( exported, exported_length,
1338 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001339 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001340 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001341 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001342
1343destroy:
1344 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001345 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001346 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001347
1348exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001349 mbedtls_free( exported );
1350 mbedtls_free( reexported );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001351 mbedtls_psa_crypto_free( );
1352}
1353/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001354
Moran Pekerf709f4a2018-06-06 17:26:04 +03001355/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001356void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001357{
Gilles Peskine8817f612018-12-18 00:18:46 +01001358 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001359 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001360
1361exit:
1362 mbedtls_psa_crypto_free( );
1363}
1364/* END_CASE */
1365
1366/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001367void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001368 int type_arg,
1369 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001370 int export_size_delta,
1371 int expected_export_status_arg,
1372 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001373{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001374 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001375 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001376 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001377 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001378 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001379 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001380 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001381 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001382 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001383
Gilles Peskine8817f612018-12-18 00:18:46 +01001384 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001385
Gilles Peskine4747d192019-04-17 15:05:45 +02001386 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1387 psa_set_key_algorithm( &attributes, alg );
1388 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001389
1390 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001391 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001392
Gilles Peskine49c25912018-10-29 15:15:31 +01001393 /* Export the public key */
1394 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001395 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001396 exported, export_size,
1397 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001398 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001399 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001400 {
1401 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1402 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001403 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1404 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001405 TEST_ASSERT( expected_public_key->len <=
1406 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001407 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1408 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001409 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001410
1411exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001412 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001413 psa_destroy_key( handle );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001414 mbedtls_psa_crypto_free( );
1415}
1416/* END_CASE */
1417
Gilles Peskine20035e32018-02-03 22:44:14 +01001418/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001419void import_and_exercise_key( data_t *data,
1420 int type_arg,
1421 int bits_arg,
1422 int alg_arg )
1423{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001424 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001425 psa_key_type_t type = type_arg;
1426 size_t bits = bits_arg;
1427 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001428 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001429 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001430 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001431
Gilles Peskine8817f612018-12-18 00:18:46 +01001432 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001433
Gilles Peskine4747d192019-04-17 15:05:45 +02001434 psa_set_key_usage_flags( &attributes, usage );
1435 psa_set_key_algorithm( &attributes, alg );
1436 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001437
1438 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001439 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001440
1441 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001442 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1443 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1444 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001445
1446 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001447 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001448 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001449
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001450 PSA_ASSERT( psa_destroy_key( handle ) );
1451 test_operations_on_invalid_handle( handle );
1452
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001453exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001454 psa_destroy_key( handle );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001455 mbedtls_psa_crypto_free( );
1456}
1457/* END_CASE */
1458
1459/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001460void key_policy( int usage_arg, int alg_arg )
1461{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001462 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001463 psa_algorithm_t alg = alg_arg;
1464 psa_key_usage_t usage = usage_arg;
1465 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1466 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001467 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001468
1469 memset( key, 0x2a, sizeof( key ) );
1470
Gilles Peskine8817f612018-12-18 00:18:46 +01001471 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001472
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001473 psa_set_key_usage_flags( &attributes, usage );
1474 psa_set_key_algorithm( &attributes, alg );
1475 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001476
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001477 PSA_ASSERT( psa_import_key( &attributes, &handle, key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001478
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001479 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1480 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1481 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1482 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001483
1484exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001485 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001486 mbedtls_psa_crypto_free( );
1487}
1488/* END_CASE */
1489
1490/* BEGIN_CASE */
Jaeden Amero70261c52019-01-04 11:47:20 +00001491void key_policy_init( )
1492{
1493 /* Test each valid way of initializing the object, except for `= {0}`, as
1494 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1495 * though it's OK by the C standard. We could test for this, but we'd need
1496 * to supress the Clang warning for the test. */
1497 psa_key_policy_t func = psa_key_policy_init( );
1498 psa_key_policy_t init = PSA_KEY_POLICY_INIT;
1499 psa_key_policy_t zero;
1500
1501 memset( &zero, 0, sizeof( zero ) );
1502
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001503 /* A default key policy should not permit any usage. */
1504 TEST_EQUAL( psa_key_policy_get_usage( &func ), 0 );
1505 TEST_EQUAL( psa_key_policy_get_usage( &init ), 0 );
1506 TEST_EQUAL( psa_key_policy_get_usage( &zero ), 0 );
1507
1508 /* A default key policy should not permit any algorithm. */
1509 TEST_EQUAL( psa_key_policy_get_algorithm( &func ), 0 );
1510 TEST_EQUAL( psa_key_policy_get_algorithm( &init ), 0 );
1511 TEST_EQUAL( psa_key_policy_get_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001512}
1513/* END_CASE */
1514
1515/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001516void mac_key_policy( int policy_usage,
1517 int policy_alg,
1518 int key_type,
1519 data_t *key_data,
1520 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001521{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001522 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001523 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001524 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001525 psa_status_t status;
1526 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001527
Gilles Peskine8817f612018-12-18 00:18:46 +01001528 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001529
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001530 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001531 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001532 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001533
Gilles Peskine87a5e562019-04-17 12:28:25 +02001534 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001535 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001536
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001537 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001538 if( policy_alg == exercise_alg &&
1539 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001540 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001541 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001542 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001543 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001544
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001545 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001546 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001547 if( policy_alg == exercise_alg &&
1548 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001549 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001550 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001551 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001552
1553exit:
1554 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001555 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001556 mbedtls_psa_crypto_free( );
1557}
1558/* END_CASE */
1559
1560/* BEGIN_CASE */
1561void cipher_key_policy( int policy_usage,
1562 int policy_alg,
1563 int key_type,
1564 data_t *key_data,
1565 int exercise_alg )
1566{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001567 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001568 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001569 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001570 psa_status_t status;
1571
Gilles Peskine8817f612018-12-18 00:18:46 +01001572 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001573
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001574 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001575 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001576 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001577
Gilles Peskine87a5e562019-04-17 12:28:25 +02001578 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001579 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001580
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001581 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001582 if( policy_alg == exercise_alg &&
1583 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001584 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001585 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001586 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001587 psa_cipher_abort( &operation );
1588
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001589 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001590 if( policy_alg == exercise_alg &&
1591 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001592 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001593 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001594 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001595
1596exit:
1597 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001598 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001599 mbedtls_psa_crypto_free( );
1600}
1601/* END_CASE */
1602
1603/* BEGIN_CASE */
1604void aead_key_policy( int policy_usage,
1605 int policy_alg,
1606 int key_type,
1607 data_t *key_data,
1608 int nonce_length_arg,
1609 int tag_length_arg,
1610 int exercise_alg )
1611{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001612 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001613 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001614 psa_status_t status;
1615 unsigned char nonce[16] = {0};
1616 size_t nonce_length = nonce_length_arg;
1617 unsigned char tag[16];
1618 size_t tag_length = tag_length_arg;
1619 size_t output_length;
1620
1621 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1622 TEST_ASSERT( tag_length <= sizeof( tag ) );
1623
Gilles Peskine8817f612018-12-18 00:18:46 +01001624 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001625
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001626 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001627 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001628 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001629
Gilles Peskine87a5e562019-04-17 12:28:25 +02001630 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001631 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001632
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001633 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001634 nonce, nonce_length,
1635 NULL, 0,
1636 NULL, 0,
1637 tag, tag_length,
1638 &output_length );
1639 if( policy_alg == exercise_alg &&
1640 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001641 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001642 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001643 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001644
1645 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001646 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001647 nonce, nonce_length,
1648 NULL, 0,
1649 tag, tag_length,
1650 NULL, 0,
1651 &output_length );
1652 if( policy_alg == exercise_alg &&
1653 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001654 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001655 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001656 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001657
1658exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001659 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001660 mbedtls_psa_crypto_free( );
1661}
1662/* END_CASE */
1663
1664/* BEGIN_CASE */
1665void asymmetric_encryption_key_policy( int policy_usage,
1666 int policy_alg,
1667 int key_type,
1668 data_t *key_data,
1669 int exercise_alg )
1670{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001671 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001672 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001673 psa_status_t status;
1674 size_t key_bits;
1675 size_t buffer_length;
1676 unsigned char *buffer = NULL;
1677 size_t output_length;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001678 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001679
Gilles Peskine8817f612018-12-18 00:18:46 +01001680 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001681
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001682 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001683 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001684 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001685
Gilles Peskine87a5e562019-04-17 12:28:25 +02001686 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001687 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001688
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001689 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1690 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001691 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1692 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001693 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001694
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001695 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001696 NULL, 0,
1697 NULL, 0,
1698 buffer, buffer_length,
1699 &output_length );
1700 if( policy_alg == exercise_alg &&
1701 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001702 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001703 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001704 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001706 if( buffer_length != 0 )
1707 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001708 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001709 buffer, buffer_length,
1710 NULL, 0,
1711 buffer, buffer_length,
1712 &output_length );
1713 if( policy_alg == exercise_alg &&
1714 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001715 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001717 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001718
1719exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001720 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001721 mbedtls_psa_crypto_free( );
1722 mbedtls_free( buffer );
1723}
1724/* END_CASE */
1725
1726/* BEGIN_CASE */
1727void asymmetric_signature_key_policy( int policy_usage,
1728 int policy_alg,
1729 int key_type,
1730 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001731 int exercise_alg,
1732 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001733{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001734 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001735 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001736 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001737 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1738 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1739 * compatible with the policy and `payload_length_arg` is supposed to be
1740 * a valid input length to sign. If `payload_length_arg <= 0`,
1741 * `exercise_alg` is supposed to be forbidden by the policy. */
1742 int compatible_alg = payload_length_arg > 0;
1743 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001744 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1745 size_t signature_length;
1746
Gilles Peskine8817f612018-12-18 00:18:46 +01001747 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001749 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001750 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001751 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001752
Gilles Peskine87a5e562019-04-17 12:28:25 +02001753 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001754 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001755
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001756 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001757 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758 signature, sizeof( signature ),
1759 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001760 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001761 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001763 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001764
1765 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001766 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001768 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001769 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001770 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001771 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001772 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001773
1774exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001775 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001776 mbedtls_psa_crypto_free( );
1777}
1778/* END_CASE */
1779
1780/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001781void derive_key_policy( int policy_usage,
1782 int policy_alg,
1783 int key_type,
1784 data_t *key_data,
1785 int exercise_alg )
1786{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001787 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001788 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001789 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1790 psa_status_t status;
1791
Gilles Peskine8817f612018-12-18 00:18:46 +01001792 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001793
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001794 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001795 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001796 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001797
Gilles Peskine87a5e562019-04-17 12:28:25 +02001798 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001799 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001800
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001801 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001802 exercise_alg,
1803 NULL, 0,
1804 NULL, 0,
1805 1 );
1806 if( policy_alg == exercise_alg &&
1807 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001808 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001809 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001810 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001811
1812exit:
1813 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001814 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001815 mbedtls_psa_crypto_free( );
1816}
1817/* END_CASE */
1818
1819/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001820void agreement_key_policy( int policy_usage,
1821 int policy_alg,
1822 int key_type_arg,
1823 data_t *key_data,
1824 int exercise_alg )
1825{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001826 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001827 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001828 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001829 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1830 psa_status_t status;
1831
Gilles Peskine8817f612018-12-18 00:18:46 +01001832 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001833
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001834 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001835 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001836 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001837
Gilles Peskine87a5e562019-04-17 12:28:25 +02001838 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001839 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001840
Gilles Peskine969c5d62019-01-16 15:53:06 +01001841 PSA_ASSERT( psa_key_derivation_setup( &generator, exercise_alg ) );
1842 status = key_agreement_with_self( &generator, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001843
Gilles Peskine01d718c2018-09-18 12:01:02 +02001844 if( policy_alg == exercise_alg &&
1845 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001846 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001847 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001848 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001849
1850exit:
1851 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001852 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001853 mbedtls_psa_crypto_free( );
1854}
1855/* END_CASE */
1856
1857/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001858void raw_agreement_key_policy( int policy_usage,
1859 int policy_alg,
1860 int key_type_arg,
1861 data_t *key_data,
1862 int exercise_alg )
1863{
1864 psa_key_handle_t handle = 0;
1865 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
1866 psa_key_type_t key_type = key_type_arg;
1867 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1868 psa_status_t status;
1869
1870 PSA_ASSERT( psa_crypto_init( ) );
1871
1872 PSA_ASSERT( psa_allocate_key( &handle ) );
1873 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
1874 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
1875
Gilles Peskine87a5e562019-04-17 12:28:25 +02001876 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001877 key_data->x, key_data->len ) );
1878
1879 status = raw_key_agreement_with_self( exercise_alg, handle );
1880
1881 if( policy_alg == exercise_alg &&
1882 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1883 PSA_ASSERT( status );
1884 else
1885 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1886
1887exit:
1888 psa_generator_abort( &generator );
1889 psa_destroy_key( handle );
1890 mbedtls_psa_crypto_free( );
1891}
1892/* END_CASE */
1893
1894/* BEGIN_CASE */
Gilles Peskineca25db92019-04-19 11:43:08 +02001895void copy_key( int source_usage_arg, int source_alg_arg,
1896 int type_arg, data_t *material,
1897 int copy_attributes,
1898 int target_usage_arg, int target_alg_arg,
1899 int expected_status_arg,
1900 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001901{
Gilles Peskineca25db92019-04-19 11:43:08 +02001902 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1903 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001904 psa_key_usage_t expected_usage = expected_usage_arg;
1905 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001906 psa_key_handle_t source_handle = 0;
1907 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001908 uint8_t *export_buffer = NULL;
1909
Gilles Peskine57ab7212019-01-28 13:03:09 +01001910 PSA_ASSERT( psa_crypto_init( ) );
1911
Gilles Peskineca25db92019-04-19 11:43:08 +02001912 /* Prepare the source key. */
1913 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1914 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1915 psa_set_key_type( &source_attributes, type_arg );
1916 PSA_ASSERT( psa_import_key( &source_attributes, &source_handle,
Gilles Peskine57ab7212019-01-28 13:03:09 +01001917 material->x, material->len ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001918 /* Retrieve the key size. */
1919 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001920
Gilles Peskineca25db92019-04-19 11:43:08 +02001921 /* Prepare the target attributes. */
1922 if( copy_attributes )
1923 target_attributes = source_attributes;
1924 if( target_usage_arg != -1 )
1925 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1926 if( target_alg_arg != -1 )
1927 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001928
1929 /* Copy the key. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001930 TEST_EQUAL( psa_copy_key( source_handle,
1931 &target_attributes, &target_handle ),
1932 expected_status_arg );
1933 if( expected_status_arg != PSA_SUCCESS )
1934 {
1935 TEST_EQUAL( target_handle, 0 );
1936 goto exit;
1937 }
Gilles Peskine57ab7212019-01-28 13:03:09 +01001938
1939 /* Destroy the source to ensure that this doesn't affect the target. */
1940 PSA_ASSERT( psa_destroy_key( source_handle ) );
1941
1942 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001943 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1944 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1945 psa_get_key_type( &target_attributes ) );
1946 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1947 psa_get_key_bits( &target_attributes ) );
1948 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
1949 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001950 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1951 {
1952 size_t length;
1953 ASSERT_ALLOC( export_buffer, material->len );
1954 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1955 material->len, &length ) );
1956 ASSERT_COMPARE( material->x, material->len,
1957 export_buffer, length );
1958 }
1959 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1960 goto exit;
1961
1962 PSA_ASSERT( psa_close_key( target_handle ) );
1963
1964exit:
1965 mbedtls_psa_crypto_free( );
1966 mbedtls_free( export_buffer );
1967}
1968/* END_CASE */
1969
1970/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00001971void hash_operation_init( )
1972{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00001973 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00001974 /* Test each valid way of initializing the object, except for `= {0}`, as
1975 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1976 * though it's OK by the C standard. We could test for this, but we'd need
1977 * to supress the Clang warning for the test. */
1978 psa_hash_operation_t func = psa_hash_operation_init( );
1979 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
1980 psa_hash_operation_t zero;
1981
1982 memset( &zero, 0, sizeof( zero ) );
1983
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00001984 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00001985 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
1986 PSA_ERROR_BAD_STATE );
1987 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
1988 PSA_ERROR_BAD_STATE );
1989 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
1990 PSA_ERROR_BAD_STATE );
1991
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001992 /* A default hash operation should be abortable without error. */
1993 PSA_ASSERT( psa_hash_abort( &func ) );
1994 PSA_ASSERT( psa_hash_abort( &init ) );
1995 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00001996}
1997/* END_CASE */
1998
1999/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002000void hash_setup( int alg_arg,
2001 int expected_status_arg )
2002{
2003 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002004 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002005 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002006 psa_status_t status;
2007
Gilles Peskine8817f612018-12-18 00:18:46 +01002008 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002009
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002010 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002011 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002012
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002013 /* Whether setup succeeded or failed, abort must succeed. */
2014 PSA_ASSERT( psa_hash_abort( &operation ) );
2015
2016 /* If setup failed, reproduce the failure, so as to
2017 * test the resulting state of the operation object. */
2018 if( status != PSA_SUCCESS )
2019 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2020
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002021 /* Now the operation object should be reusable. */
2022#if defined(KNOWN_SUPPORTED_HASH_ALG)
2023 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2024 PSA_ASSERT( psa_hash_abort( &operation ) );
2025#endif
2026
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002027exit:
2028 mbedtls_psa_crypto_free( );
2029}
2030/* END_CASE */
2031
2032/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002033void hash_bad_order( )
2034{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002035 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002036 unsigned char input[] = "";
2037 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002038 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002039 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2040 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2041 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002042 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002043 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002044 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002045
Gilles Peskine8817f612018-12-18 00:18:46 +01002046 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002047
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002048 /* Call setup twice in a row. */
2049 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2050 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2051 PSA_ERROR_BAD_STATE );
2052 PSA_ASSERT( psa_hash_abort( &operation ) );
2053
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002054 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002055 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002056 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002057 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002058
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002059 /* Call update after finish. */
2060 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2061 PSA_ASSERT( psa_hash_finish( &operation,
2062 hash, sizeof( hash ), &hash_len ) );
2063 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002064 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002065 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002066
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002067 /* Call verify without calling setup beforehand. */
2068 TEST_EQUAL( psa_hash_verify( &operation,
2069 valid_hash, sizeof( valid_hash ) ),
2070 PSA_ERROR_BAD_STATE );
2071 PSA_ASSERT( psa_hash_abort( &operation ) );
2072
2073 /* Call verify after finish. */
2074 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2075 PSA_ASSERT( psa_hash_finish( &operation,
2076 hash, sizeof( hash ), &hash_len ) );
2077 TEST_EQUAL( psa_hash_verify( &operation,
2078 valid_hash, sizeof( valid_hash ) ),
2079 PSA_ERROR_BAD_STATE );
2080 PSA_ASSERT( psa_hash_abort( &operation ) );
2081
2082 /* Call verify twice in a row. */
2083 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2084 PSA_ASSERT( psa_hash_verify( &operation,
2085 valid_hash, sizeof( valid_hash ) ) );
2086 TEST_EQUAL( psa_hash_verify( &operation,
2087 valid_hash, sizeof( valid_hash ) ),
2088 PSA_ERROR_BAD_STATE );
2089 PSA_ASSERT( psa_hash_abort( &operation ) );
2090
2091 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002092 TEST_EQUAL( psa_hash_finish( &operation,
2093 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002094 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002095 PSA_ASSERT( psa_hash_abort( &operation ) );
2096
2097 /* Call finish twice in a row. */
2098 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2099 PSA_ASSERT( psa_hash_finish( &operation,
2100 hash, sizeof( hash ), &hash_len ) );
2101 TEST_EQUAL( psa_hash_finish( &operation,
2102 hash, sizeof( hash ), &hash_len ),
2103 PSA_ERROR_BAD_STATE );
2104 PSA_ASSERT( psa_hash_abort( &operation ) );
2105
2106 /* Call finish after calling verify. */
2107 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2108 PSA_ASSERT( psa_hash_verify( &operation,
2109 valid_hash, sizeof( valid_hash ) ) );
2110 TEST_EQUAL( psa_hash_finish( &operation,
2111 hash, sizeof( hash ), &hash_len ),
2112 PSA_ERROR_BAD_STATE );
2113 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002114
2115exit:
2116 mbedtls_psa_crypto_free( );
2117}
2118/* END_CASE */
2119
itayzafrir27e69452018-11-01 14:26:34 +02002120/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2121void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002122{
2123 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002124 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2125 * appended to it */
2126 unsigned char hash[] = {
2127 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2128 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2129 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002130 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002131 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002132
Gilles Peskine8817f612018-12-18 00:18:46 +01002133 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002134
itayzafrir27e69452018-11-01 14:26:34 +02002135 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002136 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002137 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002138 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002139
itayzafrir27e69452018-11-01 14:26:34 +02002140 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002141 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002142 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002143 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002144
itayzafrir27e69452018-11-01 14:26:34 +02002145 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002146 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002147 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002148 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002149
itayzafrirec93d302018-10-18 18:01:10 +03002150exit:
2151 mbedtls_psa_crypto_free( );
2152}
2153/* END_CASE */
2154
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002155/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2156void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002157{
2158 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002159 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002160 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002161 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002162 size_t hash_len;
2163
Gilles Peskine8817f612018-12-18 00:18:46 +01002164 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002165
itayzafrir58028322018-10-25 10:22:01 +03002166 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002167 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002168 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002169 hash, expected_size - 1, &hash_len ),
2170 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002171
2172exit:
2173 mbedtls_psa_crypto_free( );
2174}
2175/* END_CASE */
2176
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002177/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2178void hash_clone_source_state( )
2179{
2180 psa_algorithm_t alg = PSA_ALG_SHA_256;
2181 unsigned char hash[PSA_HASH_MAX_SIZE];
2182 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2183 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2184 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2185 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2186 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2187 size_t hash_len;
2188
2189 PSA_ASSERT( psa_crypto_init( ) );
2190 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2191
2192 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2193 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2194 PSA_ASSERT( psa_hash_finish( &op_finished,
2195 hash, sizeof( hash ), &hash_len ) );
2196 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2197 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2198
2199 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2200 PSA_ERROR_BAD_STATE );
2201
2202 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2203 PSA_ASSERT( psa_hash_finish( &op_init,
2204 hash, sizeof( hash ), &hash_len ) );
2205 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2206 PSA_ASSERT( psa_hash_finish( &op_finished,
2207 hash, sizeof( hash ), &hash_len ) );
2208 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2209 PSA_ASSERT( psa_hash_finish( &op_aborted,
2210 hash, sizeof( hash ), &hash_len ) );
2211
2212exit:
2213 psa_hash_abort( &op_source );
2214 psa_hash_abort( &op_init );
2215 psa_hash_abort( &op_setup );
2216 psa_hash_abort( &op_finished );
2217 psa_hash_abort( &op_aborted );
2218 mbedtls_psa_crypto_free( );
2219}
2220/* END_CASE */
2221
2222/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2223void hash_clone_target_state( )
2224{
2225 psa_algorithm_t alg = PSA_ALG_SHA_256;
2226 unsigned char hash[PSA_HASH_MAX_SIZE];
2227 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2228 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2229 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2230 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2231 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2232 size_t hash_len;
2233
2234 PSA_ASSERT( psa_crypto_init( ) );
2235
2236 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2237 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2238 PSA_ASSERT( psa_hash_finish( &op_finished,
2239 hash, sizeof( hash ), &hash_len ) );
2240 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2241 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2242
2243 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2244 PSA_ASSERT( psa_hash_finish( &op_target,
2245 hash, sizeof( hash ), &hash_len ) );
2246
2247 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2248 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2249 PSA_ERROR_BAD_STATE );
2250 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2251 PSA_ERROR_BAD_STATE );
2252
2253exit:
2254 psa_hash_abort( &op_target );
2255 psa_hash_abort( &op_init );
2256 psa_hash_abort( &op_setup );
2257 psa_hash_abort( &op_finished );
2258 psa_hash_abort( &op_aborted );
2259 mbedtls_psa_crypto_free( );
2260}
2261/* END_CASE */
2262
itayzafrir58028322018-10-25 10:22:01 +03002263/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002264void mac_operation_init( )
2265{
Jaeden Amero252ef282019-02-15 14:05:35 +00002266 const uint8_t input[1] = { 0 };
2267
Jaeden Amero769ce272019-01-04 11:48:03 +00002268 /* Test each valid way of initializing the object, except for `= {0}`, as
2269 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2270 * though it's OK by the C standard. We could test for this, but we'd need
2271 * to supress the Clang warning for the test. */
2272 psa_mac_operation_t func = psa_mac_operation_init( );
2273 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2274 psa_mac_operation_t zero;
2275
2276 memset( &zero, 0, sizeof( zero ) );
2277
Jaeden Amero252ef282019-02-15 14:05:35 +00002278 /* A freshly-initialized MAC operation should not be usable. */
2279 TEST_EQUAL( psa_mac_update( &func,
2280 input, sizeof( input ) ),
2281 PSA_ERROR_BAD_STATE );
2282 TEST_EQUAL( psa_mac_update( &init,
2283 input, sizeof( input ) ),
2284 PSA_ERROR_BAD_STATE );
2285 TEST_EQUAL( psa_mac_update( &zero,
2286 input, sizeof( input ) ),
2287 PSA_ERROR_BAD_STATE );
2288
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002289 /* A default MAC operation should be abortable without error. */
2290 PSA_ASSERT( psa_mac_abort( &func ) );
2291 PSA_ASSERT( psa_mac_abort( &init ) );
2292 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002293}
2294/* END_CASE */
2295
2296/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002297void mac_setup( int key_type_arg,
2298 data_t *key,
2299 int alg_arg,
2300 int expected_status_arg )
2301{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002302 psa_key_type_t key_type = key_type_arg;
2303 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002304 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002305 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002306 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2307#if defined(KNOWN_SUPPORTED_MAC_ALG)
2308 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2309#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002310
Gilles Peskine8817f612018-12-18 00:18:46 +01002311 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002312
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002313 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2314 &operation, &status ) )
2315 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002316 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002317
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002318 /* The operation object should be reusable. */
2319#if defined(KNOWN_SUPPORTED_MAC_ALG)
2320 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2321 smoke_test_key_data,
2322 sizeof( smoke_test_key_data ),
2323 KNOWN_SUPPORTED_MAC_ALG,
2324 &operation, &status ) )
2325 goto exit;
2326 TEST_EQUAL( status, PSA_SUCCESS );
2327#endif
2328
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002329exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002330 mbedtls_psa_crypto_free( );
2331}
2332/* END_CASE */
2333
2334/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002335void mac_bad_order( )
2336{
2337 psa_key_handle_t handle = 0;
2338 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2339 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2340 const uint8_t key[] = {
2341 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2342 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2343 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
2344 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2345 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2346 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2347 size_t sign_mac_length = 0;
2348 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2349 const uint8_t verify_mac[] = {
2350 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2351 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2352 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2353
2354 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir3e02b3b2018-06-12 17:06:52 +03002355 PSA_ASSERT( psa_allocate_key( &handle ) );
2356 psa_key_policy_set_usage( &policy,
2357 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002358 alg );
2359 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2360
Gilles Peskine87a5e562019-04-17 12:28:25 +02002361 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Jaeden Amero252ef282019-02-15 14:05:35 +00002362 key, sizeof(key) ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002363
Jaeden Amero252ef282019-02-15 14:05:35 +00002364 /* Call update without calling setup beforehand. */
2365 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2366 PSA_ERROR_BAD_STATE );
2367 PSA_ASSERT( psa_mac_abort( &operation ) );
2368
2369 /* Call sign finish without calling setup beforehand. */
2370 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2371 &sign_mac_length),
2372 PSA_ERROR_BAD_STATE );
2373 PSA_ASSERT( psa_mac_abort( &operation ) );
2374
2375 /* Call verify finish without calling setup beforehand. */
2376 TEST_EQUAL( psa_mac_verify_finish( &operation,
2377 verify_mac, sizeof( verify_mac ) ),
2378 PSA_ERROR_BAD_STATE );
2379 PSA_ASSERT( psa_mac_abort( &operation ) );
2380
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002381 /* Call setup twice in a row. */
2382 PSA_ASSERT( psa_mac_sign_setup( &operation,
2383 handle, alg ) );
2384 TEST_EQUAL( psa_mac_sign_setup( &operation,
2385 handle, alg ),
2386 PSA_ERROR_BAD_STATE );
2387 PSA_ASSERT( psa_mac_abort( &operation ) );
2388
Jaeden Amero252ef282019-02-15 14:05:35 +00002389 /* Call update after sign finish. */
2390 PSA_ASSERT( psa_mac_sign_setup( &operation,
2391 handle, alg ) );
2392 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2393 PSA_ASSERT( psa_mac_sign_finish( &operation,
2394 sign_mac, sizeof( sign_mac ),
2395 &sign_mac_length ) );
2396 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2397 PSA_ERROR_BAD_STATE );
2398 PSA_ASSERT( psa_mac_abort( &operation ) );
2399
2400 /* Call update after verify finish. */
2401 PSA_ASSERT( psa_mac_verify_setup( &operation,
2402 handle, alg ) );
2403 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2404 PSA_ASSERT( psa_mac_verify_finish( &operation,
2405 verify_mac, sizeof( verify_mac ) ) );
2406 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2407 PSA_ERROR_BAD_STATE );
2408 PSA_ASSERT( psa_mac_abort( &operation ) );
2409
2410 /* Call sign finish twice in a row. */
2411 PSA_ASSERT( psa_mac_sign_setup( &operation,
2412 handle, alg ) );
2413 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2414 PSA_ASSERT( psa_mac_sign_finish( &operation,
2415 sign_mac, sizeof( sign_mac ),
2416 &sign_mac_length ) );
2417 TEST_EQUAL( psa_mac_sign_finish( &operation,
2418 sign_mac, sizeof( sign_mac ),
2419 &sign_mac_length ),
2420 PSA_ERROR_BAD_STATE );
2421 PSA_ASSERT( psa_mac_abort( &operation ) );
2422
2423 /* Call verify finish twice in a row. */
2424 PSA_ASSERT( psa_mac_verify_setup( &operation,
2425 handle, alg ) );
2426 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2427 PSA_ASSERT( psa_mac_verify_finish( &operation,
2428 verify_mac, sizeof( verify_mac ) ) );
2429 TEST_EQUAL( psa_mac_verify_finish( &operation,
2430 verify_mac, sizeof( verify_mac ) ),
2431 PSA_ERROR_BAD_STATE );
2432 PSA_ASSERT( psa_mac_abort( &operation ) );
2433
2434 /* Setup sign but try verify. */
2435 PSA_ASSERT( psa_mac_sign_setup( &operation,
2436 handle, alg ) );
2437 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2438 TEST_EQUAL( psa_mac_verify_finish( &operation,
2439 verify_mac, sizeof( verify_mac ) ),
2440 PSA_ERROR_BAD_STATE );
2441 PSA_ASSERT( psa_mac_abort( &operation ) );
2442
2443 /* Setup verify but try sign. */
2444 PSA_ASSERT( psa_mac_verify_setup( &operation,
2445 handle, alg ) );
2446 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2447 TEST_EQUAL( psa_mac_sign_finish( &operation,
2448 sign_mac, sizeof( sign_mac ),
2449 &sign_mac_length ),
2450 PSA_ERROR_BAD_STATE );
2451 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002452
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002453exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002454 mbedtls_psa_crypto_free( );
2455}
2456/* END_CASE */
2457
2458/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002459void mac_sign( int key_type_arg,
2460 data_t *key,
2461 int alg_arg,
2462 data_t *input,
2463 data_t *expected_mac )
2464{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002465 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002466 psa_key_type_t key_type = key_type_arg;
2467 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002468 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002469 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002470 /* Leave a little extra room in the output buffer. At the end of the
2471 * test, we'll check that the implementation didn't overwrite onto
2472 * this extra room. */
2473 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2474 size_t mac_buffer_size =
2475 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2476 size_t mac_length = 0;
2477
2478 memset( actual_mac, '+', sizeof( actual_mac ) );
2479 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2480 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2481
Gilles Peskine8817f612018-12-18 00:18:46 +01002482 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002483
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002484 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002485 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002486 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002487
Gilles Peskine87a5e562019-04-17 12:28:25 +02002488 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002489 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002490
2491 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002492 PSA_ASSERT( psa_mac_sign_setup( &operation,
2493 handle, alg ) );
2494 PSA_ASSERT( psa_mac_update( &operation,
2495 input->x, input->len ) );
2496 PSA_ASSERT( psa_mac_sign_finish( &operation,
2497 actual_mac, mac_buffer_size,
2498 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002499
2500 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002501 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2502 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002503
2504 /* Verify that the end of the buffer is untouched. */
2505 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2506 sizeof( actual_mac ) - mac_length ) );
2507
2508exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002509 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002510 mbedtls_psa_crypto_free( );
2511}
2512/* END_CASE */
2513
2514/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002515void mac_verify( int key_type_arg,
2516 data_t *key,
2517 int alg_arg,
2518 data_t *input,
2519 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002520{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002521 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002522 psa_key_type_t key_type = key_type_arg;
2523 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002524 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002525 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002526
Gilles Peskine69c12672018-06-28 00:07:19 +02002527 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2528
Gilles Peskine8817f612018-12-18 00:18:46 +01002529 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002530
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002531 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002532 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002533 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad16036df908f2018-04-02 08:34:15 -07002534
Gilles Peskine87a5e562019-04-17 12:28:25 +02002535 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002536 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002537
Gilles Peskine8817f612018-12-18 00:18:46 +01002538 PSA_ASSERT( psa_mac_verify_setup( &operation,
2539 handle, alg ) );
2540 PSA_ASSERT( psa_destroy_key( handle ) );
2541 PSA_ASSERT( psa_mac_update( &operation,
2542 input->x, input->len ) );
2543 PSA_ASSERT( psa_mac_verify_finish( &operation,
2544 expected_mac->x,
2545 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002546
2547exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002548 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002549 mbedtls_psa_crypto_free( );
2550}
2551/* END_CASE */
2552
2553/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002554void cipher_operation_init( )
2555{
Jaeden Ameroab439972019-02-15 14:12:05 +00002556 const uint8_t input[1] = { 0 };
2557 unsigned char output[1] = { 0 };
2558 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002559 /* Test each valid way of initializing the object, except for `= {0}`, as
2560 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2561 * though it's OK by the C standard. We could test for this, but we'd need
2562 * to supress the Clang warning for the test. */
2563 psa_cipher_operation_t func = psa_cipher_operation_init( );
2564 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2565 psa_cipher_operation_t zero;
2566
2567 memset( &zero, 0, sizeof( zero ) );
2568
Jaeden Ameroab439972019-02-15 14:12:05 +00002569 /* A freshly-initialized cipher operation should not be usable. */
2570 TEST_EQUAL( psa_cipher_update( &func,
2571 input, sizeof( input ),
2572 output, sizeof( output ),
2573 &output_length ),
2574 PSA_ERROR_BAD_STATE );
2575 TEST_EQUAL( psa_cipher_update( &init,
2576 input, sizeof( input ),
2577 output, sizeof( output ),
2578 &output_length ),
2579 PSA_ERROR_BAD_STATE );
2580 TEST_EQUAL( psa_cipher_update( &zero,
2581 input, sizeof( input ),
2582 output, sizeof( output ),
2583 &output_length ),
2584 PSA_ERROR_BAD_STATE );
2585
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002586 /* A default cipher operation should be abortable without error. */
2587 PSA_ASSERT( psa_cipher_abort( &func ) );
2588 PSA_ASSERT( psa_cipher_abort( &init ) );
2589 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002590}
2591/* END_CASE */
2592
2593/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002594void cipher_setup( int key_type_arg,
2595 data_t *key,
2596 int alg_arg,
2597 int expected_status_arg )
2598{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002599 psa_key_type_t key_type = key_type_arg;
2600 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002601 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002602 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002603 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002604#if defined(KNOWN_SUPPORTED_MAC_ALG)
2605 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2606#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002607
Gilles Peskine8817f612018-12-18 00:18:46 +01002608 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002609
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002610 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2611 &operation, &status ) )
2612 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002613 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002614
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002615 /* The operation object should be reusable. */
2616#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2617 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2618 smoke_test_key_data,
2619 sizeof( smoke_test_key_data ),
2620 KNOWN_SUPPORTED_CIPHER_ALG,
2621 &operation, &status ) )
2622 goto exit;
2623 TEST_EQUAL( status, PSA_SUCCESS );
2624#endif
2625
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002626exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002627 mbedtls_psa_crypto_free( );
2628}
2629/* END_CASE */
2630
2631/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002632void cipher_bad_order( )
2633{
2634 psa_key_handle_t handle = 0;
2635 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2636 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
2637 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2638 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2639 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2640 const uint8_t key[] = {
2641 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2642 0xaa, 0xaa, 0xaa, 0xaa };
2643 const uint8_t text[] = {
2644 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2645 0xbb, 0xbb, 0xbb, 0xbb };
2646 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2647 size_t length = 0;
2648
2649 PSA_ASSERT( psa_crypto_init( ) );
2650 PSA_ASSERT( psa_allocate_key( &handle ) );
2651 psa_key_policy_set_usage( &policy,
2652 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
2653 alg );
2654 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02002655 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Jaeden Ameroab439972019-02-15 14:12:05 +00002656 key, sizeof(key) ) );
2657
2658
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002659 /* Call encrypt setup twice in a row. */
2660 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2661 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2662 PSA_ERROR_BAD_STATE );
2663 PSA_ASSERT( psa_cipher_abort( &operation ) );
2664
2665 /* Call decrypt setup twice in a row. */
2666 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2667 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2668 PSA_ERROR_BAD_STATE );
2669 PSA_ASSERT( psa_cipher_abort( &operation ) );
2670
Jaeden Ameroab439972019-02-15 14:12:05 +00002671 /* Generate an IV without calling setup beforehand. */
2672 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2673 buffer, sizeof( buffer ),
2674 &length ),
2675 PSA_ERROR_BAD_STATE );
2676 PSA_ASSERT( psa_cipher_abort( &operation ) );
2677
2678 /* Generate an IV twice in a row. */
2679 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2680 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2681 buffer, sizeof( buffer ),
2682 &length ) );
2683 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2684 buffer, sizeof( buffer ),
2685 &length ),
2686 PSA_ERROR_BAD_STATE );
2687 PSA_ASSERT( psa_cipher_abort( &operation ) );
2688
2689 /* Generate an IV after it's already set. */
2690 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2691 PSA_ASSERT( psa_cipher_set_iv( &operation,
2692 iv, sizeof( iv ) ) );
2693 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2694 buffer, sizeof( buffer ),
2695 &length ),
2696 PSA_ERROR_BAD_STATE );
2697 PSA_ASSERT( psa_cipher_abort( &operation ) );
2698
2699 /* Set an IV without calling setup beforehand. */
2700 TEST_EQUAL( psa_cipher_set_iv( &operation,
2701 iv, sizeof( iv ) ),
2702 PSA_ERROR_BAD_STATE );
2703 PSA_ASSERT( psa_cipher_abort( &operation ) );
2704
2705 /* Set an IV after it's already set. */
2706 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2707 PSA_ASSERT( psa_cipher_set_iv( &operation,
2708 iv, sizeof( iv ) ) );
2709 TEST_EQUAL( psa_cipher_set_iv( &operation,
2710 iv, sizeof( iv ) ),
2711 PSA_ERROR_BAD_STATE );
2712 PSA_ASSERT( psa_cipher_abort( &operation ) );
2713
2714 /* Set an IV after it's already generated. */
2715 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2716 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2717 buffer, sizeof( buffer ),
2718 &length ) );
2719 TEST_EQUAL( psa_cipher_set_iv( &operation,
2720 iv, sizeof( iv ) ),
2721 PSA_ERROR_BAD_STATE );
2722 PSA_ASSERT( psa_cipher_abort( &operation ) );
2723
2724 /* Call update without calling setup beforehand. */
2725 TEST_EQUAL( psa_cipher_update( &operation,
2726 text, sizeof( text ),
2727 buffer, sizeof( buffer ),
2728 &length ),
2729 PSA_ERROR_BAD_STATE );
2730 PSA_ASSERT( psa_cipher_abort( &operation ) );
2731
2732 /* Call update without an IV where an IV is required. */
2733 TEST_EQUAL( psa_cipher_update( &operation,
2734 text, sizeof( text ),
2735 buffer, sizeof( buffer ),
2736 &length ),
2737 PSA_ERROR_BAD_STATE );
2738 PSA_ASSERT( psa_cipher_abort( &operation ) );
2739
2740 /* Call update after finish. */
2741 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2742 PSA_ASSERT( psa_cipher_set_iv( &operation,
2743 iv, sizeof( iv ) ) );
2744 PSA_ASSERT( psa_cipher_finish( &operation,
2745 buffer, sizeof( buffer ), &length ) );
2746 TEST_EQUAL( psa_cipher_update( &operation,
2747 text, sizeof( text ),
2748 buffer, sizeof( buffer ),
2749 &length ),
2750 PSA_ERROR_BAD_STATE );
2751 PSA_ASSERT( psa_cipher_abort( &operation ) );
2752
2753 /* Call finish without calling setup beforehand. */
2754 TEST_EQUAL( psa_cipher_finish( &operation,
2755 buffer, sizeof( buffer ), &length ),
2756 PSA_ERROR_BAD_STATE );
2757 PSA_ASSERT( psa_cipher_abort( &operation ) );
2758
2759 /* Call finish without an IV where an IV is required. */
2760 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2761 /* Not calling update means we are encrypting an empty buffer, which is OK
2762 * for cipher modes with padding. */
2763 TEST_EQUAL( psa_cipher_finish( &operation,
2764 buffer, sizeof( buffer ), &length ),
2765 PSA_ERROR_BAD_STATE );
2766 PSA_ASSERT( psa_cipher_abort( &operation ) );
2767
2768 /* Call finish twice in a row. */
2769 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2770 PSA_ASSERT( psa_cipher_set_iv( &operation,
2771 iv, sizeof( iv ) ) );
2772 PSA_ASSERT( psa_cipher_finish( &operation,
2773 buffer, sizeof( buffer ), &length ) );
2774 TEST_EQUAL( psa_cipher_finish( &operation,
2775 buffer, sizeof( buffer ), &length ),
2776 PSA_ERROR_BAD_STATE );
2777 PSA_ASSERT( psa_cipher_abort( &operation ) );
2778
2779exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002780 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002781}
2782/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002783
Gilles Peskine50e586b2018-06-08 14:28:46 +02002784/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002785void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002786 data_t *key,
2787 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002788 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002789{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002790 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002791 psa_status_t status;
2792 psa_key_type_t key_type = key_type_arg;
2793 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002794 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002795 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002796 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002797 unsigned char *output = NULL;
2798 size_t output_buffer_size = 0;
2799 size_t function_output_length = 0;
2800 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002801 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002802 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002803
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002804 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2805 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002806
Gilles Peskine8817f612018-12-18 00:18:46 +01002807 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002808
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002809 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002810 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002811 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002812
Gilles Peskine87a5e562019-04-17 12:28:25 +02002813 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002814 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002815
Gilles Peskine8817f612018-12-18 00:18:46 +01002816 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2817 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002818
Gilles Peskine8817f612018-12-18 00:18:46 +01002819 PSA_ASSERT( psa_cipher_set_iv( &operation,
2820 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002821 output_buffer_size = ( (size_t) input->len +
2822 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002823 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002824
Gilles Peskine8817f612018-12-18 00:18:46 +01002825 PSA_ASSERT( psa_cipher_update( &operation,
2826 input->x, input->len,
2827 output, output_buffer_size,
2828 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002829 total_output_length += function_output_length;
2830 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002831 output + total_output_length,
2832 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002833 &function_output_length );
2834 total_output_length += function_output_length;
2835
Gilles Peskinefe11b722018-12-18 00:24:04 +01002836 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002837 if( expected_status == PSA_SUCCESS )
2838 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002839 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002840 ASSERT_COMPARE( expected_output->x, expected_output->len,
2841 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002842 }
2843
2844exit:
2845 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002846 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002847 mbedtls_psa_crypto_free( );
2848}
2849/* END_CASE */
2850
2851/* BEGIN_CASE */
2852void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
2853 data_t *key,
2854 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002855 int first_part_size_arg,
2856 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002857 data_t *expected_output )
2858{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002859 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002860 psa_key_type_t key_type = key_type_arg;
2861 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002862 size_t first_part_size = first_part_size_arg;
2863 size_t output1_length = output1_length_arg;
2864 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002865 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002866 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002867 unsigned char *output = NULL;
2868 size_t output_buffer_size = 0;
2869 size_t function_output_length = 0;
2870 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002871 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002872 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002873
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002874 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2875 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002876
Gilles Peskine8817f612018-12-18 00:18:46 +01002877 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002878
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002879 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002880 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002881 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002882
Gilles Peskine87a5e562019-04-17 12:28:25 +02002883 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002884 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002885
Gilles Peskine8817f612018-12-18 00:18:46 +01002886 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2887 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002888
Gilles Peskine8817f612018-12-18 00:18:46 +01002889 PSA_ASSERT( psa_cipher_set_iv( &operation,
2890 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002891 output_buffer_size = ( (size_t) input->len +
2892 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002893 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002894
Gilles Peskinee0866522019-02-19 19:44:00 +01002895 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002896 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2897 output, output_buffer_size,
2898 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002899 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002900 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002901 PSA_ASSERT( psa_cipher_update( &operation,
2902 input->x + first_part_size,
2903 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002904 output + total_output_length,
2905 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002906 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002907 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002908 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002909 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002910 output + total_output_length,
2911 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002912 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002913 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002914 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002915
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002916 ASSERT_COMPARE( expected_output->x, expected_output->len,
2917 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002918
2919exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002920 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002921 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002922 mbedtls_psa_crypto_free( );
2923}
2924/* END_CASE */
2925
2926/* BEGIN_CASE */
2927void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002928 data_t *key,
2929 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002930 int first_part_size_arg,
2931 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002932 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002934 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002935
2936 psa_key_type_t key_type = key_type_arg;
2937 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002938 size_t first_part_size = first_part_size_arg;
2939 size_t output1_length = output1_length_arg;
2940 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002941 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002942 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002943 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002944 size_t output_buffer_size = 0;
2945 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002946 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002947 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002948 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002949
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002950 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2951 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952
Gilles Peskine8817f612018-12-18 00:18:46 +01002953 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002954
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002955 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002956 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002957 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002958
Gilles Peskine87a5e562019-04-17 12:28:25 +02002959 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002960 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002961
Gilles Peskine8817f612018-12-18 00:18:46 +01002962 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
2963 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002964
Gilles Peskine8817f612018-12-18 00:18:46 +01002965 PSA_ASSERT( psa_cipher_set_iv( &operation,
2966 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002967
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002968 output_buffer_size = ( (size_t) input->len +
2969 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002970 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002971
Gilles Peskinee0866522019-02-19 19:44:00 +01002972 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002973 PSA_ASSERT( psa_cipher_update( &operation,
2974 input->x, first_part_size,
2975 output, output_buffer_size,
2976 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002977 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002978 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002979 PSA_ASSERT( psa_cipher_update( &operation,
2980 input->x + first_part_size,
2981 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002982 output + total_output_length,
2983 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002984 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002985 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002986 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002987 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002988 output + total_output_length,
2989 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002990 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002991 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002992 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002993
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002994 ASSERT_COMPARE( expected_output->x, expected_output->len,
2995 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002996
2997exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002998 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002999 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003000 mbedtls_psa_crypto_free( );
3001}
3002/* END_CASE */
3003
Gilles Peskine50e586b2018-06-08 14:28:46 +02003004/* BEGIN_CASE */
3005void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003006 data_t *key,
3007 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003008 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003009{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003010 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003011 psa_status_t status;
3012 psa_key_type_t key_type = key_type_arg;
3013 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003014 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003015 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003016 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003017 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003018 size_t output_buffer_size = 0;
3019 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003020 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003021 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003022 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003023
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003024 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3025 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003026
Gilles Peskine8817f612018-12-18 00:18:46 +01003027 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003028
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003029 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003030 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003031 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003032
Gilles Peskine87a5e562019-04-17 12:28:25 +02003033 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003034 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003035
Gilles Peskine8817f612018-12-18 00:18:46 +01003036 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3037 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003038
Gilles Peskine8817f612018-12-18 00:18:46 +01003039 PSA_ASSERT( psa_cipher_set_iv( &operation,
3040 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003042 output_buffer_size = ( (size_t) input->len +
3043 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003044 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003045
Gilles Peskine8817f612018-12-18 00:18:46 +01003046 PSA_ASSERT( psa_cipher_update( &operation,
3047 input->x, input->len,
3048 output, output_buffer_size,
3049 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003050 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003051 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003052 output + total_output_length,
3053 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003054 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003055 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003056 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003057
3058 if( expected_status == PSA_SUCCESS )
3059 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003060 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003061 ASSERT_COMPARE( expected_output->x, expected_output->len,
3062 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003063 }
3064
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003066 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003067 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003068 mbedtls_psa_crypto_free( );
3069}
3070/* END_CASE */
3071
Gilles Peskine50e586b2018-06-08 14:28:46 +02003072/* BEGIN_CASE */
3073void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003074 data_t *key,
3075 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003076{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003077 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003078 psa_key_type_t key_type = key_type_arg;
3079 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003080 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003081 size_t iv_size = 16;
3082 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003083 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003084 size_t output1_size = 0;
3085 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003086 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003087 size_t output2_size = 0;
3088 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003089 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003090 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3091 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003092 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003093
Gilles Peskine8817f612018-12-18 00:18:46 +01003094 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003095
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003096 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003097 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003098 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003099
Gilles Peskine87a5e562019-04-17 12:28:25 +02003100 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003101 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003102
Gilles Peskine8817f612018-12-18 00:18:46 +01003103 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3104 handle, alg ) );
3105 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3106 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003107
Gilles Peskine8817f612018-12-18 00:18:46 +01003108 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3109 iv, iv_size,
3110 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003111 output1_size = ( (size_t) input->len +
3112 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003113 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003114
Gilles Peskine8817f612018-12-18 00:18:46 +01003115 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3116 output1, output1_size,
3117 &output1_length ) );
3118 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003119 output1 + output1_length,
3120 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003121 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003122
Gilles Peskine048b7f02018-06-08 14:20:49 +02003123 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003124
Gilles Peskine8817f612018-12-18 00:18:46 +01003125 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003126
3127 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003128 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003129
Gilles Peskine8817f612018-12-18 00:18:46 +01003130 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3131 iv, iv_length ) );
3132 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3133 output2, output2_size,
3134 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003135 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003136 PSA_ASSERT( psa_cipher_finish( &operation2,
3137 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003138 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003139 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003140
Gilles Peskine048b7f02018-06-08 14:20:49 +02003141 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003142
Gilles Peskine8817f612018-12-18 00:18:46 +01003143 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003144
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003145 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003146
3147exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003148 mbedtls_free( output1 );
3149 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003150 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003151 mbedtls_psa_crypto_free( );
3152}
3153/* END_CASE */
3154
3155/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003156void cipher_verify_output_multipart( int alg_arg,
3157 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003158 data_t *key,
3159 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003160 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003161{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003162 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003163 psa_key_type_t key_type = key_type_arg;
3164 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003165 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003166 unsigned char iv[16] = {0};
3167 size_t iv_size = 16;
3168 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003169 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003170 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003171 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003172 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003173 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003174 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003175 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003176 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3177 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003178 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003179
Gilles Peskine8817f612018-12-18 00:18:46 +01003180 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003181
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003182 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003183 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003184 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003185
Gilles Peskine87a5e562019-04-17 12:28:25 +02003186 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003187 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003188
Gilles Peskine8817f612018-12-18 00:18:46 +01003189 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3190 handle, alg ) );
3191 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3192 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003193
Gilles Peskine8817f612018-12-18 00:18:46 +01003194 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3195 iv, iv_size,
3196 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003197 output1_buffer_size = ( (size_t) input->len +
3198 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003199 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003200
Gilles Peskinee0866522019-02-19 19:44:00 +01003201 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003202
Gilles Peskine8817f612018-12-18 00:18:46 +01003203 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3204 output1, output1_buffer_size,
3205 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003206 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003207
Gilles Peskine8817f612018-12-18 00:18:46 +01003208 PSA_ASSERT( psa_cipher_update( &operation1,
3209 input->x + first_part_size,
3210 input->len - first_part_size,
3211 output1, output1_buffer_size,
3212 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003213 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003214
Gilles Peskine8817f612018-12-18 00:18:46 +01003215 PSA_ASSERT( psa_cipher_finish( &operation1,
3216 output1 + output1_length,
3217 output1_buffer_size - output1_length,
3218 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003219 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003220
Gilles Peskine8817f612018-12-18 00:18:46 +01003221 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003222
Gilles Peskine048b7f02018-06-08 14:20:49 +02003223 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003224 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003225
Gilles Peskine8817f612018-12-18 00:18:46 +01003226 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3227 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003228
Gilles Peskine8817f612018-12-18 00:18:46 +01003229 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3230 output2, output2_buffer_size,
3231 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003232 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003233
Gilles Peskine8817f612018-12-18 00:18:46 +01003234 PSA_ASSERT( psa_cipher_update( &operation2,
3235 output1 + first_part_size,
3236 output1_length - first_part_size,
3237 output2, output2_buffer_size,
3238 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003239 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003240
Gilles Peskine8817f612018-12-18 00:18:46 +01003241 PSA_ASSERT( psa_cipher_finish( &operation2,
3242 output2 + output2_length,
3243 output2_buffer_size - output2_length,
3244 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003245 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003246
Gilles Peskine8817f612018-12-18 00:18:46 +01003247 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003248
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003249 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003250
3251exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003252 mbedtls_free( output1 );
3253 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003254 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003255 mbedtls_psa_crypto_free( );
3256}
3257/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003258
Gilles Peskine20035e32018-02-03 22:44:14 +01003259/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003260void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003261 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003262 data_t *nonce,
3263 data_t *additional_data,
3264 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003265 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003266{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003267 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003268 psa_key_type_t key_type = key_type_arg;
3269 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003270 unsigned char *output_data = NULL;
3271 size_t output_size = 0;
3272 size_t output_length = 0;
3273 unsigned char *output_data2 = NULL;
3274 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003275 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003276 psa_status_t expected_result = expected_result_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003277 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003278
Gilles Peskine4abf7412018-06-18 16:35:34 +02003279 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003280 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003281
Gilles Peskine8817f612018-12-18 00:18:46 +01003282 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003283
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003284 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003285 psa_key_policy_set_usage( &policy,
3286 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
3287 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003288 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003289
Gilles Peskine87a5e562019-04-17 12:28:25 +02003290 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003291 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003292
Gilles Peskinefe11b722018-12-18 00:24:04 +01003293 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3294 nonce->x, nonce->len,
3295 additional_data->x,
3296 additional_data->len,
3297 input_data->x, input_data->len,
3298 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003299 &output_length ),
3300 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003301
3302 if( PSA_SUCCESS == expected_result )
3303 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003304 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003305
Gilles Peskinefe11b722018-12-18 00:24:04 +01003306 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3307 nonce->x, nonce->len,
3308 additional_data->x,
3309 additional_data->len,
3310 output_data, output_length,
3311 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003312 &output_length2 ),
3313 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003314
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003315 ASSERT_COMPARE( input_data->x, input_data->len,
3316 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003317 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003318
Gilles Peskinea1cac842018-06-11 19:33:02 +02003319exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003320 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003321 mbedtls_free( output_data );
3322 mbedtls_free( output_data2 );
3323 mbedtls_psa_crypto_free( );
3324}
3325/* END_CASE */
3326
3327/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003328void aead_encrypt( int key_type_arg, data_t *key_data,
3329 int alg_arg,
3330 data_t *nonce,
3331 data_t *additional_data,
3332 data_t *input_data,
3333 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003334{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003335 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003336 psa_key_type_t key_type = key_type_arg;
3337 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003338 unsigned char *output_data = NULL;
3339 size_t output_size = 0;
3340 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003341 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003342 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003343
Gilles Peskine4abf7412018-06-18 16:35:34 +02003344 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003345 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003346
Gilles Peskine8817f612018-12-18 00:18:46 +01003347 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003348
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003349 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003350 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003351 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003352
Gilles Peskine87a5e562019-04-17 12:28:25 +02003353 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003354 key_data->x,
3355 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003356
Gilles Peskine8817f612018-12-18 00:18:46 +01003357 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3358 nonce->x, nonce->len,
3359 additional_data->x, additional_data->len,
3360 input_data->x, input_data->len,
3361 output_data, output_size,
3362 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003363
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003364 ASSERT_COMPARE( expected_result->x, expected_result->len,
3365 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003366
Gilles Peskinea1cac842018-06-11 19:33:02 +02003367exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003368 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003369 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003370 mbedtls_psa_crypto_free( );
3371}
3372/* END_CASE */
3373
3374/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003375void aead_decrypt( int key_type_arg, data_t *key_data,
3376 int alg_arg,
3377 data_t *nonce,
3378 data_t *additional_data,
3379 data_t *input_data,
3380 data_t *expected_data,
3381 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003382{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003383 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003384 psa_key_type_t key_type = key_type_arg;
3385 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003386 unsigned char *output_data = NULL;
3387 size_t output_size = 0;
3388 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003389 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003390 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003391 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003392
Gilles Peskine4abf7412018-06-18 16:35:34 +02003393 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003394 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003395
Gilles Peskine8817f612018-12-18 00:18:46 +01003396 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003397
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003398 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003399 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003400 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003401
Gilles Peskine87a5e562019-04-17 12:28:25 +02003402 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003403 key_data->x,
3404 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003405
Gilles Peskinefe11b722018-12-18 00:24:04 +01003406 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3407 nonce->x, nonce->len,
3408 additional_data->x,
3409 additional_data->len,
3410 input_data->x, input_data->len,
3411 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003412 &output_length ),
3413 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003414
Gilles Peskine2d277862018-06-18 15:41:12 +02003415 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003416 ASSERT_COMPARE( expected_data->x, expected_data->len,
3417 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418
Gilles Peskinea1cac842018-06-11 19:33:02 +02003419exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003420 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003422 mbedtls_psa_crypto_free( );
3423}
3424/* END_CASE */
3425
3426/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003427void signature_size( int type_arg,
3428 int bits,
3429 int alg_arg,
3430 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003431{
3432 psa_key_type_t type = type_arg;
3433 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003434 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003435 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003436exit:
3437 ;
3438}
3439/* END_CASE */
3440
3441/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003442void sign_deterministic( int key_type_arg, data_t *key_data,
3443 int alg_arg, data_t *input_data,
3444 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003445{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003446 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003447 psa_key_type_t key_type = key_type_arg;
3448 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003449 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003450 unsigned char *signature = NULL;
3451 size_t signature_size;
3452 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003453 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003454 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003455
Gilles Peskine8817f612018-12-18 00:18:46 +01003456 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003457
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003458 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003459 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003460 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003461
Gilles Peskine87a5e562019-04-17 12:28:25 +02003462 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003463 key_data->x,
3464 key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003465 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3466 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003467
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003468 /* Allocate a buffer which has the size advertized by the
3469 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003470 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3471 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003472 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003473 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003474 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003475
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003476 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003477 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3478 input_data->x, input_data->len,
3479 signature, signature_size,
3480 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003481 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003482 ASSERT_COMPARE( output_data->x, output_data->len,
3483 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003484
3485exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003486 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003487 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003488 mbedtls_psa_crypto_free( );
3489}
3490/* END_CASE */
3491
3492/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003493void sign_fail( int key_type_arg, data_t *key_data,
3494 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003495 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003496{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003497 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003498 psa_key_type_t key_type = key_type_arg;
3499 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003500 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003501 psa_status_t actual_status;
3502 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003503 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003504 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003505 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003506
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003507 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003508
Gilles Peskine8817f612018-12-18 00:18:46 +01003509 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003510
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003511 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003512 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003513 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003514
Gilles Peskine87a5e562019-04-17 12:28:25 +02003515 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003516 key_data->x,
3517 key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003518
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003519 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003520 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003521 signature, signature_size,
3522 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003523 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003524 /* The value of *signature_length is unspecified on error, but
3525 * whatever it is, it should be less than signature_size, so that
3526 * if the caller tries to read *signature_length bytes without
3527 * checking the error code then they don't overflow a buffer. */
3528 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003529
3530exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003531 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003532 mbedtls_free( signature );
3533 mbedtls_psa_crypto_free( );
3534}
3535/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003536
3537/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003538void sign_verify( int key_type_arg, data_t *key_data,
3539 int alg_arg, data_t *input_data )
3540{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003541 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003542 psa_key_type_t key_type = key_type_arg;
3543 psa_algorithm_t alg = alg_arg;
3544 size_t key_bits;
3545 unsigned char *signature = NULL;
3546 size_t signature_size;
3547 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003548 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003549 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003550
Gilles Peskine8817f612018-12-18 00:18:46 +01003551 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003552
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003553 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003554 psa_key_policy_set_usage( &policy,
3555 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
3556 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003557 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003558
Gilles Peskine87a5e562019-04-17 12:28:25 +02003559 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003560 key_data->x,
3561 key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003562 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3563 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003564
3565 /* Allocate a buffer which has the size advertized by the
3566 * library. */
3567 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3568 key_bits, alg );
3569 TEST_ASSERT( signature_size != 0 );
3570 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003571 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003572
3573 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003574 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3575 input_data->x, input_data->len,
3576 signature, signature_size,
3577 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003578 /* Check that the signature length looks sensible. */
3579 TEST_ASSERT( signature_length <= signature_size );
3580 TEST_ASSERT( signature_length > 0 );
3581
3582 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003583 PSA_ASSERT( psa_asymmetric_verify(
3584 handle, alg,
3585 input_data->x, input_data->len,
3586 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003587
3588 if( input_data->len != 0 )
3589 {
3590 /* Flip a bit in the input and verify that the signature is now
3591 * detected as invalid. Flip a bit at the beginning, not at the end,
3592 * because ECDSA may ignore the last few bits of the input. */
3593 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003594 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3595 input_data->x, input_data->len,
3596 signature, signature_length ),
3597 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003598 }
3599
3600exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003601 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003602 mbedtls_free( signature );
3603 mbedtls_psa_crypto_free( );
3604}
3605/* END_CASE */
3606
3607/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003608void asymmetric_verify( int key_type_arg, data_t *key_data,
3609 int alg_arg, data_t *hash_data,
3610 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003611{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003612 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003613 psa_key_type_t key_type = key_type_arg;
3614 psa_algorithm_t alg = alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003615 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003616
Gilles Peskine69c12672018-06-28 00:07:19 +02003617 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3618
Gilles Peskine8817f612018-12-18 00:18:46 +01003619 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003620
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003621 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003622 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003623 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
itayzafrir5c753392018-05-08 11:18:38 +03003624
Gilles Peskine87a5e562019-04-17 12:28:25 +02003625 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003626 key_data->x,
3627 key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003628
Gilles Peskine8817f612018-12-18 00:18:46 +01003629 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3630 hash_data->x, hash_data->len,
3631 signature_data->x,
3632 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003633exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003634 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003635 mbedtls_psa_crypto_free( );
3636}
3637/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003638
3639/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003640void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3641 int alg_arg, data_t *hash_data,
3642 data_t *signature_data,
3643 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003644{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003645 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003646 psa_key_type_t key_type = key_type_arg;
3647 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003648 psa_status_t actual_status;
3649 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003650 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003651
Gilles Peskine8817f612018-12-18 00:18:46 +01003652 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003653
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003654 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003655 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003656 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003657
Gilles Peskine87a5e562019-04-17 12:28:25 +02003658 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003659 key_data->x,
3660 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003661
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003662 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003663 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003664 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003665 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003666
Gilles Peskinefe11b722018-12-18 00:24:04 +01003667 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003668
3669exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003670 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003671 mbedtls_psa_crypto_free( );
3672}
3673/* END_CASE */
3674
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003675/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003676void asymmetric_encrypt( int key_type_arg,
3677 data_t *key_data,
3678 int alg_arg,
3679 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003680 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003681 int expected_output_length_arg,
3682 int expected_status_arg )
3683{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003684 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003685 psa_key_type_t key_type = key_type_arg;
3686 psa_algorithm_t alg = alg_arg;
3687 size_t expected_output_length = expected_output_length_arg;
3688 size_t key_bits;
3689 unsigned char *output = NULL;
3690 size_t output_size;
3691 size_t output_length = ~0;
3692 psa_status_t actual_status;
3693 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003694 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003695 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003696
Gilles Peskine8817f612018-12-18 00:18:46 +01003697 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003698
Gilles Peskine656896e2018-06-29 19:12:28 +02003699 /* Import the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003700 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003701 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003702 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02003703 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003704 key_data->x,
3705 key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003706
3707 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003708 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3709 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003710 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003711 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003712
3713 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003714 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003715 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003716 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003717 output, output_size,
3718 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003719 TEST_EQUAL( actual_status, expected_status );
3720 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003721
Gilles Peskine68428122018-06-30 18:42:41 +02003722 /* If the label is empty, the test framework puts a non-null pointer
3723 * in label->x. Test that a null pointer works as well. */
3724 if( label->len == 0 )
3725 {
3726 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003727 if( output_size != 0 )
3728 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003729 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003730 input_data->x, input_data->len,
3731 NULL, label->len,
3732 output, output_size,
3733 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003734 TEST_EQUAL( actual_status, expected_status );
3735 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003736 }
3737
Gilles Peskine656896e2018-06-29 19:12:28 +02003738exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003739 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003740 mbedtls_free( output );
3741 mbedtls_psa_crypto_free( );
3742}
3743/* END_CASE */
3744
3745/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003746void asymmetric_encrypt_decrypt( int key_type_arg,
3747 data_t *key_data,
3748 int alg_arg,
3749 data_t *input_data,
3750 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003751{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003752 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003753 psa_key_type_t key_type = key_type_arg;
3754 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003755 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003756 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003757 size_t output_size;
3758 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003759 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003760 size_t output2_size;
3761 size_t output2_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003762 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003763 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003764
Gilles Peskine8817f612018-12-18 00:18:46 +01003765 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003766
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003767 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003768 psa_key_policy_set_usage( &policy,
3769 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003770 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003771 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003772
Gilles Peskine87a5e562019-04-17 12:28:25 +02003773 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003774 key_data->x,
3775 key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003776
3777 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003778 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3779 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003780 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003781 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003782 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003783 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003784
Gilles Peskineeebd7382018-06-08 18:11:54 +02003785 /* We test encryption by checking that encrypt-then-decrypt gives back
3786 * the original plaintext because of the non-optional random
3787 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003788 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3789 input_data->x, input_data->len,
3790 label->x, label->len,
3791 output, output_size,
3792 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003793 /* We don't know what ciphertext length to expect, but check that
3794 * it looks sensible. */
3795 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003796
Gilles Peskine8817f612018-12-18 00:18:46 +01003797 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3798 output, output_length,
3799 label->x, label->len,
3800 output2, output2_size,
3801 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003802 ASSERT_COMPARE( input_data->x, input_data->len,
3803 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003804
3805exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003806 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003807 mbedtls_free( output );
3808 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003809 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003810}
3811/* END_CASE */
3812
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003813/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003814void asymmetric_decrypt( int key_type_arg,
3815 data_t *key_data,
3816 int alg_arg,
3817 data_t *input_data,
3818 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003819 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003820{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003821 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003822 psa_key_type_t key_type = key_type_arg;
3823 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003824 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003825 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003826 size_t output_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003827 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003828
Jaeden Amero412654a2019-02-06 12:57:46 +00003829 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003830 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003831
Gilles Peskine8817f612018-12-18 00:18:46 +01003832 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003833
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003834 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003835 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003836 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003837
Gilles Peskine87a5e562019-04-17 12:28:25 +02003838 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003839 key_data->x,
3840 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003841
Gilles Peskine8817f612018-12-18 00:18:46 +01003842 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3843 input_data->x, input_data->len,
3844 label->x, label->len,
3845 output,
3846 output_size,
3847 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003848 ASSERT_COMPARE( expected_data->x, expected_data->len,
3849 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003850
Gilles Peskine68428122018-06-30 18:42:41 +02003851 /* If the label is empty, the test framework puts a non-null pointer
3852 * in label->x. Test that a null pointer works as well. */
3853 if( label->len == 0 )
3854 {
3855 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003856 if( output_size != 0 )
3857 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003858 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3859 input_data->x, input_data->len,
3860 NULL, label->len,
3861 output,
3862 output_size,
3863 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003864 ASSERT_COMPARE( expected_data->x, expected_data->len,
3865 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003866 }
3867
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003868exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003869 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003870 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003872}
3873/* END_CASE */
3874
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003875/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003876void asymmetric_decrypt_fail( int key_type_arg,
3877 data_t *key_data,
3878 int alg_arg,
3879 data_t *input_data,
3880 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003881 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003882 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003884 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003885 psa_key_type_t key_type = key_type_arg;
3886 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003887 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003888 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003889 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003890 psa_status_t actual_status;
3891 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003892 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003893
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003894 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003895
Gilles Peskine8817f612018-12-18 00:18:46 +01003896 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003897
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003898 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003899 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003900 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003901
Gilles Peskine87a5e562019-04-17 12:28:25 +02003902 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003903 key_data->x,
3904 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003905
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003906 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003907 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003908 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003909 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003910 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003911 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003912 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003913
Gilles Peskine68428122018-06-30 18:42:41 +02003914 /* If the label is empty, the test framework puts a non-null pointer
3915 * in label->x. Test that a null pointer works as well. */
3916 if( label->len == 0 )
3917 {
3918 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003919 if( output_size != 0 )
3920 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003921 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003922 input_data->x, input_data->len,
3923 NULL, label->len,
3924 output, output_size,
3925 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003926 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003927 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003928 }
3929
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003930exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003931 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003932 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003933 mbedtls_psa_crypto_free( );
3934}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003935/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003936
3937/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00003938void crypto_generator_init( )
3939{
3940 /* Test each valid way of initializing the object, except for `= {0}`, as
3941 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
3942 * though it's OK by the C standard. We could test for this, but we'd need
3943 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003944 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00003945 psa_crypto_generator_t func = psa_crypto_generator_init( );
3946 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
3947 psa_crypto_generator_t zero;
3948
3949 memset( &zero, 0, sizeof( zero ) );
3950
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003951 /* A default generator should not be able to report its capacity. */
3952 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
3953 PSA_ERROR_BAD_STATE );
3954 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
3955 PSA_ERROR_BAD_STATE );
3956 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
3957 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003958
3959 /* A default generator should be abortable without error. */
3960 PSA_ASSERT( psa_generator_abort(&func) );
3961 PSA_ASSERT( psa_generator_abort(&init) );
3962 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00003963}
3964/* END_CASE */
3965
3966/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02003967void derive_setup( int key_type_arg,
3968 data_t *key_data,
3969 int alg_arg,
3970 data_t *salt,
3971 data_t *label,
3972 int requested_capacity_arg,
3973 int expected_status_arg )
3974{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003975 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003976 size_t key_type = key_type_arg;
3977 psa_algorithm_t alg = alg_arg;
3978 size_t requested_capacity = requested_capacity_arg;
3979 psa_status_t expected_status = expected_status_arg;
3980 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003981 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003982
Gilles Peskine8817f612018-12-18 00:18:46 +01003983 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003984
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003985 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003986 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003987 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003988
Gilles Peskine87a5e562019-04-17 12:28:25 +02003989 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003990 key_data->x,
3991 key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003992
Gilles Peskinefe11b722018-12-18 00:24:04 +01003993 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
3994 salt->x, salt->len,
3995 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003996 requested_capacity ),
3997 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003998
3999exit:
4000 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004001 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004002 mbedtls_psa_crypto_free( );
4003}
4004/* END_CASE */
4005
4006/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004007void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004008{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004009 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004010 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004011 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004012 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004013 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004014 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004015 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4016 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4017 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Jaeden Amero70261c52019-01-04 11:47:20 +00004018 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004019
Gilles Peskine8817f612018-12-18 00:18:46 +01004020 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004021
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004022 PSA_ASSERT( psa_allocate_key( &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004023 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004024 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004025
Gilles Peskine87a5e562019-04-17 12:28:25 +02004026 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004027 key_data,
4028 sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004029
4030 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004031 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4032 NULL, 0,
4033 NULL, 0,
4034 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004035
4036 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004037 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4038 NULL, 0,
4039 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004040 capacity ),
4041 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004042
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004043 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004044
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004045 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004046 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004047
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004048exit:
4049 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004050 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004051 mbedtls_psa_crypto_free( );
4052}
4053/* END_CASE */
4054
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004055/* BEGIN_CASE */
4056void test_derive_invalid_generator_tests( )
4057{
4058 uint8_t output_buffer[16];
4059 size_t buffer_size = 16;
4060 size_t capacity = 0;
4061 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4062
Nir Sonnenschein50789302018-10-31 12:16:38 +02004063 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004064 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004065
4066 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004067 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004068
Gilles Peskine8817f612018-12-18 00:18:46 +01004069 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004070
Nir Sonnenschein50789302018-10-31 12:16:38 +02004071 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004072 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004073
Nir Sonnenschein50789302018-10-31 12:16:38 +02004074 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004075 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004076
4077exit:
4078 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004079}
4080/* END_CASE */
4081
4082/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004083void derive_output( int alg_arg,
4084 data_t *key_data,
4085 data_t *salt,
4086 data_t *label,
4087 int requested_capacity_arg,
4088 data_t *expected_output1,
4089 data_t *expected_output2 )
4090{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004091 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004092 psa_algorithm_t alg = alg_arg;
4093 size_t requested_capacity = requested_capacity_arg;
4094 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4095 uint8_t *expected_outputs[2] =
4096 {expected_output1->x, expected_output2->x};
4097 size_t output_sizes[2] =
4098 {expected_output1->len, expected_output2->len};
4099 size_t output_buffer_size = 0;
4100 uint8_t *output_buffer = NULL;
4101 size_t expected_capacity;
4102 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004103 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004104 psa_status_t status;
4105 unsigned i;
4106
4107 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4108 {
4109 if( output_sizes[i] > output_buffer_size )
4110 output_buffer_size = output_sizes[i];
4111 if( output_sizes[i] == 0 )
4112 expected_outputs[i] = NULL;
4113 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004114 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004115 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004116
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004117 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4118 psa_set_key_algorithm( &attributes, alg );
4119 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004120
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004121 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004122 key_data->x,
4123 key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004124
4125 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004126 if( PSA_ALG_IS_HKDF( alg ) )
4127 {
4128 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4129 PSA_ASSERT( psa_set_generator_capacity( &generator,
4130 requested_capacity ) );
4131 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4132 PSA_KDF_STEP_SALT,
4133 salt->x, salt->len ) );
4134 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4135 PSA_KDF_STEP_SECRET,
4136 handle ) );
4137 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4138 PSA_KDF_STEP_INFO,
4139 label->x, label->len ) );
4140 }
4141 else
4142 {
4143 // legacy
4144 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4145 salt->x, salt->len,
4146 label->x, label->len,
4147 requested_capacity ) );
4148 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004149 PSA_ASSERT( psa_get_generator_capacity( &generator,
4150 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004151 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004152 expected_capacity = requested_capacity;
4153
4154 /* Expansion phase. */
4155 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4156 {
4157 /* Read some bytes. */
4158 status = psa_generator_read( &generator,
4159 output_buffer, output_sizes[i] );
4160 if( expected_capacity == 0 && output_sizes[i] == 0 )
4161 {
4162 /* Reading 0 bytes when 0 bytes are available can go either way. */
4163 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004164 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004165 continue;
4166 }
4167 else if( expected_capacity == 0 ||
4168 output_sizes[i] > expected_capacity )
4169 {
4170 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004171 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004172 expected_capacity = 0;
4173 continue;
4174 }
4175 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004176 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004177 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004178 ASSERT_COMPARE( output_buffer, output_sizes[i],
4179 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004180 /* Check the generator status. */
4181 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004182 PSA_ASSERT( psa_get_generator_capacity( &generator,
4183 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004184 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004185 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004186 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004187
4188exit:
4189 mbedtls_free( output_buffer );
4190 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004191 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004192 mbedtls_psa_crypto_free( );
4193}
4194/* END_CASE */
4195
4196/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004197void derive_full( int alg_arg,
4198 data_t *key_data,
4199 data_t *salt,
4200 data_t *label,
4201 int requested_capacity_arg )
4202{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004203 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004204 psa_algorithm_t alg = alg_arg;
4205 size_t requested_capacity = requested_capacity_arg;
4206 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4207 unsigned char output_buffer[16];
4208 size_t expected_capacity = requested_capacity;
4209 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004210 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004211
Gilles Peskine8817f612018-12-18 00:18:46 +01004212 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004213
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004214 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4215 psa_set_key_algorithm( &attributes, alg );
4216 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004217
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004218 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004219 key_data->x,
4220 key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004221
4222 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004223 if( PSA_ALG_IS_HKDF( alg ) )
4224 {
4225 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4226 PSA_ASSERT( psa_set_generator_capacity( &generator,
4227 requested_capacity ) );
4228 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4229 PSA_KDF_STEP_SALT,
4230 salt->x, salt->len ) );
4231 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4232 PSA_KDF_STEP_SECRET,
4233 handle ) );
4234 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4235 PSA_KDF_STEP_INFO,
4236 label->x, label->len ) );
4237 }
4238 else
4239 {
4240 // legacy
4241 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4242 salt->x, salt->len,
4243 label->x, label->len,
4244 requested_capacity ) );
4245 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004246 PSA_ASSERT( psa_get_generator_capacity( &generator,
4247 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004248 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004249
4250 /* Expansion phase. */
4251 while( current_capacity > 0 )
4252 {
4253 size_t read_size = sizeof( output_buffer );
4254 if( read_size > current_capacity )
4255 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004256 PSA_ASSERT( psa_generator_read( &generator,
4257 output_buffer,
4258 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004259 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004260 PSA_ASSERT( psa_get_generator_capacity( &generator,
4261 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004262 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004263 }
4264
4265 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004266 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004267 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004268
Gilles Peskine8817f612018-12-18 00:18:46 +01004269 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004270
4271exit:
4272 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004273 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004274 mbedtls_psa_crypto_free( );
4275}
4276/* END_CASE */
4277
4278/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004279void derive_key_exercise( int alg_arg,
4280 data_t *key_data,
4281 data_t *salt,
4282 data_t *label,
4283 int derived_type_arg,
4284 int derived_bits_arg,
4285 int derived_usage_arg,
4286 int derived_alg_arg )
4287{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004288 psa_key_handle_t base_handle = 0;
4289 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004290 psa_algorithm_t alg = alg_arg;
4291 psa_key_type_t derived_type = derived_type_arg;
4292 size_t derived_bits = derived_bits_arg;
4293 psa_key_usage_t derived_usage = derived_usage_arg;
4294 psa_algorithm_t derived_alg = derived_alg_arg;
4295 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4296 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004297 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004298 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004299
Gilles Peskine8817f612018-12-18 00:18:46 +01004300 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004301
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004302 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4303 psa_set_key_algorithm( &attributes, alg );
4304 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
4305 PSA_ASSERT( psa_import_key( &attributes, &base_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004306 key_data->x,
4307 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004308
4309 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004310 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4311 salt->x, salt->len,
4312 label->x, label->len,
4313 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004314 psa_set_key_usage_flags( &attributes, derived_usage );
4315 psa_set_key_algorithm( &attributes, derived_alg );
4316 psa_set_key_type( &attributes, derived_type );
4317 PSA_ASSERT( psa_generator_import_key( &attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004318 derived_bits,
4319 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004320
4321 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004322 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4323 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4324 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004325
4326 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004327 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004328 goto exit;
4329
4330exit:
4331 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004332 psa_destroy_key( base_handle );
4333 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004334 mbedtls_psa_crypto_free( );
4335}
4336/* END_CASE */
4337
4338/* BEGIN_CASE */
4339void derive_key_export( int alg_arg,
4340 data_t *key_data,
4341 data_t *salt,
4342 data_t *label,
4343 int bytes1_arg,
4344 int bytes2_arg )
4345{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004346 psa_key_handle_t base_handle = 0;
4347 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004348 psa_algorithm_t alg = alg_arg;
4349 size_t bytes1 = bytes1_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004350 size_t derived_bits = PSA_BYTES_TO_BITS( bytes1 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004351 size_t bytes2 = bytes2_arg;
4352 size_t capacity = bytes1 + bytes2;
4353 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004354 uint8_t *output_buffer = NULL;
4355 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004356 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4357 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004358 size_t length;
4359
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004360 ASSERT_ALLOC( output_buffer, capacity );
4361 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004362 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004363
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004364 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4365 psa_set_key_algorithm( &base_attributes, alg );
4366 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4367 PSA_ASSERT( psa_import_key( &base_attributes, &base_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004368 key_data->x,
4369 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004370
4371 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004372 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4373 salt->x, salt->len,
4374 label->x, label->len,
4375 capacity ) );
4376 PSA_ASSERT( psa_generator_read( &generator,
4377 output_buffer,
4378 capacity ) );
4379 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004380
4381 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004382 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4383 salt->x, salt->len,
4384 label->x, label->len,
4385 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004386 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4387 psa_set_key_algorithm( &derived_attributes, 0 );
4388 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
4389 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004390 derived_bits,
4391 &generator ) );
4392 PSA_ASSERT( psa_export_key( derived_handle,
4393 export_buffer, bytes1,
4394 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004395 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004396 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004397 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004398 PSA_BYTES_TO_BITS( bytes2 ),
4399 &generator ) );
4400 PSA_ASSERT( psa_export_key( derived_handle,
4401 export_buffer + bytes1, bytes2,
4402 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004403 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004404
4405 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004406 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4407 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004408
4409exit:
4410 mbedtls_free( output_buffer );
4411 mbedtls_free( export_buffer );
4412 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004413 psa_destroy_key( base_handle );
4414 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004415 mbedtls_psa_crypto_free( );
4416}
4417/* END_CASE */
4418
4419/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004420void key_agreement_setup( int alg_arg,
4421 int our_key_type_arg, data_t *our_key_data,
4422 data_t *peer_key_data,
4423 int expected_status_arg )
4424{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004425 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004426 psa_algorithm_t alg = alg_arg;
4427 psa_key_type_t our_key_type = our_key_type_arg;
4428 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004429 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004430 psa_status_t expected_status = expected_status_arg;
4431 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004432
Gilles Peskine8817f612018-12-18 00:18:46 +01004433 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004434
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004435 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4436 psa_set_key_algorithm( &attributes, alg );
4437 psa_set_key_type( &attributes, our_key_type );
4438 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004439 our_key_data->x,
4440 our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004441
Gilles Peskine77f40d82019-04-11 21:27:06 +02004442 /* The tests currently include inputs that should fail at either step.
4443 * Test cases that fail at the setup step should be changed to call
4444 * key_derivation_setup instead, and this function should be renamed
4445 * to key_agreement_fail. */
4446 status = psa_key_derivation_setup( &generator, alg );
4447 if( status == PSA_SUCCESS )
4448 {
4449 TEST_EQUAL( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
4450 our_key,
4451 peer_key_data->x, peer_key_data->len ),
4452 expected_status );
4453 }
4454 else
4455 {
4456 TEST_ASSERT( status == expected_status );
4457 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004458
4459exit:
4460 psa_generator_abort( &generator );
4461 psa_destroy_key( our_key );
4462 mbedtls_psa_crypto_free( );
4463}
4464/* END_CASE */
4465
4466/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004467void raw_key_agreement( int alg_arg,
4468 int our_key_type_arg, data_t *our_key_data,
4469 data_t *peer_key_data,
4470 data_t *expected_output )
4471{
4472 psa_key_handle_t our_key = 0;
4473 psa_algorithm_t alg = alg_arg;
4474 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004475 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004476 unsigned char *output = NULL;
4477 size_t output_length = ~0;
4478
4479 ASSERT_ALLOC( output, expected_output->len );
4480 PSA_ASSERT( psa_crypto_init( ) );
4481
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004482 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4483 psa_set_key_algorithm( &attributes, alg );
4484 psa_set_key_type( &attributes, our_key_type );
4485 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskinef0cba732019-04-11 22:12:38 +02004486 our_key_data->x,
4487 our_key_data->len ) );
4488
4489 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4490 alg, our_key,
4491 peer_key_data->x, peer_key_data->len,
4492 output, expected_output->len, &output_length ) );
4493 ASSERT_COMPARE( output, output_length,
4494 expected_output->x, expected_output->len );
4495
4496exit:
4497 mbedtls_free( output );
4498 psa_destroy_key( our_key );
4499 mbedtls_psa_crypto_free( );
4500}
4501/* END_CASE */
4502
4503/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004504void key_agreement_capacity( int alg_arg,
4505 int our_key_type_arg, data_t *our_key_data,
4506 data_t *peer_key_data,
4507 int expected_capacity_arg )
4508{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004509 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004510 psa_algorithm_t alg = alg_arg;
4511 psa_key_type_t our_key_type = our_key_type_arg;
4512 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004513 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004514 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004515 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004516
Gilles Peskine8817f612018-12-18 00:18:46 +01004517 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004518
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004519 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4520 psa_set_key_algorithm( &attributes, alg );
4521 psa_set_key_type( &attributes, our_key_type );
4522 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004523 our_key_data->x,
4524 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004525
Gilles Peskine969c5d62019-01-16 15:53:06 +01004526 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4527 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004528 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004529 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004530 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4531 {
4532 /* The test data is for info="" */
4533 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4534 PSA_KDF_STEP_INFO,
4535 NULL, 0 ) );
4536 }
Gilles Peskine59685592018-09-18 12:11:34 +02004537
Gilles Peskinebf491972018-10-25 22:36:12 +02004538 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004539 PSA_ASSERT( psa_get_generator_capacity(
4540 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004541 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004542
Gilles Peskinebf491972018-10-25 22:36:12 +02004543 /* Test the actual capacity by reading the output. */
4544 while( actual_capacity > sizeof( output ) )
4545 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004546 PSA_ASSERT( psa_generator_read( &generator,
4547 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004548 actual_capacity -= sizeof( output );
4549 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004550 PSA_ASSERT( psa_generator_read( &generator,
4551 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004552 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004553 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004554
Gilles Peskine59685592018-09-18 12:11:34 +02004555exit:
4556 psa_generator_abort( &generator );
4557 psa_destroy_key( our_key );
4558 mbedtls_psa_crypto_free( );
4559}
4560/* END_CASE */
4561
4562/* BEGIN_CASE */
4563void key_agreement_output( int alg_arg,
4564 int our_key_type_arg, data_t *our_key_data,
4565 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004566 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004567{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004568 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004569 psa_algorithm_t alg = alg_arg;
4570 psa_key_type_t our_key_type = our_key_type_arg;
4571 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004572 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004573 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004574
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004575 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4576 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004577
Gilles Peskine8817f612018-12-18 00:18:46 +01004578 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004579
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004580 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4581 psa_set_key_algorithm( &attributes, alg );
4582 psa_set_key_type( &attributes, our_key_type );
4583 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004584 our_key_data->x,
4585 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004586
Gilles Peskine969c5d62019-01-16 15:53:06 +01004587 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4588 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004589 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004590 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004591 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4592 {
4593 /* The test data is for info="" */
4594 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4595 PSA_KDF_STEP_INFO,
4596 NULL, 0 ) );
4597 }
Gilles Peskine59685592018-09-18 12:11:34 +02004598
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004599 PSA_ASSERT( psa_generator_read( &generator,
4600 actual_output,
4601 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004602 ASSERT_COMPARE( actual_output, expected_output1->len,
4603 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004604 if( expected_output2->len != 0 )
4605 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004606 PSA_ASSERT( psa_generator_read( &generator,
4607 actual_output,
4608 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004609 ASSERT_COMPARE( actual_output, expected_output2->len,
4610 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004611 }
Gilles Peskine59685592018-09-18 12:11:34 +02004612
4613exit:
4614 psa_generator_abort( &generator );
4615 psa_destroy_key( our_key );
4616 mbedtls_psa_crypto_free( );
4617 mbedtls_free( actual_output );
4618}
4619/* END_CASE */
4620
4621/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004622void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004623{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004624 size_t bytes = bytes_arg;
4625 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004626 unsigned char *output = NULL;
4627 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004628 size_t i;
4629 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004630
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004631 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4632 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004633 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004634
Gilles Peskine8817f612018-12-18 00:18:46 +01004635 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004636
Gilles Peskinea50d7392018-06-21 10:22:13 +02004637 /* Run several times, to ensure that every output byte will be
4638 * nonzero at least once with overwhelming probability
4639 * (2^(-8*number_of_runs)). */
4640 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004641 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004642 if( bytes != 0 )
4643 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004644 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004645
4646 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004647 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4648 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004649
4650 for( i = 0; i < bytes; i++ )
4651 {
4652 if( output[i] != 0 )
4653 ++changed[i];
4654 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004655 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004656
4657 /* Check that every byte was changed to nonzero at least once. This
4658 * validates that psa_generate_random is overwriting every byte of
4659 * the output buffer. */
4660 for( i = 0; i < bytes; i++ )
4661 {
4662 TEST_ASSERT( changed[i] != 0 );
4663 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004664
4665exit:
4666 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004667 mbedtls_free( output );
4668 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004669}
4670/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004671
4672/* BEGIN_CASE */
4673void generate_key( int type_arg,
4674 int bits_arg,
4675 int usage_arg,
4676 int alg_arg,
4677 int expected_status_arg )
4678{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004679 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004680 psa_key_type_t type = type_arg;
4681 psa_key_usage_t usage = usage_arg;
4682 size_t bits = bits_arg;
4683 psa_algorithm_t alg = alg_arg;
4684 psa_status_t expected_status = expected_status_arg;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004685 psa_status_t expected_info_status =
David Saadab4ecc272019-02-14 13:48:10 +02004686 expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004687 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004688 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004689
Gilles Peskine8817f612018-12-18 00:18:46 +01004690 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004691
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004692 psa_set_key_usage_flags( &attributes, usage );
4693 psa_set_key_algorithm( &attributes, alg );
4694 psa_set_key_type( &attributes, type );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004695
4696 /* Generate a key */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004697 TEST_EQUAL( psa_generate_key( &attributes, &handle, bits, NULL, 0 ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004698 expected_status );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004699 if( expected_info_status != PSA_SUCCESS )
4700 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004701
4702 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004703 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4704 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4705 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004706
Gilles Peskine818ca122018-06-20 18:16:48 +02004707 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004708 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004709 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004710
4711exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004712 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004713 mbedtls_psa_crypto_free( );
4714}
4715/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004716
Darryl Greend49a4992018-06-18 17:27:26 +01004717/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
4718void persistent_key_load_key_from_storage( data_t *data, int type_arg,
4719 int bits, int usage_arg,
Darryl Green0c6575a2018-11-07 16:05:30 +00004720 int alg_arg, int generation_method,
4721 int export_status )
Darryl Greend49a4992018-06-18 17:27:26 +01004722{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004723 psa_key_handle_t handle = 0;
4724 psa_key_handle_t base_key;
Darryl Greend49a4992018-06-18 17:27:26 +01004725 psa_key_type_t type = (psa_key_type_t) type_arg;
4726 psa_key_type_t type_get;
4727 size_t bits_get;
Jaeden Amero70261c52019-01-04 11:47:20 +00004728 psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT;
4729 psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004730 psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg;
4731 psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00004732 psa_key_policy_t base_policy_set = PSA_KEY_POLICY_INIT;
Darryl Green0c6575a2018-11-07 16:05:30 +00004733 psa_algorithm_t base_policy_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
4734 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004735 unsigned char *first_export = NULL;
4736 unsigned char *second_export = NULL;
4737 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4738 size_t first_exported_length;
4739 size_t second_exported_length;
4740
4741 ASSERT_ALLOC( first_export, export_size );
4742 ASSERT_ALLOC( second_export, export_size );
4743
Gilles Peskine8817f612018-12-18 00:18:46 +01004744 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004745
Gilles Peskine8817f612018-12-18 00:18:46 +01004746 PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
Gilles Peskine8817f612018-12-18 00:18:46 +01004747 &handle ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004748 psa_key_policy_set_usage( &policy_set, policy_usage,
4749 policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004750 PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004751
Darryl Green0c6575a2018-11-07 16:05:30 +00004752 switch( generation_method )
4753 {
4754 case IMPORT_KEY:
4755 /* Import the key */
Gilles Peskine87a5e562019-04-17 12:28:25 +02004756 PSA_ASSERT( psa_import_key_to_handle( handle, type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004757 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004758 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004759
Darryl Green0c6575a2018-11-07 16:05:30 +00004760 case GENERATE_KEY:
4761 /* Generate a key */
Gilles Peskine87a5e562019-04-17 12:28:25 +02004762 PSA_ASSERT( psa_generate_key_to_handle( handle, type, bits,
Gilles Peskine8817f612018-12-18 00:18:46 +01004763 NULL, 0 ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004764 break;
4765
4766 case DERIVE_KEY:
4767 /* Create base key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004768 PSA_ASSERT( psa_allocate_key( &base_key ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004769 psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE,
4770 base_policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004771 PSA_ASSERT( psa_set_key_policy(
4772 base_key, &base_policy_set ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02004773 PSA_ASSERT( psa_import_key_to_handle( base_key, PSA_KEY_TYPE_DERIVE,
Gilles Peskine8817f612018-12-18 00:18:46 +01004774 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004775 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004776 PSA_ASSERT( psa_key_derivation( &generator, base_key,
4777 base_policy_alg,
4778 NULL, 0, NULL, 0,
4779 export_size ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02004780 PSA_ASSERT( psa_generator_import_key_to_handle(
Gilles Peskine8817f612018-12-18 00:18:46 +01004781 handle, PSA_KEY_TYPE_RAW_DATA,
4782 bits, &generator ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004783 break;
4784 }
Darryl Greend49a4992018-06-18 17:27:26 +01004785
4786 /* Export the key */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004787 TEST_EQUAL( psa_export_key( handle,
4788 first_export, export_size,
4789 &first_exported_length ),
4790 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004791
4792 /* Shutdown and restart */
4793 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004794 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004795
Darryl Greend49a4992018-06-18 17:27:26 +01004796 /* Check key slot still contains key data */
Gilles Peskine8817f612018-12-18 00:18:46 +01004797 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
4798 &handle ) );
4799 PSA_ASSERT( psa_get_key_information(
4800 handle, &type_get, &bits_get ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004801 TEST_EQUAL( type_get, type );
4802 TEST_EQUAL( bits_get, (size_t) bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004803
Gilles Peskine8817f612018-12-18 00:18:46 +01004804 PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004805 TEST_EQUAL( psa_key_policy_get_usage( &policy_get ), policy_usage );
4806 TEST_EQUAL( psa_key_policy_get_algorithm( &policy_get ), policy_alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004807
4808 /* Export the key again */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004809 TEST_EQUAL( psa_export_key( handle,
4810 second_export, export_size,
4811 &second_exported_length ),
4812 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004813
Darryl Green0c6575a2018-11-07 16:05:30 +00004814 if( export_status == PSA_SUCCESS )
4815 {
4816 ASSERT_COMPARE( first_export, first_exported_length,
4817 second_export, second_exported_length );
Darryl Greend49a4992018-06-18 17:27:26 +01004818
Darryl Green0c6575a2018-11-07 16:05:30 +00004819 switch( generation_method )
4820 {
4821 case IMPORT_KEY:
4822 ASSERT_COMPARE( data->x, data->len,
4823 first_export, first_exported_length );
4824 break;
4825 default:
4826 break;
4827 }
4828 }
4829
4830 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004831 if( ! exercise_key( handle, policy_usage, policy_alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004832 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004833
4834exit:
4835 mbedtls_free( first_export );
4836 mbedtls_free( second_export );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004837 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004838 mbedtls_psa_crypto_free();
4839}
4840/* END_CASE */