blob: 152f7e99892354e6692af9d2a5ff467e8c696726 [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;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100215
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200216 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
217 psa_set_key_algorithm( &attributes, alg );
218 psa_set_key_type( &attributes, key_type );
219 PSA_ASSERT( psa_import_key( &attributes, &handle, 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;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200248 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100249
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200250 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
251 psa_set_key_algorithm( &attributes, alg );
252 psa_set_key_type( &attributes, key_type );
253 PSA_ASSERT( psa_import_key( &attributes, &handle, 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 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001101 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001102 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,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001160 int type_arg, int bits_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;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001168 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001169
1170 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1171 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1172 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1173 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1174 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001175 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001176
1177 psa_make_key_persistent( &attributes, id, lifetime );
1178 psa_set_key_usage_flags( &attributes, usage_flags );
1179 psa_set_key_algorithm( &attributes, alg );
1180 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001181 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001182
1183 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1184 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1185 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1186 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1187 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001188 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001189
1190 psa_reset_key_attributes( &attributes );
1191
1192 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1193 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1194 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1195 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1196 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001197 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001198}
1199/* END_CASE */
1200
1201/* BEGIN_CASE */
1202void import( data_t *data, int type_arg, int expected_status_arg )
1203{
1204 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1205 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001206 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001207 psa_key_type_t type = type_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001208 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001209 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001210
Gilles Peskine8817f612018-12-18 00:18:46 +01001211 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001212
Gilles Peskine4747d192019-04-17 15:05:45 +02001213 psa_set_key_type( &attributes, type );
1214 status = psa_import_key( &attributes, &handle, data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001215 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001216 if( status != PSA_SUCCESS )
1217 goto exit;
1218
1219 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1220 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1221
1222 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001223 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001224
1225exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001226 psa_destroy_key( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001227 mbedtls_psa_crypto_free( );
1228}
1229/* END_CASE */
1230
1231/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001232void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1233{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001234 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001235 size_t bits = bits_arg;
1236 psa_status_t expected_status = expected_status_arg;
1237 psa_status_t status;
1238 psa_key_type_t type =
1239 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1240 size_t buffer_size = /* Slight overapproximations */
1241 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001242 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001243 unsigned char *p;
1244 int ret;
1245 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001246 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001247
Gilles Peskine8817f612018-12-18 00:18:46 +01001248 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001249 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001250
1251 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1252 bits, keypair ) ) >= 0 );
1253 length = ret;
1254
1255 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001256 psa_set_key_type( &attributes, type );
1257 status = psa_import_key( &attributes, &handle, p, length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001258 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001259 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001260 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001261
1262exit:
1263 mbedtls_free( buffer );
1264 mbedtls_psa_crypto_free( );
1265}
1266/* END_CASE */
1267
1268/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001269void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001270 int type_arg,
1271 int alg_arg,
1272 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001273 int expected_bits,
1274 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001275 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001276 int canonical_input )
1277{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001278 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001279 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001280 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001281 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001282 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001283 unsigned char *exported = NULL;
1284 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001285 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001286 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001287 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001288 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001289 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001290
Moran Pekercb088e72018-07-17 17:36:59 +03001291 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001292 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001293 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001294 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001295 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001296
Gilles Peskine4747d192019-04-17 15:05:45 +02001297 psa_set_key_usage_flags( &attributes, usage_arg );
1298 psa_set_key_algorithm( &attributes, alg );
1299 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001300
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001301 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001302 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001303
1304 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001305 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1306 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1307 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001308
1309 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001310 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001311 exported, export_size,
1312 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001313 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001314
1315 /* The exported length must be set by psa_export_key() to a value between 0
1316 * and export_size. On errors, the exported length must be 0. */
1317 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1318 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1319 TEST_ASSERT( exported_length <= export_size );
1320
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001321 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001322 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001323 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001324 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001325 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001326 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001327 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001328
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001329 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001330 goto exit;
1331
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001332 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001333 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001334 else
1335 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001336 psa_key_handle_t handle2;
Gilles Peskine4747d192019-04-17 15:05:45 +02001337 PSA_ASSERT( psa_import_key( &attributes, &handle2,
1338 exported, exported_length ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001339 PSA_ASSERT( psa_export_key( handle2,
1340 reexported,
1341 export_size,
1342 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001343 ASSERT_COMPARE( exported, exported_length,
1344 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001345 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001346 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001347 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001348
1349destroy:
1350 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001351 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001352 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001353
1354exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001355 mbedtls_free( exported );
1356 mbedtls_free( reexported );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001357 mbedtls_psa_crypto_free( );
1358}
1359/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001360
Moran Pekerf709f4a2018-06-06 17:26:04 +03001361/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001362void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001363{
Gilles Peskine8817f612018-12-18 00:18:46 +01001364 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001365 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001366
1367exit:
1368 mbedtls_psa_crypto_free( );
1369}
1370/* END_CASE */
1371
1372/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001373void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001374 int type_arg,
1375 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001376 int export_size_delta,
1377 int expected_export_status_arg,
1378 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001379{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001380 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001381 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001382 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001383 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001384 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001385 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001386 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001387 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001388 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001389
Gilles Peskine8817f612018-12-18 00:18:46 +01001390 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001391
Gilles Peskine4747d192019-04-17 15:05:45 +02001392 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1393 psa_set_key_algorithm( &attributes, alg );
1394 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001395
1396 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001397 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001398
Gilles Peskine49c25912018-10-29 15:15:31 +01001399 /* Export the public key */
1400 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001401 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001402 exported, export_size,
1403 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001404 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001405 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001406 {
1407 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1408 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001409 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1410 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001411 TEST_ASSERT( expected_public_key->len <=
1412 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001413 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1414 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001415 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001416
1417exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001418 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001419 psa_destroy_key( handle );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001420 mbedtls_psa_crypto_free( );
1421}
1422/* END_CASE */
1423
Gilles Peskine20035e32018-02-03 22:44:14 +01001424/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001425void import_and_exercise_key( data_t *data,
1426 int type_arg,
1427 int bits_arg,
1428 int alg_arg )
1429{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001430 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001431 psa_key_type_t type = type_arg;
1432 size_t bits = bits_arg;
1433 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001434 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001435 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001436 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001437
Gilles Peskine8817f612018-12-18 00:18:46 +01001438 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001439
Gilles Peskine4747d192019-04-17 15:05:45 +02001440 psa_set_key_usage_flags( &attributes, usage );
1441 psa_set_key_algorithm( &attributes, alg );
1442 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001443
1444 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001445 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001446
1447 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001448 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1449 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1450 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001451
1452 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001453 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001454 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001455
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001456 PSA_ASSERT( psa_destroy_key( handle ) );
1457 test_operations_on_invalid_handle( handle );
1458
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001459exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001460 psa_destroy_key( handle );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001461 mbedtls_psa_crypto_free( );
1462}
1463/* END_CASE */
1464
1465/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001466void key_policy( int usage_arg, int alg_arg )
1467{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001468 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001469 psa_algorithm_t alg = alg_arg;
1470 psa_key_usage_t usage = usage_arg;
1471 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1472 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001473 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001474
1475 memset( key, 0x2a, sizeof( key ) );
1476
Gilles Peskine8817f612018-12-18 00:18:46 +01001477 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001478
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001479 psa_set_key_usage_flags( &attributes, usage );
1480 psa_set_key_algorithm( &attributes, alg );
1481 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001482
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001483 PSA_ASSERT( psa_import_key( &attributes, &handle, key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001484
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001485 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1486 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1487 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1488 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001489
1490exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001491 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001492 mbedtls_psa_crypto_free( );
1493}
1494/* END_CASE */
1495
1496/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001497void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001498{
1499 /* Test each valid way of initializing the object, except for `= {0}`, as
1500 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1501 * though it's OK by the C standard. We could test for this, but we'd need
1502 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001503 psa_key_attributes_t func = psa_key_attributes_init( );
1504 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1505 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001506
1507 memset( &zero, 0, sizeof( zero ) );
1508
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001509 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1510 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1511 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001512
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001513 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1514 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1515 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1516
1517 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1518 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1519 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1520
1521 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1522 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1523 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1524
1525 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1526 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1527 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001528}
1529/* END_CASE */
1530
1531/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001532void mac_key_policy( int policy_usage,
1533 int policy_alg,
1534 int key_type,
1535 data_t *key_data,
1536 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001537{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001538 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001539 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001540 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001541 psa_status_t status;
1542 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001543
Gilles Peskine8817f612018-12-18 00:18:46 +01001544 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001545
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001546 psa_set_key_usage_flags( &attributes, policy_usage );
1547 psa_set_key_algorithm( &attributes, policy_alg );
1548 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001549
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001550 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001551 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001552
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001553 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001554 if( policy_alg == exercise_alg &&
1555 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001556 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001557 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001558 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001559 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001560
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001561 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001562 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001563 if( policy_alg == exercise_alg &&
1564 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001565 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001566 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001567 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001568
1569exit:
1570 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001571 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001572 mbedtls_psa_crypto_free( );
1573}
1574/* END_CASE */
1575
1576/* BEGIN_CASE */
1577void cipher_key_policy( int policy_usage,
1578 int policy_alg,
1579 int key_type,
1580 data_t *key_data,
1581 int exercise_alg )
1582{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001583 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001584 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001585 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001586 psa_status_t status;
1587
Gilles Peskine8817f612018-12-18 00:18:46 +01001588 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001589
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001590 psa_set_key_usage_flags( &attributes, policy_usage );
1591 psa_set_key_algorithm( &attributes, policy_alg );
1592 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001593
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001594 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001595 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001596
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001597 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001598 if( policy_alg == exercise_alg &&
1599 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001600 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001601 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001602 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001603 psa_cipher_abort( &operation );
1604
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001605 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001606 if( policy_alg == exercise_alg &&
1607 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001608 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001609 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001610 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001611
1612exit:
1613 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001614 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001615 mbedtls_psa_crypto_free( );
1616}
1617/* END_CASE */
1618
1619/* BEGIN_CASE */
1620void aead_key_policy( int policy_usage,
1621 int policy_alg,
1622 int key_type,
1623 data_t *key_data,
1624 int nonce_length_arg,
1625 int tag_length_arg,
1626 int exercise_alg )
1627{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001628 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001629 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001630 psa_status_t status;
1631 unsigned char nonce[16] = {0};
1632 size_t nonce_length = nonce_length_arg;
1633 unsigned char tag[16];
1634 size_t tag_length = tag_length_arg;
1635 size_t output_length;
1636
1637 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1638 TEST_ASSERT( tag_length <= sizeof( tag ) );
1639
Gilles Peskine8817f612018-12-18 00:18:46 +01001640 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001641
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001642 psa_set_key_usage_flags( &attributes, policy_usage );
1643 psa_set_key_algorithm( &attributes, policy_alg );
1644 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001645
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001646 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001647 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001648
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001649 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001650 nonce, nonce_length,
1651 NULL, 0,
1652 NULL, 0,
1653 tag, tag_length,
1654 &output_length );
1655 if( policy_alg == exercise_alg &&
1656 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001657 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001658 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001659 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001660
1661 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001662 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001663 nonce, nonce_length,
1664 NULL, 0,
1665 tag, tag_length,
1666 NULL, 0,
1667 &output_length );
1668 if( policy_alg == exercise_alg &&
1669 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001670 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001671 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001672 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001673
1674exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001675 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001676 mbedtls_psa_crypto_free( );
1677}
1678/* END_CASE */
1679
1680/* BEGIN_CASE */
1681void asymmetric_encryption_key_policy( int policy_usage,
1682 int policy_alg,
1683 int key_type,
1684 data_t *key_data,
1685 int exercise_alg )
1686{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001687 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001688 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001689 psa_status_t status;
1690 size_t key_bits;
1691 size_t buffer_length;
1692 unsigned char *buffer = NULL;
1693 size_t output_length;
1694
Gilles Peskine8817f612018-12-18 00:18:46 +01001695 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001696
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001697 psa_set_key_usage_flags( &attributes, policy_usage );
1698 psa_set_key_algorithm( &attributes, policy_alg );
1699 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001700
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001701 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001702 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001703
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001704 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1705 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001706 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1707 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001708 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001709
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001710 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001711 NULL, 0,
1712 NULL, 0,
1713 buffer, buffer_length,
1714 &output_length );
1715 if( policy_alg == exercise_alg &&
1716 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001717 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001718 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001719 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001720
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001721 if( buffer_length != 0 )
1722 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001723 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001724 buffer, buffer_length,
1725 NULL, 0,
1726 buffer, buffer_length,
1727 &output_length );
1728 if( policy_alg == exercise_alg &&
1729 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001730 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001731 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001732 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001733
1734exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001735 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001736 mbedtls_psa_crypto_free( );
1737 mbedtls_free( buffer );
1738}
1739/* END_CASE */
1740
1741/* BEGIN_CASE */
1742void asymmetric_signature_key_policy( int policy_usage,
1743 int policy_alg,
1744 int key_type,
1745 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001746 int exercise_alg,
1747 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001749 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001750 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001752 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1753 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1754 * compatible with the policy and `payload_length_arg` is supposed to be
1755 * a valid input length to sign. If `payload_length_arg <= 0`,
1756 * `exercise_alg` is supposed to be forbidden by the policy. */
1757 int compatible_alg = payload_length_arg > 0;
1758 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001759 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1760 size_t signature_length;
1761
Gilles Peskine8817f612018-12-18 00:18:46 +01001762 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001763
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001764 psa_set_key_usage_flags( &attributes, policy_usage );
1765 psa_set_key_algorithm( &attributes, policy_alg );
1766 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001768 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001769 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001770
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001771 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001772 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001773 signature, sizeof( signature ),
1774 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001775 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001776 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001777 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001778 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001779
1780 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001781 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001782 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001783 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001784 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001785 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001786 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001787 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001788
1789exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001790 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001791 mbedtls_psa_crypto_free( );
1792}
1793/* END_CASE */
1794
1795/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001796void derive_key_policy( int policy_usage,
1797 int policy_alg,
1798 int key_type,
1799 data_t *key_data,
1800 int exercise_alg )
1801{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001802 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001803 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001804 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1805 psa_status_t status;
1806
Gilles Peskine8817f612018-12-18 00:18:46 +01001807 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001808
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001809 psa_set_key_usage_flags( &attributes, policy_usage );
1810 psa_set_key_algorithm( &attributes, policy_alg );
1811 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001812
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001813 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001814 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001815
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001816 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001817 exercise_alg,
1818 NULL, 0,
1819 NULL, 0,
1820 1 );
1821 if( policy_alg == exercise_alg &&
1822 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001823 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001824 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001825 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001826
1827exit:
1828 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001829 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001830 mbedtls_psa_crypto_free( );
1831}
1832/* END_CASE */
1833
1834/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001835void agreement_key_policy( int policy_usage,
1836 int policy_alg,
1837 int key_type_arg,
1838 data_t *key_data,
1839 int exercise_alg )
1840{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001841 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001842 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001843 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001844 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1845 psa_status_t status;
1846
Gilles Peskine8817f612018-12-18 00:18:46 +01001847 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001848
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001849 psa_set_key_usage_flags( &attributes, policy_usage );
1850 psa_set_key_algorithm( &attributes, policy_alg );
1851 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001852
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001853 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001854 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001855
Gilles Peskine969c5d62019-01-16 15:53:06 +01001856 PSA_ASSERT( psa_key_derivation_setup( &generator, exercise_alg ) );
1857 status = key_agreement_with_self( &generator, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001858
Gilles Peskine01d718c2018-09-18 12:01:02 +02001859 if( policy_alg == exercise_alg &&
1860 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001861 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001862 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001863 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001864
1865exit:
1866 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001867 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001868 mbedtls_psa_crypto_free( );
1869}
1870/* END_CASE */
1871
1872/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001873void raw_agreement_key_policy( int policy_usage,
1874 int policy_alg,
1875 int key_type_arg,
1876 data_t *key_data,
1877 int exercise_alg )
1878{
1879 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001880 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001881 psa_key_type_t key_type = key_type_arg;
1882 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1883 psa_status_t status;
1884
1885 PSA_ASSERT( psa_crypto_init( ) );
1886
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001887 psa_set_key_usage_flags( &attributes, policy_usage );
1888 psa_set_key_algorithm( &attributes, policy_alg );
1889 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001890
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001891 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001892 key_data->x, key_data->len ) );
1893
1894 status = raw_key_agreement_with_self( exercise_alg, handle );
1895
1896 if( policy_alg == exercise_alg &&
1897 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1898 PSA_ASSERT( status );
1899 else
1900 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1901
1902exit:
1903 psa_generator_abort( &generator );
1904 psa_destroy_key( handle );
1905 mbedtls_psa_crypto_free( );
1906}
1907/* END_CASE */
1908
1909/* BEGIN_CASE */
Gilles Peskineca25db92019-04-19 11:43:08 +02001910void copy_key( int source_usage_arg, int source_alg_arg,
1911 int type_arg, data_t *material,
1912 int copy_attributes,
1913 int target_usage_arg, int target_alg_arg,
1914 int expected_status_arg,
1915 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001916{
Gilles Peskineca25db92019-04-19 11:43:08 +02001917 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1918 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001919 psa_key_usage_t expected_usage = expected_usage_arg;
1920 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001921 psa_key_handle_t source_handle = 0;
1922 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001923 uint8_t *export_buffer = NULL;
1924
Gilles Peskine57ab7212019-01-28 13:03:09 +01001925 PSA_ASSERT( psa_crypto_init( ) );
1926
Gilles Peskineca25db92019-04-19 11:43:08 +02001927 /* Prepare the source key. */
1928 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1929 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1930 psa_set_key_type( &source_attributes, type_arg );
1931 PSA_ASSERT( psa_import_key( &source_attributes, &source_handle,
Gilles Peskine57ab7212019-01-28 13:03:09 +01001932 material->x, material->len ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001933 /* Retrieve the key size. */
1934 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001935
Gilles Peskineca25db92019-04-19 11:43:08 +02001936 /* Prepare the target attributes. */
1937 if( copy_attributes )
1938 target_attributes = source_attributes;
1939 if( target_usage_arg != -1 )
1940 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1941 if( target_alg_arg != -1 )
1942 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001943
1944 /* Copy the key. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001945 TEST_EQUAL( psa_copy_key( source_handle,
1946 &target_attributes, &target_handle ),
1947 expected_status_arg );
1948 if( expected_status_arg != PSA_SUCCESS )
1949 {
1950 TEST_EQUAL( target_handle, 0 );
1951 goto exit;
1952 }
Gilles Peskine57ab7212019-01-28 13:03:09 +01001953
1954 /* Destroy the source to ensure that this doesn't affect the target. */
1955 PSA_ASSERT( psa_destroy_key( source_handle ) );
1956
1957 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001958 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1959 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1960 psa_get_key_type( &target_attributes ) );
1961 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1962 psa_get_key_bits( &target_attributes ) );
1963 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
1964 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001965 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1966 {
1967 size_t length;
1968 ASSERT_ALLOC( export_buffer, material->len );
1969 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1970 material->len, &length ) );
1971 ASSERT_COMPARE( material->x, material->len,
1972 export_buffer, length );
1973 }
1974 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1975 goto exit;
1976
1977 PSA_ASSERT( psa_close_key( target_handle ) );
1978
1979exit:
1980 mbedtls_psa_crypto_free( );
1981 mbedtls_free( export_buffer );
1982}
1983/* END_CASE */
1984
1985/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00001986void hash_operation_init( )
1987{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00001988 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00001989 /* Test each valid way of initializing the object, except for `= {0}`, as
1990 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1991 * though it's OK by the C standard. We could test for this, but we'd need
1992 * to supress the Clang warning for the test. */
1993 psa_hash_operation_t func = psa_hash_operation_init( );
1994 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
1995 psa_hash_operation_t zero;
1996
1997 memset( &zero, 0, sizeof( zero ) );
1998
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00001999 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002000 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2001 PSA_ERROR_BAD_STATE );
2002 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2003 PSA_ERROR_BAD_STATE );
2004 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2005 PSA_ERROR_BAD_STATE );
2006
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002007 /* A default hash operation should be abortable without error. */
2008 PSA_ASSERT( psa_hash_abort( &func ) );
2009 PSA_ASSERT( psa_hash_abort( &init ) );
2010 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002011}
2012/* END_CASE */
2013
2014/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002015void hash_setup( int alg_arg,
2016 int expected_status_arg )
2017{
2018 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002019 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002020 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002021 psa_status_t status;
2022
Gilles Peskine8817f612018-12-18 00:18:46 +01002023 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002024
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002025 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002026 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002027
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002028 /* Whether setup succeeded or failed, abort must succeed. */
2029 PSA_ASSERT( psa_hash_abort( &operation ) );
2030
2031 /* If setup failed, reproduce the failure, so as to
2032 * test the resulting state of the operation object. */
2033 if( status != PSA_SUCCESS )
2034 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2035
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002036 /* Now the operation object should be reusable. */
2037#if defined(KNOWN_SUPPORTED_HASH_ALG)
2038 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2039 PSA_ASSERT( psa_hash_abort( &operation ) );
2040#endif
2041
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002042exit:
2043 mbedtls_psa_crypto_free( );
2044}
2045/* END_CASE */
2046
2047/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002048void hash_bad_order( )
2049{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002050 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002051 unsigned char input[] = "";
2052 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002053 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002054 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2055 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2056 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002057 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002058 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002059 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002060
Gilles Peskine8817f612018-12-18 00:18:46 +01002061 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002062
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002063 /* Call setup twice in a row. */
2064 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2065 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2066 PSA_ERROR_BAD_STATE );
2067 PSA_ASSERT( psa_hash_abort( &operation ) );
2068
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002069 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002070 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002071 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002072 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002073
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002074 /* Call update after finish. */
2075 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2076 PSA_ASSERT( psa_hash_finish( &operation,
2077 hash, sizeof( hash ), &hash_len ) );
2078 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002079 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002080 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002081
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002082 /* Call verify without calling setup beforehand. */
2083 TEST_EQUAL( psa_hash_verify( &operation,
2084 valid_hash, sizeof( valid_hash ) ),
2085 PSA_ERROR_BAD_STATE );
2086 PSA_ASSERT( psa_hash_abort( &operation ) );
2087
2088 /* Call verify after finish. */
2089 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2090 PSA_ASSERT( psa_hash_finish( &operation,
2091 hash, sizeof( hash ), &hash_len ) );
2092 TEST_EQUAL( psa_hash_verify( &operation,
2093 valid_hash, sizeof( valid_hash ) ),
2094 PSA_ERROR_BAD_STATE );
2095 PSA_ASSERT( psa_hash_abort( &operation ) );
2096
2097 /* Call verify twice in a row. */
2098 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2099 PSA_ASSERT( psa_hash_verify( &operation,
2100 valid_hash, sizeof( valid_hash ) ) );
2101 TEST_EQUAL( psa_hash_verify( &operation,
2102 valid_hash, sizeof( valid_hash ) ),
2103 PSA_ERROR_BAD_STATE );
2104 PSA_ASSERT( psa_hash_abort( &operation ) );
2105
2106 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002107 TEST_EQUAL( psa_hash_finish( &operation,
2108 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002109 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002110 PSA_ASSERT( psa_hash_abort( &operation ) );
2111
2112 /* Call finish twice in a row. */
2113 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2114 PSA_ASSERT( psa_hash_finish( &operation,
2115 hash, sizeof( hash ), &hash_len ) );
2116 TEST_EQUAL( psa_hash_finish( &operation,
2117 hash, sizeof( hash ), &hash_len ),
2118 PSA_ERROR_BAD_STATE );
2119 PSA_ASSERT( psa_hash_abort( &operation ) );
2120
2121 /* Call finish after calling verify. */
2122 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2123 PSA_ASSERT( psa_hash_verify( &operation,
2124 valid_hash, sizeof( valid_hash ) ) );
2125 TEST_EQUAL( psa_hash_finish( &operation,
2126 hash, sizeof( hash ), &hash_len ),
2127 PSA_ERROR_BAD_STATE );
2128 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002129
2130exit:
2131 mbedtls_psa_crypto_free( );
2132}
2133/* END_CASE */
2134
itayzafrir27e69452018-11-01 14:26:34 +02002135/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2136void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002137{
2138 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002139 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2140 * appended to it */
2141 unsigned char hash[] = {
2142 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2143 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2144 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002145 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002146 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002147
Gilles Peskine8817f612018-12-18 00:18:46 +01002148 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002149
itayzafrir27e69452018-11-01 14:26:34 +02002150 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002151 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002152 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002153 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002154
itayzafrir27e69452018-11-01 14:26:34 +02002155 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002156 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002157 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002158 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002159
itayzafrir27e69452018-11-01 14:26:34 +02002160 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002161 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002162 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002163 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002164
itayzafrirec93d302018-10-18 18:01:10 +03002165exit:
2166 mbedtls_psa_crypto_free( );
2167}
2168/* END_CASE */
2169
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002170/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2171void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002172{
2173 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002174 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002175 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002176 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002177 size_t hash_len;
2178
Gilles Peskine8817f612018-12-18 00:18:46 +01002179 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002180
itayzafrir58028322018-10-25 10:22:01 +03002181 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002182 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002183 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002184 hash, expected_size - 1, &hash_len ),
2185 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002186
2187exit:
2188 mbedtls_psa_crypto_free( );
2189}
2190/* END_CASE */
2191
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002192/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2193void hash_clone_source_state( )
2194{
2195 psa_algorithm_t alg = PSA_ALG_SHA_256;
2196 unsigned char hash[PSA_HASH_MAX_SIZE];
2197 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2198 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2199 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2200 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2201 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2202 size_t hash_len;
2203
2204 PSA_ASSERT( psa_crypto_init( ) );
2205 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2206
2207 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2208 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2209 PSA_ASSERT( psa_hash_finish( &op_finished,
2210 hash, sizeof( hash ), &hash_len ) );
2211 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2212 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2213
2214 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2215 PSA_ERROR_BAD_STATE );
2216
2217 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2218 PSA_ASSERT( psa_hash_finish( &op_init,
2219 hash, sizeof( hash ), &hash_len ) );
2220 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2221 PSA_ASSERT( psa_hash_finish( &op_finished,
2222 hash, sizeof( hash ), &hash_len ) );
2223 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2224 PSA_ASSERT( psa_hash_finish( &op_aborted,
2225 hash, sizeof( hash ), &hash_len ) );
2226
2227exit:
2228 psa_hash_abort( &op_source );
2229 psa_hash_abort( &op_init );
2230 psa_hash_abort( &op_setup );
2231 psa_hash_abort( &op_finished );
2232 psa_hash_abort( &op_aborted );
2233 mbedtls_psa_crypto_free( );
2234}
2235/* END_CASE */
2236
2237/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2238void hash_clone_target_state( )
2239{
2240 psa_algorithm_t alg = PSA_ALG_SHA_256;
2241 unsigned char hash[PSA_HASH_MAX_SIZE];
2242 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2243 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2244 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2245 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2246 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2247 size_t hash_len;
2248
2249 PSA_ASSERT( psa_crypto_init( ) );
2250
2251 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2252 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2253 PSA_ASSERT( psa_hash_finish( &op_finished,
2254 hash, sizeof( hash ), &hash_len ) );
2255 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2256 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2257
2258 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2259 PSA_ASSERT( psa_hash_finish( &op_target,
2260 hash, sizeof( hash ), &hash_len ) );
2261
2262 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2263 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2264 PSA_ERROR_BAD_STATE );
2265 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2266 PSA_ERROR_BAD_STATE );
2267
2268exit:
2269 psa_hash_abort( &op_target );
2270 psa_hash_abort( &op_init );
2271 psa_hash_abort( &op_setup );
2272 psa_hash_abort( &op_finished );
2273 psa_hash_abort( &op_aborted );
2274 mbedtls_psa_crypto_free( );
2275}
2276/* END_CASE */
2277
itayzafrir58028322018-10-25 10:22:01 +03002278/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002279void mac_operation_init( )
2280{
Jaeden Amero252ef282019-02-15 14:05:35 +00002281 const uint8_t input[1] = { 0 };
2282
Jaeden Amero769ce272019-01-04 11:48:03 +00002283 /* Test each valid way of initializing the object, except for `= {0}`, as
2284 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2285 * though it's OK by the C standard. We could test for this, but we'd need
2286 * to supress the Clang warning for the test. */
2287 psa_mac_operation_t func = psa_mac_operation_init( );
2288 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2289 psa_mac_operation_t zero;
2290
2291 memset( &zero, 0, sizeof( zero ) );
2292
Jaeden Amero252ef282019-02-15 14:05:35 +00002293 /* A freshly-initialized MAC operation should not be usable. */
2294 TEST_EQUAL( psa_mac_update( &func,
2295 input, sizeof( input ) ),
2296 PSA_ERROR_BAD_STATE );
2297 TEST_EQUAL( psa_mac_update( &init,
2298 input, sizeof( input ) ),
2299 PSA_ERROR_BAD_STATE );
2300 TEST_EQUAL( psa_mac_update( &zero,
2301 input, sizeof( input ) ),
2302 PSA_ERROR_BAD_STATE );
2303
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002304 /* A default MAC operation should be abortable without error. */
2305 PSA_ASSERT( psa_mac_abort( &func ) );
2306 PSA_ASSERT( psa_mac_abort( &init ) );
2307 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002308}
2309/* END_CASE */
2310
2311/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002312void mac_setup( int key_type_arg,
2313 data_t *key,
2314 int alg_arg,
2315 int expected_status_arg )
2316{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002317 psa_key_type_t key_type = key_type_arg;
2318 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002319 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002320 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002321 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2322#if defined(KNOWN_SUPPORTED_MAC_ALG)
2323 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2324#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002325
Gilles Peskine8817f612018-12-18 00:18:46 +01002326 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002327
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002328 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2329 &operation, &status ) )
2330 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002331 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002332
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002333 /* The operation object should be reusable. */
2334#if defined(KNOWN_SUPPORTED_MAC_ALG)
2335 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2336 smoke_test_key_data,
2337 sizeof( smoke_test_key_data ),
2338 KNOWN_SUPPORTED_MAC_ALG,
2339 &operation, &status ) )
2340 goto exit;
2341 TEST_EQUAL( status, PSA_SUCCESS );
2342#endif
2343
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002344exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002345 mbedtls_psa_crypto_free( );
2346}
2347/* END_CASE */
2348
2349/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002350void mac_bad_order( )
2351{
2352 psa_key_handle_t handle = 0;
2353 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2354 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2355 const uint8_t key[] = {
2356 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2357 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2358 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002359 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002360 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2361 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2362 size_t sign_mac_length = 0;
2363 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2364 const uint8_t verify_mac[] = {
2365 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2366 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2367 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2368
2369 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002370 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2371 psa_set_key_algorithm( &attributes, alg );
2372 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002373
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002374 PSA_ASSERT( psa_import_key( &attributes, &handle,
Jaeden Amero252ef282019-02-15 14:05:35 +00002375 key, sizeof(key) ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002376
Jaeden Amero252ef282019-02-15 14:05:35 +00002377 /* Call update without calling setup beforehand. */
2378 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2379 PSA_ERROR_BAD_STATE );
2380 PSA_ASSERT( psa_mac_abort( &operation ) );
2381
2382 /* Call sign finish without calling setup beforehand. */
2383 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2384 &sign_mac_length),
2385 PSA_ERROR_BAD_STATE );
2386 PSA_ASSERT( psa_mac_abort( &operation ) );
2387
2388 /* Call verify finish without calling setup beforehand. */
2389 TEST_EQUAL( psa_mac_verify_finish( &operation,
2390 verify_mac, sizeof( verify_mac ) ),
2391 PSA_ERROR_BAD_STATE );
2392 PSA_ASSERT( psa_mac_abort( &operation ) );
2393
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002394 /* Call setup twice in a row. */
2395 PSA_ASSERT( psa_mac_sign_setup( &operation,
2396 handle, alg ) );
2397 TEST_EQUAL( psa_mac_sign_setup( &operation,
2398 handle, alg ),
2399 PSA_ERROR_BAD_STATE );
2400 PSA_ASSERT( psa_mac_abort( &operation ) );
2401
Jaeden Amero252ef282019-02-15 14:05:35 +00002402 /* Call update after sign finish. */
2403 PSA_ASSERT( psa_mac_sign_setup( &operation,
2404 handle, alg ) );
2405 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2406 PSA_ASSERT( psa_mac_sign_finish( &operation,
2407 sign_mac, sizeof( sign_mac ),
2408 &sign_mac_length ) );
2409 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2410 PSA_ERROR_BAD_STATE );
2411 PSA_ASSERT( psa_mac_abort( &operation ) );
2412
2413 /* Call update after verify finish. */
2414 PSA_ASSERT( psa_mac_verify_setup( &operation,
2415 handle, alg ) );
2416 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2417 PSA_ASSERT( psa_mac_verify_finish( &operation,
2418 verify_mac, sizeof( verify_mac ) ) );
2419 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2420 PSA_ERROR_BAD_STATE );
2421 PSA_ASSERT( psa_mac_abort( &operation ) );
2422
2423 /* Call sign finish twice in a row. */
2424 PSA_ASSERT( psa_mac_sign_setup( &operation,
2425 handle, alg ) );
2426 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2427 PSA_ASSERT( psa_mac_sign_finish( &operation,
2428 sign_mac, sizeof( sign_mac ),
2429 &sign_mac_length ) );
2430 TEST_EQUAL( psa_mac_sign_finish( &operation,
2431 sign_mac, sizeof( sign_mac ),
2432 &sign_mac_length ),
2433 PSA_ERROR_BAD_STATE );
2434 PSA_ASSERT( psa_mac_abort( &operation ) );
2435
2436 /* Call verify finish twice in a row. */
2437 PSA_ASSERT( psa_mac_verify_setup( &operation,
2438 handle, alg ) );
2439 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2440 PSA_ASSERT( psa_mac_verify_finish( &operation,
2441 verify_mac, sizeof( verify_mac ) ) );
2442 TEST_EQUAL( psa_mac_verify_finish( &operation,
2443 verify_mac, sizeof( verify_mac ) ),
2444 PSA_ERROR_BAD_STATE );
2445 PSA_ASSERT( psa_mac_abort( &operation ) );
2446
2447 /* Setup sign but try verify. */
2448 PSA_ASSERT( psa_mac_sign_setup( &operation,
2449 handle, alg ) );
2450 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2451 TEST_EQUAL( psa_mac_verify_finish( &operation,
2452 verify_mac, sizeof( verify_mac ) ),
2453 PSA_ERROR_BAD_STATE );
2454 PSA_ASSERT( psa_mac_abort( &operation ) );
2455
2456 /* Setup verify but try sign. */
2457 PSA_ASSERT( psa_mac_verify_setup( &operation,
2458 handle, alg ) );
2459 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2460 TEST_EQUAL( psa_mac_sign_finish( &operation,
2461 sign_mac, sizeof( sign_mac ),
2462 &sign_mac_length ),
2463 PSA_ERROR_BAD_STATE );
2464 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002465
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002466exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002467 mbedtls_psa_crypto_free( );
2468}
2469/* END_CASE */
2470
2471/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002472void mac_sign( int key_type_arg,
2473 data_t *key,
2474 int alg_arg,
2475 data_t *input,
2476 data_t *expected_mac )
2477{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002478 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002479 psa_key_type_t key_type = key_type_arg;
2480 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002481 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002482 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002483 /* Leave a little extra room in the output buffer. At the end of the
2484 * test, we'll check that the implementation didn't overwrite onto
2485 * this extra room. */
2486 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2487 size_t mac_buffer_size =
2488 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2489 size_t mac_length = 0;
2490
2491 memset( actual_mac, '+', sizeof( actual_mac ) );
2492 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2493 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2494
Gilles Peskine8817f612018-12-18 00:18:46 +01002495 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002496
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002497 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2498 psa_set_key_algorithm( &attributes, alg );
2499 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002500
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002501 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002502 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002503
2504 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002505 PSA_ASSERT( psa_mac_sign_setup( &operation,
2506 handle, alg ) );
2507 PSA_ASSERT( psa_mac_update( &operation,
2508 input->x, input->len ) );
2509 PSA_ASSERT( psa_mac_sign_finish( &operation,
2510 actual_mac, mac_buffer_size,
2511 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002512
2513 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002514 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2515 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002516
2517 /* Verify that the end of the buffer is untouched. */
2518 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2519 sizeof( actual_mac ) - mac_length ) );
2520
2521exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002522 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002523 mbedtls_psa_crypto_free( );
2524}
2525/* END_CASE */
2526
2527/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002528void mac_verify( int key_type_arg,
2529 data_t *key,
2530 int alg_arg,
2531 data_t *input,
2532 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002533{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002534 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002535 psa_key_type_t key_type = key_type_arg;
2536 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002537 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002538 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002539
Gilles Peskine69c12672018-06-28 00:07:19 +02002540 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2541
Gilles Peskine8817f612018-12-18 00:18:46 +01002542 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002543
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002544 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2545 psa_set_key_algorithm( &attributes, alg );
2546 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002547
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002548 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002549 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002550
Gilles Peskine8817f612018-12-18 00:18:46 +01002551 PSA_ASSERT( psa_mac_verify_setup( &operation,
2552 handle, alg ) );
2553 PSA_ASSERT( psa_destroy_key( handle ) );
2554 PSA_ASSERT( psa_mac_update( &operation,
2555 input->x, input->len ) );
2556 PSA_ASSERT( psa_mac_verify_finish( &operation,
2557 expected_mac->x,
2558 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002559
2560exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002561 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002562 mbedtls_psa_crypto_free( );
2563}
2564/* END_CASE */
2565
2566/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002567void cipher_operation_init( )
2568{
Jaeden Ameroab439972019-02-15 14:12:05 +00002569 const uint8_t input[1] = { 0 };
2570 unsigned char output[1] = { 0 };
2571 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002572 /* Test each valid way of initializing the object, except for `= {0}`, as
2573 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2574 * though it's OK by the C standard. We could test for this, but we'd need
2575 * to supress the Clang warning for the test. */
2576 psa_cipher_operation_t func = psa_cipher_operation_init( );
2577 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2578 psa_cipher_operation_t zero;
2579
2580 memset( &zero, 0, sizeof( zero ) );
2581
Jaeden Ameroab439972019-02-15 14:12:05 +00002582 /* A freshly-initialized cipher operation should not be usable. */
2583 TEST_EQUAL( psa_cipher_update( &func,
2584 input, sizeof( input ),
2585 output, sizeof( output ),
2586 &output_length ),
2587 PSA_ERROR_BAD_STATE );
2588 TEST_EQUAL( psa_cipher_update( &init,
2589 input, sizeof( input ),
2590 output, sizeof( output ),
2591 &output_length ),
2592 PSA_ERROR_BAD_STATE );
2593 TEST_EQUAL( psa_cipher_update( &zero,
2594 input, sizeof( input ),
2595 output, sizeof( output ),
2596 &output_length ),
2597 PSA_ERROR_BAD_STATE );
2598
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002599 /* A default cipher operation should be abortable without error. */
2600 PSA_ASSERT( psa_cipher_abort( &func ) );
2601 PSA_ASSERT( psa_cipher_abort( &init ) );
2602 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002603}
2604/* END_CASE */
2605
2606/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002607void cipher_setup( int key_type_arg,
2608 data_t *key,
2609 int alg_arg,
2610 int expected_status_arg )
2611{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002612 psa_key_type_t key_type = key_type_arg;
2613 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002614 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002615 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002616 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002617#if defined(KNOWN_SUPPORTED_MAC_ALG)
2618 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2619#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002620
Gilles Peskine8817f612018-12-18 00:18:46 +01002621 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002622
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002623 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2624 &operation, &status ) )
2625 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002626 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002627
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002628 /* The operation object should be reusable. */
2629#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2630 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2631 smoke_test_key_data,
2632 sizeof( smoke_test_key_data ),
2633 KNOWN_SUPPORTED_CIPHER_ALG,
2634 &operation, &status ) )
2635 goto exit;
2636 TEST_EQUAL( status, PSA_SUCCESS );
2637#endif
2638
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002639exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002640 mbedtls_psa_crypto_free( );
2641}
2642/* END_CASE */
2643
2644/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002645void cipher_bad_order( )
2646{
2647 psa_key_handle_t handle = 0;
2648 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2649 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002650 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002651 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2652 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2653 const uint8_t key[] = {
2654 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2655 0xaa, 0xaa, 0xaa, 0xaa };
2656 const uint8_t text[] = {
2657 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2658 0xbb, 0xbb, 0xbb, 0xbb };
2659 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2660 size_t length = 0;
2661
2662 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002663 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2664 psa_set_key_algorithm( &attributes, alg );
2665 psa_set_key_type( &attributes, key_type );
2666 PSA_ASSERT( psa_import_key( &attributes, &handle,
Jaeden Ameroab439972019-02-15 14:12:05 +00002667 key, sizeof(key) ) );
2668
2669
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002670 /* Call encrypt setup twice in a row. */
2671 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2672 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2673 PSA_ERROR_BAD_STATE );
2674 PSA_ASSERT( psa_cipher_abort( &operation ) );
2675
2676 /* Call decrypt setup twice in a row. */
2677 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2678 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2679 PSA_ERROR_BAD_STATE );
2680 PSA_ASSERT( psa_cipher_abort( &operation ) );
2681
Jaeden Ameroab439972019-02-15 14:12:05 +00002682 /* Generate an IV without calling setup beforehand. */
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 twice in a row. */
2690 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2691 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2692 buffer, sizeof( buffer ),
2693 &length ) );
2694 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2695 buffer, sizeof( buffer ),
2696 &length ),
2697 PSA_ERROR_BAD_STATE );
2698 PSA_ASSERT( psa_cipher_abort( &operation ) );
2699
2700 /* Generate an IV after it's already set. */
2701 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2702 PSA_ASSERT( psa_cipher_set_iv( &operation,
2703 iv, sizeof( iv ) ) );
2704 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2705 buffer, sizeof( buffer ),
2706 &length ),
2707 PSA_ERROR_BAD_STATE );
2708 PSA_ASSERT( psa_cipher_abort( &operation ) );
2709
2710 /* Set an IV without calling setup beforehand. */
2711 TEST_EQUAL( psa_cipher_set_iv( &operation,
2712 iv, sizeof( iv ) ),
2713 PSA_ERROR_BAD_STATE );
2714 PSA_ASSERT( psa_cipher_abort( &operation ) );
2715
2716 /* Set an IV after it's already set. */
2717 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2718 PSA_ASSERT( psa_cipher_set_iv( &operation,
2719 iv, sizeof( iv ) ) );
2720 TEST_EQUAL( psa_cipher_set_iv( &operation,
2721 iv, sizeof( iv ) ),
2722 PSA_ERROR_BAD_STATE );
2723 PSA_ASSERT( psa_cipher_abort( &operation ) );
2724
2725 /* Set an IV after it's already generated. */
2726 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2727 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2728 buffer, sizeof( buffer ),
2729 &length ) );
2730 TEST_EQUAL( psa_cipher_set_iv( &operation,
2731 iv, sizeof( iv ) ),
2732 PSA_ERROR_BAD_STATE );
2733 PSA_ASSERT( psa_cipher_abort( &operation ) );
2734
2735 /* Call update without calling setup beforehand. */
2736 TEST_EQUAL( psa_cipher_update( &operation,
2737 text, sizeof( text ),
2738 buffer, sizeof( buffer ),
2739 &length ),
2740 PSA_ERROR_BAD_STATE );
2741 PSA_ASSERT( psa_cipher_abort( &operation ) );
2742
2743 /* Call update without an IV where an IV is required. */
2744 TEST_EQUAL( psa_cipher_update( &operation,
2745 text, sizeof( text ),
2746 buffer, sizeof( buffer ),
2747 &length ),
2748 PSA_ERROR_BAD_STATE );
2749 PSA_ASSERT( psa_cipher_abort( &operation ) );
2750
2751 /* Call update after finish. */
2752 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2753 PSA_ASSERT( psa_cipher_set_iv( &operation,
2754 iv, sizeof( iv ) ) );
2755 PSA_ASSERT( psa_cipher_finish( &operation,
2756 buffer, sizeof( buffer ), &length ) );
2757 TEST_EQUAL( psa_cipher_update( &operation,
2758 text, sizeof( text ),
2759 buffer, sizeof( buffer ),
2760 &length ),
2761 PSA_ERROR_BAD_STATE );
2762 PSA_ASSERT( psa_cipher_abort( &operation ) );
2763
2764 /* Call finish without calling setup beforehand. */
2765 TEST_EQUAL( psa_cipher_finish( &operation,
2766 buffer, sizeof( buffer ), &length ),
2767 PSA_ERROR_BAD_STATE );
2768 PSA_ASSERT( psa_cipher_abort( &operation ) );
2769
2770 /* Call finish without an IV where an IV is required. */
2771 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2772 /* Not calling update means we are encrypting an empty buffer, which is OK
2773 * for cipher modes with padding. */
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
2779 /* Call finish twice in a row. */
2780 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2781 PSA_ASSERT( psa_cipher_set_iv( &operation,
2782 iv, sizeof( iv ) ) );
2783 PSA_ASSERT( psa_cipher_finish( &operation,
2784 buffer, sizeof( buffer ), &length ) );
2785 TEST_EQUAL( psa_cipher_finish( &operation,
2786 buffer, sizeof( buffer ), &length ),
2787 PSA_ERROR_BAD_STATE );
2788 PSA_ASSERT( psa_cipher_abort( &operation ) );
2789
2790exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002791 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002792}
2793/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002794
Gilles Peskine50e586b2018-06-08 14:28:46 +02002795/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002796void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002797 data_t *key,
2798 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002799 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002800{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002801 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002802 psa_status_t status;
2803 psa_key_type_t key_type = key_type_arg;
2804 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002805 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002806 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002807 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002808 unsigned char *output = NULL;
2809 size_t output_buffer_size = 0;
2810 size_t function_output_length = 0;
2811 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002812 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002813 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002814
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002815 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2816 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002817
Gilles Peskine8817f612018-12-18 00:18:46 +01002818 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002819
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002820 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2821 psa_set_key_algorithm( &attributes, alg );
2822 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002823
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002824 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002825 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002826
Gilles Peskine8817f612018-12-18 00:18:46 +01002827 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2828 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002829
Gilles Peskine8817f612018-12-18 00:18:46 +01002830 PSA_ASSERT( psa_cipher_set_iv( &operation,
2831 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002832 output_buffer_size = ( (size_t) input->len +
2833 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002834 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002835
Gilles Peskine8817f612018-12-18 00:18:46 +01002836 PSA_ASSERT( psa_cipher_update( &operation,
2837 input->x, input->len,
2838 output, output_buffer_size,
2839 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002840 total_output_length += function_output_length;
2841 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002842 output + total_output_length,
2843 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002844 &function_output_length );
2845 total_output_length += function_output_length;
2846
Gilles Peskinefe11b722018-12-18 00:24:04 +01002847 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002848 if( expected_status == PSA_SUCCESS )
2849 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002850 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002851 ASSERT_COMPARE( expected_output->x, expected_output->len,
2852 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002853 }
2854
2855exit:
2856 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002857 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002858 mbedtls_psa_crypto_free( );
2859}
2860/* END_CASE */
2861
2862/* BEGIN_CASE */
2863void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
2864 data_t *key,
2865 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002866 int first_part_size_arg,
2867 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002868 data_t *expected_output )
2869{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002870 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002871 psa_key_type_t key_type = key_type_arg;
2872 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002873 size_t first_part_size = first_part_size_arg;
2874 size_t output1_length = output1_length_arg;
2875 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002876 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002877 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002878 unsigned char *output = NULL;
2879 size_t output_buffer_size = 0;
2880 size_t function_output_length = 0;
2881 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002882 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002883 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002884
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002885 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2886 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002887
Gilles Peskine8817f612018-12-18 00:18:46 +01002888 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002889
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002890 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2891 psa_set_key_algorithm( &attributes, alg );
2892 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002893
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002894 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002895 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002896
Gilles Peskine8817f612018-12-18 00:18:46 +01002897 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2898 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002899
Gilles Peskine8817f612018-12-18 00:18:46 +01002900 PSA_ASSERT( psa_cipher_set_iv( &operation,
2901 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002902 output_buffer_size = ( (size_t) input->len +
2903 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002904 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002905
Gilles Peskinee0866522019-02-19 19:44:00 +01002906 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002907 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2908 output, output_buffer_size,
2909 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002910 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002911 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002912 PSA_ASSERT( psa_cipher_update( &operation,
2913 input->x + first_part_size,
2914 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002915 output + total_output_length,
2916 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002917 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002918 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002919 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002920 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002921 output + total_output_length,
2922 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002923 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002924 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002925 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002926
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002927 ASSERT_COMPARE( expected_output->x, expected_output->len,
2928 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002929
2930exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002931 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002932 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933 mbedtls_psa_crypto_free( );
2934}
2935/* END_CASE */
2936
2937/* BEGIN_CASE */
2938void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002939 data_t *key,
2940 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002941 int first_part_size_arg,
2942 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002943 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002944{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002945 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002946
2947 psa_key_type_t key_type = key_type_arg;
2948 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002949 size_t first_part_size = first_part_size_arg;
2950 size_t output1_length = output1_length_arg;
2951 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002953 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002954 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002955 size_t output_buffer_size = 0;
2956 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002957 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002958 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002959 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002960
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002961 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2962 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002963
Gilles Peskine8817f612018-12-18 00:18:46 +01002964 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002965
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002966 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
2967 psa_set_key_algorithm( &attributes, alg );
2968 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002969
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002970 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002971 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002972
Gilles Peskine8817f612018-12-18 00:18:46 +01002973 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
2974 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002975
Gilles Peskine8817f612018-12-18 00:18:46 +01002976 PSA_ASSERT( psa_cipher_set_iv( &operation,
2977 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002978
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002979 output_buffer_size = ( (size_t) input->len +
2980 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002981 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002982
Gilles Peskinee0866522019-02-19 19:44:00 +01002983 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002984 PSA_ASSERT( psa_cipher_update( &operation,
2985 input->x, first_part_size,
2986 output, output_buffer_size,
2987 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002988 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002989 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002990 PSA_ASSERT( psa_cipher_update( &operation,
2991 input->x + first_part_size,
2992 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002993 output + total_output_length,
2994 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002995 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002996 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002997 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002998 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002999 output + total_output_length,
3000 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003001 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003002 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003003 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003004
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003005 ASSERT_COMPARE( expected_output->x, expected_output->len,
3006 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003007
3008exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003009 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003010 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003011 mbedtls_psa_crypto_free( );
3012}
3013/* END_CASE */
3014
Gilles Peskine50e586b2018-06-08 14:28:46 +02003015/* BEGIN_CASE */
3016void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003017 data_t *key,
3018 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003019 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003020{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003021 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003022 psa_status_t status;
3023 psa_key_type_t key_type = key_type_arg;
3024 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003025 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003026 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003027 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003028 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003029 size_t output_buffer_size = 0;
3030 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003031 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003032 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003033 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003034
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003035 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3036 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003037
Gilles Peskine8817f612018-12-18 00:18:46 +01003038 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003039
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003040 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3041 psa_set_key_algorithm( &attributes, alg );
3042 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003043
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003044 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003045 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003046
Gilles Peskine8817f612018-12-18 00:18:46 +01003047 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3048 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003049
Gilles Peskine8817f612018-12-18 00:18:46 +01003050 PSA_ASSERT( psa_cipher_set_iv( &operation,
3051 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003052
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003053 output_buffer_size = ( (size_t) input->len +
3054 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003055 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003056
Gilles Peskine8817f612018-12-18 00:18:46 +01003057 PSA_ASSERT( psa_cipher_update( &operation,
3058 input->x, input->len,
3059 output, output_buffer_size,
3060 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003061 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003062 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003063 output + total_output_length,
3064 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003066 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003067 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003068
3069 if( expected_status == PSA_SUCCESS )
3070 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003071 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003072 ASSERT_COMPARE( expected_output->x, expected_output->len,
3073 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074 }
3075
Gilles Peskine50e586b2018-06-08 14:28:46 +02003076exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003077 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003078 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003079 mbedtls_psa_crypto_free( );
3080}
3081/* END_CASE */
3082
Gilles Peskine50e586b2018-06-08 14:28:46 +02003083/* BEGIN_CASE */
3084void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003085 data_t *key,
3086 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003087{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003088 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003089 psa_key_type_t key_type = key_type_arg;
3090 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003091 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003092 size_t iv_size = 16;
3093 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003094 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003095 size_t output1_size = 0;
3096 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003097 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003098 size_t output2_size = 0;
3099 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003100 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003101 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3102 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003103 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003104
Gilles Peskine8817f612018-12-18 00:18:46 +01003105 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003106
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003107 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3108 psa_set_key_algorithm( &attributes, alg );
3109 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003110
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003111 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003112 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003113
Gilles Peskine8817f612018-12-18 00:18:46 +01003114 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3115 handle, alg ) );
3116 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3117 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003118
Gilles Peskine8817f612018-12-18 00:18:46 +01003119 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3120 iv, iv_size,
3121 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003122 output1_size = ( (size_t) input->len +
3123 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003124 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003125
Gilles Peskine8817f612018-12-18 00:18:46 +01003126 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3127 output1, output1_size,
3128 &output1_length ) );
3129 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003130 output1 + output1_length,
3131 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003132 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003133
Gilles Peskine048b7f02018-06-08 14:20:49 +02003134 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003135
Gilles Peskine8817f612018-12-18 00:18:46 +01003136 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003137
3138 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003139 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003140
Gilles Peskine8817f612018-12-18 00:18:46 +01003141 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3142 iv, iv_length ) );
3143 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3144 output2, output2_size,
3145 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003146 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003147 PSA_ASSERT( psa_cipher_finish( &operation2,
3148 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003149 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003150 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003151
Gilles Peskine048b7f02018-06-08 14:20:49 +02003152 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003153
Gilles Peskine8817f612018-12-18 00:18:46 +01003154 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003155
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003156 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003157
3158exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003159 mbedtls_free( output1 );
3160 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003161 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003162 mbedtls_psa_crypto_free( );
3163}
3164/* END_CASE */
3165
3166/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003167void cipher_verify_output_multipart( int alg_arg,
3168 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003169 data_t *key,
3170 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003171 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003172{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003173 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003174 psa_key_type_t key_type = key_type_arg;
3175 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003176 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003177 unsigned char iv[16] = {0};
3178 size_t iv_size = 16;
3179 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003180 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003181 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003182 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003183 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003184 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003185 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003186 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003187 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3188 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003189 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003190
Gilles Peskine8817f612018-12-18 00:18:46 +01003191 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003192
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003193 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3194 psa_set_key_algorithm( &attributes, alg );
3195 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003196
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003197 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003198 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003199
Gilles Peskine8817f612018-12-18 00:18:46 +01003200 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3201 handle, alg ) );
3202 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3203 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003204
Gilles Peskine8817f612018-12-18 00:18:46 +01003205 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3206 iv, iv_size,
3207 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003208 output1_buffer_size = ( (size_t) input->len +
3209 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003210 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003211
Gilles Peskinee0866522019-02-19 19:44:00 +01003212 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003213
Gilles Peskine8817f612018-12-18 00:18:46 +01003214 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3215 output1, output1_buffer_size,
3216 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003217 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003218
Gilles Peskine8817f612018-12-18 00:18:46 +01003219 PSA_ASSERT( psa_cipher_update( &operation1,
3220 input->x + first_part_size,
3221 input->len - first_part_size,
3222 output1, output1_buffer_size,
3223 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003224 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003225
Gilles Peskine8817f612018-12-18 00:18:46 +01003226 PSA_ASSERT( psa_cipher_finish( &operation1,
3227 output1 + output1_length,
3228 output1_buffer_size - output1_length,
3229 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003230 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003231
Gilles Peskine8817f612018-12-18 00:18:46 +01003232 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003233
Gilles Peskine048b7f02018-06-08 14:20:49 +02003234 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003235 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003236
Gilles Peskine8817f612018-12-18 00:18:46 +01003237 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3238 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003239
Gilles Peskine8817f612018-12-18 00:18:46 +01003240 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3241 output2, output2_buffer_size,
3242 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003243 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003244
Gilles Peskine8817f612018-12-18 00:18:46 +01003245 PSA_ASSERT( psa_cipher_update( &operation2,
3246 output1 + first_part_size,
3247 output1_length - first_part_size,
3248 output2, output2_buffer_size,
3249 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003250 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003251
Gilles Peskine8817f612018-12-18 00:18:46 +01003252 PSA_ASSERT( psa_cipher_finish( &operation2,
3253 output2 + output2_length,
3254 output2_buffer_size - output2_length,
3255 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003256 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003257
Gilles Peskine8817f612018-12-18 00:18:46 +01003258 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003259
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003260 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003261
3262exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003263 mbedtls_free( output1 );
3264 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003265 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003266 mbedtls_psa_crypto_free( );
3267}
3268/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003269
Gilles Peskine20035e32018-02-03 22:44:14 +01003270/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003271void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003272 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003273 data_t *nonce,
3274 data_t *additional_data,
3275 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003276 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003277{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003278 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003279 psa_key_type_t key_type = key_type_arg;
3280 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003281 unsigned char *output_data = NULL;
3282 size_t output_size = 0;
3283 size_t output_length = 0;
3284 unsigned char *output_data2 = NULL;
3285 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003286 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003287 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003288 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003289
Gilles Peskine4abf7412018-06-18 16:35:34 +02003290 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003291 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003292
Gilles Peskine8817f612018-12-18 00:18:46 +01003293 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003294
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003295 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3296 psa_set_key_algorithm( &attributes, alg );
3297 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003298
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003299 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003300 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003301
Gilles Peskinefe11b722018-12-18 00:24:04 +01003302 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3303 nonce->x, nonce->len,
3304 additional_data->x,
3305 additional_data->len,
3306 input_data->x, input_data->len,
3307 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003308 &output_length ),
3309 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003310
3311 if( PSA_SUCCESS == expected_result )
3312 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003313 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003314
Gilles Peskinefe11b722018-12-18 00:24:04 +01003315 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3316 nonce->x, nonce->len,
3317 additional_data->x,
3318 additional_data->len,
3319 output_data, output_length,
3320 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003321 &output_length2 ),
3322 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003323
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003324 ASSERT_COMPARE( input_data->x, input_data->len,
3325 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003326 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003327
Gilles Peskinea1cac842018-06-11 19:33:02 +02003328exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003329 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003330 mbedtls_free( output_data );
3331 mbedtls_free( output_data2 );
3332 mbedtls_psa_crypto_free( );
3333}
3334/* END_CASE */
3335
3336/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003337void aead_encrypt( int key_type_arg, data_t *key_data,
3338 int alg_arg,
3339 data_t *nonce,
3340 data_t *additional_data,
3341 data_t *input_data,
3342 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003343{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003344 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003345 psa_key_type_t key_type = key_type_arg;
3346 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003347 unsigned char *output_data = NULL;
3348 size_t output_size = 0;
3349 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003350 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003351 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003352
Gilles Peskine4abf7412018-06-18 16:35:34 +02003353 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003354 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003355
Gilles Peskine8817f612018-12-18 00:18:46 +01003356 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003357
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003358 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3359 psa_set_key_algorithm( &attributes, alg );
3360 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003361
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003362 PSA_ASSERT( psa_import_key( &attributes, &handle,
3363 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003364
Gilles Peskine8817f612018-12-18 00:18:46 +01003365 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3366 nonce->x, nonce->len,
3367 additional_data->x, additional_data->len,
3368 input_data->x, input_data->len,
3369 output_data, output_size,
3370 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003371
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003372 ASSERT_COMPARE( expected_result->x, expected_result->len,
3373 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003374
Gilles Peskinea1cac842018-06-11 19:33:02 +02003375exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003376 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003377 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003378 mbedtls_psa_crypto_free( );
3379}
3380/* END_CASE */
3381
3382/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003383void aead_decrypt( int key_type_arg, data_t *key_data,
3384 int alg_arg,
3385 data_t *nonce,
3386 data_t *additional_data,
3387 data_t *input_data,
3388 data_t *expected_data,
3389 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003390{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003391 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003392 psa_key_type_t key_type = key_type_arg;
3393 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003394 unsigned char *output_data = NULL;
3395 size_t output_size = 0;
3396 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003397 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003398 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003399 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400
Gilles Peskine4abf7412018-06-18 16:35:34 +02003401 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003402 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003403
Gilles Peskine8817f612018-12-18 00:18:46 +01003404 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003405
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003406 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3407 psa_set_key_algorithm( &attributes, alg );
3408 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003409
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003410 PSA_ASSERT( psa_import_key( &attributes, &handle,
3411 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003412
Gilles Peskinefe11b722018-12-18 00:24:04 +01003413 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3414 nonce->x, nonce->len,
3415 additional_data->x,
3416 additional_data->len,
3417 input_data->x, input_data->len,
3418 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003419 &output_length ),
3420 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421
Gilles Peskine2d277862018-06-18 15:41:12 +02003422 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003423 ASSERT_COMPARE( expected_data->x, expected_data->len,
3424 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003425
Gilles Peskinea1cac842018-06-11 19:33:02 +02003426exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003427 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003428 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003429 mbedtls_psa_crypto_free( );
3430}
3431/* END_CASE */
3432
3433/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003434void signature_size( int type_arg,
3435 int bits,
3436 int alg_arg,
3437 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003438{
3439 psa_key_type_t type = type_arg;
3440 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003441 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003442 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003443exit:
3444 ;
3445}
3446/* END_CASE */
3447
3448/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003449void sign_deterministic( int key_type_arg, data_t *key_data,
3450 int alg_arg, data_t *input_data,
3451 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003452{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003453 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003454 psa_key_type_t key_type = key_type_arg;
3455 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003456 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003457 unsigned char *signature = NULL;
3458 size_t signature_size;
3459 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003460 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003461
Gilles Peskine8817f612018-12-18 00:18:46 +01003462 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003463
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003464 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3465 psa_set_key_algorithm( &attributes, alg );
3466 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003467
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003468 PSA_ASSERT( psa_import_key( &attributes, &handle,
3469 key_data->x, key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003470 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3471 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003472
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003473 /* Allocate a buffer which has the size advertized by the
3474 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003475 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3476 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003477 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003478 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003479 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003480
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003481 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003482 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3483 input_data->x, input_data->len,
3484 signature, signature_size,
3485 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003486 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003487 ASSERT_COMPARE( output_data->x, output_data->len,
3488 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003489
3490exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003491 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003492 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003493 mbedtls_psa_crypto_free( );
3494}
3495/* END_CASE */
3496
3497/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003498void sign_fail( int key_type_arg, data_t *key_data,
3499 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003500 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003501{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003502 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003503 psa_key_type_t key_type = key_type_arg;
3504 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003505 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003506 psa_status_t actual_status;
3507 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003508 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003509 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003510 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003511
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003512 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003513
Gilles Peskine8817f612018-12-18 00:18:46 +01003514 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003515
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003516 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3517 psa_set_key_algorithm( &attributes, alg );
3518 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003519
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003520 PSA_ASSERT( psa_import_key( &attributes, &handle,
3521 key_data->x, key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003522
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003523 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003524 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003525 signature, signature_size,
3526 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003527 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003528 /* The value of *signature_length is unspecified on error, but
3529 * whatever it is, it should be less than signature_size, so that
3530 * if the caller tries to read *signature_length bytes without
3531 * checking the error code then they don't overflow a buffer. */
3532 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003533
3534exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003535 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003536 mbedtls_free( signature );
3537 mbedtls_psa_crypto_free( );
3538}
3539/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003540
3541/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003542void sign_verify( int key_type_arg, data_t *key_data,
3543 int alg_arg, data_t *input_data )
3544{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003545 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003546 psa_key_type_t key_type = key_type_arg;
3547 psa_algorithm_t alg = alg_arg;
3548 size_t key_bits;
3549 unsigned char *signature = NULL;
3550 size_t signature_size;
3551 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003552 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003553
Gilles Peskine8817f612018-12-18 00:18:46 +01003554 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003555
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003556 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3557 psa_set_key_algorithm( &attributes, alg );
3558 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003559
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003560 PSA_ASSERT( psa_import_key( &attributes, &handle,
3561 key_data->x, 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;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003615 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_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 Peskine2c2cf0e2019-04-19 19:58:20 +02003621 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3622 psa_set_key_algorithm( &attributes, alg );
3623 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003624
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003625 PSA_ASSERT( psa_import_key( &attributes, &handle,
3626 key_data->x, key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003627
Gilles Peskine8817f612018-12-18 00:18:46 +01003628 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3629 hash_data->x, hash_data->len,
3630 signature_data->x,
3631 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003632exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003633 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003634 mbedtls_psa_crypto_free( );
3635}
3636/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003637
3638/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003639void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3640 int alg_arg, data_t *hash_data,
3641 data_t *signature_data,
3642 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003643{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003644 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003645 psa_key_type_t key_type = key_type_arg;
3646 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003647 psa_status_t actual_status;
3648 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003649 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003650
Gilles Peskine8817f612018-12-18 00:18:46 +01003651 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003652
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003653 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3654 psa_set_key_algorithm( &attributes, alg );
3655 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003656
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003657 PSA_ASSERT( psa_import_key( &attributes, &handle,
3658 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003659
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003660 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003661 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003662 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003663 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003664
Gilles Peskinefe11b722018-12-18 00:24:04 +01003665 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003666
3667exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003668 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003669 mbedtls_psa_crypto_free( );
3670}
3671/* END_CASE */
3672
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003673/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003674void asymmetric_encrypt( int key_type_arg,
3675 data_t *key_data,
3676 int alg_arg,
3677 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003678 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003679 int expected_output_length_arg,
3680 int expected_status_arg )
3681{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003682 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003683 psa_key_type_t key_type = key_type_arg;
3684 psa_algorithm_t alg = alg_arg;
3685 size_t expected_output_length = expected_output_length_arg;
3686 size_t key_bits;
3687 unsigned char *output = NULL;
3688 size_t output_size;
3689 size_t output_length = ~0;
3690 psa_status_t actual_status;
3691 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003692 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003693
Gilles Peskine8817f612018-12-18 00:18:46 +01003694 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003695
Gilles Peskine656896e2018-06-29 19:12:28 +02003696 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003697 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3698 psa_set_key_algorithm( &attributes, alg );
3699 psa_set_key_type( &attributes, key_type );
3700 PSA_ASSERT( psa_import_key( &attributes, &handle,
3701 key_data->x, key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003702
3703 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003704 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3705 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003706 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003707 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003708
3709 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003710 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003711 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003712 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003713 output, output_size,
3714 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003715 TEST_EQUAL( actual_status, expected_status );
3716 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003717
Gilles Peskine68428122018-06-30 18:42:41 +02003718 /* If the label is empty, the test framework puts a non-null pointer
3719 * in label->x. Test that a null pointer works as well. */
3720 if( label->len == 0 )
3721 {
3722 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003723 if( output_size != 0 )
3724 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003725 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003726 input_data->x, input_data->len,
3727 NULL, label->len,
3728 output, output_size,
3729 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003730 TEST_EQUAL( actual_status, expected_status );
3731 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003732 }
3733
Gilles Peskine656896e2018-06-29 19:12:28 +02003734exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003735 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003736 mbedtls_free( output );
3737 mbedtls_psa_crypto_free( );
3738}
3739/* END_CASE */
3740
3741/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003742void asymmetric_encrypt_decrypt( int key_type_arg,
3743 data_t *key_data,
3744 int alg_arg,
3745 data_t *input_data,
3746 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003747{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003748 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003749 psa_key_type_t key_type = key_type_arg;
3750 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003751 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003752 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003753 size_t output_size;
3754 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003755 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003756 size_t output2_size;
3757 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003758 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003759
Gilles Peskine8817f612018-12-18 00:18:46 +01003760 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003761
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003762 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3763 psa_set_key_algorithm( &attributes, alg );
3764 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003765
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003766 PSA_ASSERT( psa_import_key( &attributes, &handle,
3767 key_data->x, key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003768
3769 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003770 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3771 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003772 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003773 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003774 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003775 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003776
Gilles Peskineeebd7382018-06-08 18:11:54 +02003777 /* We test encryption by checking that encrypt-then-decrypt gives back
3778 * the original plaintext because of the non-optional random
3779 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003780 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3781 input_data->x, input_data->len,
3782 label->x, label->len,
3783 output, output_size,
3784 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003785 /* We don't know what ciphertext length to expect, but check that
3786 * it looks sensible. */
3787 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003788
Gilles Peskine8817f612018-12-18 00:18:46 +01003789 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3790 output, output_length,
3791 label->x, label->len,
3792 output2, output2_size,
3793 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003794 ASSERT_COMPARE( input_data->x, input_data->len,
3795 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003796
3797exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003798 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003799 mbedtls_free( output );
3800 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003801 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003802}
3803/* END_CASE */
3804
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003805/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003806void asymmetric_decrypt( int key_type_arg,
3807 data_t *key_data,
3808 int alg_arg,
3809 data_t *input_data,
3810 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003811 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003812{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003813 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003814 psa_key_type_t key_type = key_type_arg;
3815 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003816 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003817 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003818 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003819 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003820
Jaeden Amero412654a2019-02-06 12:57:46 +00003821 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003822 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003823
Gilles Peskine8817f612018-12-18 00:18:46 +01003824 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003825
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003826 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3827 psa_set_key_algorithm( &attributes, alg );
3828 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003829
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003830 PSA_ASSERT( psa_import_key( &attributes, &handle,
3831 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003832
Gilles Peskine8817f612018-12-18 00:18:46 +01003833 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3834 input_data->x, input_data->len,
3835 label->x, label->len,
3836 output,
3837 output_size,
3838 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003839 ASSERT_COMPARE( expected_data->x, expected_data->len,
3840 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003841
Gilles Peskine68428122018-06-30 18:42:41 +02003842 /* If the label is empty, the test framework puts a non-null pointer
3843 * in label->x. Test that a null pointer works as well. */
3844 if( label->len == 0 )
3845 {
3846 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003847 if( output_size != 0 )
3848 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003849 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3850 input_data->x, input_data->len,
3851 NULL, label->len,
3852 output,
3853 output_size,
3854 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003855 ASSERT_COMPARE( expected_data->x, expected_data->len,
3856 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003857 }
3858
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003859exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003860 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003861 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003862 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003863}
3864/* END_CASE */
3865
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003866/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003867void asymmetric_decrypt_fail( int key_type_arg,
3868 data_t *key_data,
3869 int alg_arg,
3870 data_t *input_data,
3871 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003872 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003873 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003874{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003875 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876 psa_key_type_t key_type = key_type_arg;
3877 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003878 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003879 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003880 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881 psa_status_t actual_status;
3882 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003883 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003884
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003885 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003886
Gilles Peskine8817f612018-12-18 00:18:46 +01003887 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003888
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003889 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3890 psa_set_key_algorithm( &attributes, alg );
3891 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003892
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003893 PSA_ASSERT( psa_import_key( &attributes, &handle,
3894 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003895
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003896 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003897 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003898 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003899 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003900 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003901 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003902 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003903
Gilles Peskine68428122018-06-30 18:42:41 +02003904 /* If the label is empty, the test framework puts a non-null pointer
3905 * in label->x. Test that a null pointer works as well. */
3906 if( label->len == 0 )
3907 {
3908 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003909 if( output_size != 0 )
3910 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003911 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003912 input_data->x, input_data->len,
3913 NULL, label->len,
3914 output, output_size,
3915 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003916 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003917 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003918 }
3919
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003920exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003921 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003922 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003923 mbedtls_psa_crypto_free( );
3924}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003925/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003926
3927/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00003928void crypto_generator_init( )
3929{
3930 /* Test each valid way of initializing the object, except for `= {0}`, as
3931 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
3932 * though it's OK by the C standard. We could test for this, but we'd need
3933 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003934 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00003935 psa_crypto_generator_t func = psa_crypto_generator_init( );
3936 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
3937 psa_crypto_generator_t zero;
3938
3939 memset( &zero, 0, sizeof( zero ) );
3940
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003941 /* A default generator should not be able to report its capacity. */
3942 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
3943 PSA_ERROR_BAD_STATE );
3944 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
3945 PSA_ERROR_BAD_STATE );
3946 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
3947 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003948
3949 /* A default generator should be abortable without error. */
3950 PSA_ASSERT( psa_generator_abort(&func) );
3951 PSA_ASSERT( psa_generator_abort(&init) );
3952 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00003953}
3954/* END_CASE */
3955
3956/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02003957void derive_setup( int key_type_arg,
3958 data_t *key_data,
3959 int alg_arg,
3960 data_t *salt,
3961 data_t *label,
3962 int requested_capacity_arg,
3963 int expected_status_arg )
3964{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003965 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003966 size_t key_type = key_type_arg;
3967 psa_algorithm_t alg = alg_arg;
3968 size_t requested_capacity = requested_capacity_arg;
3969 psa_status_t expected_status = expected_status_arg;
3970 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003971 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003972
Gilles Peskine8817f612018-12-18 00:18:46 +01003973 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003974
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003975 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
3976 psa_set_key_algorithm( &attributes, alg );
3977 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003978
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003979 PSA_ASSERT( psa_import_key( &attributes, &handle,
3980 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003981
Gilles Peskinefe11b722018-12-18 00:24:04 +01003982 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
3983 salt->x, salt->len,
3984 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003985 requested_capacity ),
3986 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003987
3988exit:
3989 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003990 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003991 mbedtls_psa_crypto_free( );
3992}
3993/* END_CASE */
3994
3995/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02003996void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03003997{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003998 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02003999 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004000 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004001 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004002 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004003 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004004 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4005 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4006 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004007 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004008
Gilles Peskine8817f612018-12-18 00:18:46 +01004009 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004010
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004011 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4012 psa_set_key_algorithm( &attributes, alg );
4013 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004014
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004015 PSA_ASSERT( psa_import_key( &attributes, &handle,
4016 key_data, sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004017
4018 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004019 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4020 NULL, 0,
4021 NULL, 0,
4022 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004023
4024 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004025 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4026 NULL, 0,
4027 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004028 capacity ),
4029 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004030
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004031 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004032
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004033 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004034 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004035
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004036exit:
4037 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004038 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004039 mbedtls_psa_crypto_free( );
4040}
4041/* END_CASE */
4042
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004043/* BEGIN_CASE */
4044void test_derive_invalid_generator_tests( )
4045{
4046 uint8_t output_buffer[16];
4047 size_t buffer_size = 16;
4048 size_t capacity = 0;
4049 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4050
Nir Sonnenschein50789302018-10-31 12:16:38 +02004051 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004052 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004053
4054 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004055 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004056
Gilles Peskine8817f612018-12-18 00:18:46 +01004057 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004058
Nir Sonnenschein50789302018-10-31 12:16:38 +02004059 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004060 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004061
Nir Sonnenschein50789302018-10-31 12:16:38 +02004062 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004063 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004064
4065exit:
4066 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004067}
4068/* END_CASE */
4069
4070/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004071void derive_output( int alg_arg,
4072 data_t *key_data,
4073 data_t *salt,
4074 data_t *label,
4075 int requested_capacity_arg,
4076 data_t *expected_output1,
4077 data_t *expected_output2 )
4078{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004079 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004080 psa_algorithm_t alg = alg_arg;
4081 size_t requested_capacity = requested_capacity_arg;
4082 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4083 uint8_t *expected_outputs[2] =
4084 {expected_output1->x, expected_output2->x};
4085 size_t output_sizes[2] =
4086 {expected_output1->len, expected_output2->len};
4087 size_t output_buffer_size = 0;
4088 uint8_t *output_buffer = NULL;
4089 size_t expected_capacity;
4090 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004091 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004092 psa_status_t status;
4093 unsigned i;
4094
4095 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4096 {
4097 if( output_sizes[i] > output_buffer_size )
4098 output_buffer_size = output_sizes[i];
4099 if( output_sizes[i] == 0 )
4100 expected_outputs[i] = NULL;
4101 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004102 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004103 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004104
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004105 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4106 psa_set_key_algorithm( &attributes, alg );
4107 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004108
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004109 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004110 key_data->x, key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004111
4112 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004113 if( PSA_ALG_IS_HKDF( alg ) )
4114 {
4115 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4116 PSA_ASSERT( psa_set_generator_capacity( &generator,
4117 requested_capacity ) );
4118 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4119 PSA_KDF_STEP_SALT,
4120 salt->x, salt->len ) );
4121 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4122 PSA_KDF_STEP_SECRET,
4123 handle ) );
4124 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4125 PSA_KDF_STEP_INFO,
4126 label->x, label->len ) );
4127 }
4128 else
4129 {
4130 // legacy
4131 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4132 salt->x, salt->len,
4133 label->x, label->len,
4134 requested_capacity ) );
4135 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004136 PSA_ASSERT( psa_get_generator_capacity( &generator,
4137 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004138 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004139 expected_capacity = requested_capacity;
4140
4141 /* Expansion phase. */
4142 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4143 {
4144 /* Read some bytes. */
4145 status = psa_generator_read( &generator,
4146 output_buffer, output_sizes[i] );
4147 if( expected_capacity == 0 && output_sizes[i] == 0 )
4148 {
4149 /* Reading 0 bytes when 0 bytes are available can go either way. */
4150 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004151 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004152 continue;
4153 }
4154 else if( expected_capacity == 0 ||
4155 output_sizes[i] > expected_capacity )
4156 {
4157 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004158 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004159 expected_capacity = 0;
4160 continue;
4161 }
4162 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004163 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004164 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004165 ASSERT_COMPARE( output_buffer, output_sizes[i],
4166 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004167 /* Check the generator status. */
4168 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004169 PSA_ASSERT( psa_get_generator_capacity( &generator,
4170 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004171 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004172 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004173 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004174
4175exit:
4176 mbedtls_free( output_buffer );
4177 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004178 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004179 mbedtls_psa_crypto_free( );
4180}
4181/* END_CASE */
4182
4183/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004184void derive_full( int alg_arg,
4185 data_t *key_data,
4186 data_t *salt,
4187 data_t *label,
4188 int requested_capacity_arg )
4189{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004190 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004191 psa_algorithm_t alg = alg_arg;
4192 size_t requested_capacity = requested_capacity_arg;
4193 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4194 unsigned char output_buffer[16];
4195 size_t expected_capacity = requested_capacity;
4196 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004197 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004198
Gilles Peskine8817f612018-12-18 00:18:46 +01004199 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004200
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004201 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4202 psa_set_key_algorithm( &attributes, alg );
4203 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004204
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004205 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004206 key_data->x, key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004207
4208 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004209 if( PSA_ALG_IS_HKDF( alg ) )
4210 {
4211 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4212 PSA_ASSERT( psa_set_generator_capacity( &generator,
4213 requested_capacity ) );
4214 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4215 PSA_KDF_STEP_SALT,
4216 salt->x, salt->len ) );
4217 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4218 PSA_KDF_STEP_SECRET,
4219 handle ) );
4220 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4221 PSA_KDF_STEP_INFO,
4222 label->x, label->len ) );
4223 }
4224 else
4225 {
4226 // legacy
4227 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4228 salt->x, salt->len,
4229 label->x, label->len,
4230 requested_capacity ) );
4231 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004232 PSA_ASSERT( psa_get_generator_capacity( &generator,
4233 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004234 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004235
4236 /* Expansion phase. */
4237 while( current_capacity > 0 )
4238 {
4239 size_t read_size = sizeof( output_buffer );
4240 if( read_size > current_capacity )
4241 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004242 PSA_ASSERT( psa_generator_read( &generator,
4243 output_buffer,
4244 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004245 expected_capacity -= read_size;
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
4251 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004252 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004253 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004254
Gilles Peskine8817f612018-12-18 00:18:46 +01004255 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004256
4257exit:
4258 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004259 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004260 mbedtls_psa_crypto_free( );
4261}
4262/* END_CASE */
4263
4264/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004265void derive_key_exercise( int alg_arg,
4266 data_t *key_data,
4267 data_t *salt,
4268 data_t *label,
4269 int derived_type_arg,
4270 int derived_bits_arg,
4271 int derived_usage_arg,
4272 int derived_alg_arg )
4273{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004274 psa_key_handle_t base_handle = 0;
4275 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004276 psa_algorithm_t alg = alg_arg;
4277 psa_key_type_t derived_type = derived_type_arg;
4278 size_t derived_bits = derived_bits_arg;
4279 psa_key_usage_t derived_usage = derived_usage_arg;
4280 psa_algorithm_t derived_alg = derived_alg_arg;
4281 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4282 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004283 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004284 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004285
Gilles Peskine8817f612018-12-18 00:18:46 +01004286 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004287
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004288 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4289 psa_set_key_algorithm( &attributes, alg );
4290 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
4291 PSA_ASSERT( psa_import_key( &attributes, &base_handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004292 key_data->x, key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004293
4294 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004295 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4296 salt->x, salt->len,
4297 label->x, label->len,
4298 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004299 psa_set_key_usage_flags( &attributes, derived_usage );
4300 psa_set_key_algorithm( &attributes, derived_alg );
4301 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004302 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004303 PSA_ASSERT( psa_generator_import_key( &attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004304 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004305
4306 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004307 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4308 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4309 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004310
4311 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004312 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004313 goto exit;
4314
4315exit:
4316 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004317 psa_destroy_key( base_handle );
4318 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004319 mbedtls_psa_crypto_free( );
4320}
4321/* END_CASE */
4322
4323/* BEGIN_CASE */
4324void derive_key_export( int alg_arg,
4325 data_t *key_data,
4326 data_t *salt,
4327 data_t *label,
4328 int bytes1_arg,
4329 int bytes2_arg )
4330{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004331 psa_key_handle_t base_handle = 0;
4332 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004333 psa_algorithm_t alg = alg_arg;
4334 size_t bytes1 = bytes1_arg;
4335 size_t bytes2 = bytes2_arg;
4336 size_t capacity = bytes1 + bytes2;
4337 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004338 uint8_t *output_buffer = NULL;
4339 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004340 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4341 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004342 size_t length;
4343
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004344 ASSERT_ALLOC( output_buffer, capacity );
4345 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004346 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004347
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004348 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4349 psa_set_key_algorithm( &base_attributes, alg );
4350 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4351 PSA_ASSERT( psa_import_key( &base_attributes, &base_handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004352 key_data->x, key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004353
4354 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004355 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4356 salt->x, salt->len,
4357 label->x, label->len,
4358 capacity ) );
4359 PSA_ASSERT( psa_generator_read( &generator,
4360 output_buffer,
4361 capacity ) );
4362 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004363
4364 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004365 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4366 salt->x, salt->len,
4367 label->x, label->len,
4368 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004369 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4370 psa_set_key_algorithm( &derived_attributes, 0 );
4371 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004372 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004373 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004374 &generator ) );
4375 PSA_ASSERT( psa_export_key( derived_handle,
4376 export_buffer, bytes1,
4377 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004378 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004379 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004380 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004381 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004382 &generator ) );
4383 PSA_ASSERT( psa_export_key( derived_handle,
4384 export_buffer + bytes1, bytes2,
4385 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004386 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004387
4388 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004389 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4390 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004391
4392exit:
4393 mbedtls_free( output_buffer );
4394 mbedtls_free( export_buffer );
4395 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004396 psa_destroy_key( base_handle );
4397 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004398 mbedtls_psa_crypto_free( );
4399}
4400/* END_CASE */
4401
4402/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004403void key_agreement_setup( int alg_arg,
4404 int our_key_type_arg, data_t *our_key_data,
4405 data_t *peer_key_data,
4406 int expected_status_arg )
4407{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004408 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004409 psa_algorithm_t alg = alg_arg;
4410 psa_key_type_t our_key_type = our_key_type_arg;
4411 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004412 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004413 psa_status_t expected_status = expected_status_arg;
4414 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004415
Gilles Peskine8817f612018-12-18 00:18:46 +01004416 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004417
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004418 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4419 psa_set_key_algorithm( &attributes, alg );
4420 psa_set_key_type( &attributes, our_key_type );
4421 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004422 our_key_data->x, our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004423
Gilles Peskine77f40d82019-04-11 21:27:06 +02004424 /* The tests currently include inputs that should fail at either step.
4425 * Test cases that fail at the setup step should be changed to call
4426 * key_derivation_setup instead, and this function should be renamed
4427 * to key_agreement_fail. */
4428 status = psa_key_derivation_setup( &generator, alg );
4429 if( status == PSA_SUCCESS )
4430 {
4431 TEST_EQUAL( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
4432 our_key,
4433 peer_key_data->x, peer_key_data->len ),
4434 expected_status );
4435 }
4436 else
4437 {
4438 TEST_ASSERT( status == expected_status );
4439 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004440
4441exit:
4442 psa_generator_abort( &generator );
4443 psa_destroy_key( our_key );
4444 mbedtls_psa_crypto_free( );
4445}
4446/* END_CASE */
4447
4448/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004449void raw_key_agreement( int alg_arg,
4450 int our_key_type_arg, data_t *our_key_data,
4451 data_t *peer_key_data,
4452 data_t *expected_output )
4453{
4454 psa_key_handle_t our_key = 0;
4455 psa_algorithm_t alg = alg_arg;
4456 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004457 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004458 unsigned char *output = NULL;
4459 size_t output_length = ~0;
4460
4461 ASSERT_ALLOC( output, expected_output->len );
4462 PSA_ASSERT( psa_crypto_init( ) );
4463
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004464 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4465 psa_set_key_algorithm( &attributes, alg );
4466 psa_set_key_type( &attributes, our_key_type );
4467 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004468 our_key_data->x, our_key_data->len ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004469
4470 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4471 alg, our_key,
4472 peer_key_data->x, peer_key_data->len,
4473 output, expected_output->len, &output_length ) );
4474 ASSERT_COMPARE( output, output_length,
4475 expected_output->x, expected_output->len );
4476
4477exit:
4478 mbedtls_free( output );
4479 psa_destroy_key( our_key );
4480 mbedtls_psa_crypto_free( );
4481}
4482/* END_CASE */
4483
4484/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004485void key_agreement_capacity( int alg_arg,
4486 int our_key_type_arg, data_t *our_key_data,
4487 data_t *peer_key_data,
4488 int expected_capacity_arg )
4489{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004490 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004491 psa_algorithm_t alg = alg_arg;
4492 psa_key_type_t our_key_type = our_key_type_arg;
4493 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004494 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004495 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004496 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004497
Gilles Peskine8817f612018-12-18 00:18:46 +01004498 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004499
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004500 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4501 psa_set_key_algorithm( &attributes, alg );
4502 psa_set_key_type( &attributes, our_key_type );
4503 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004504 our_key_data->x, our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004505
Gilles Peskine969c5d62019-01-16 15:53:06 +01004506 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4507 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004508 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004509 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004510 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4511 {
4512 /* The test data is for info="" */
4513 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4514 PSA_KDF_STEP_INFO,
4515 NULL, 0 ) );
4516 }
Gilles Peskine59685592018-09-18 12:11:34 +02004517
Gilles Peskinebf491972018-10-25 22:36:12 +02004518 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004519 PSA_ASSERT( psa_get_generator_capacity(
4520 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004521 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004522
Gilles Peskinebf491972018-10-25 22:36:12 +02004523 /* Test the actual capacity by reading the output. */
4524 while( actual_capacity > sizeof( output ) )
4525 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004526 PSA_ASSERT( psa_generator_read( &generator,
4527 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004528 actual_capacity -= sizeof( output );
4529 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004530 PSA_ASSERT( psa_generator_read( &generator,
4531 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004532 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004533 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004534
Gilles Peskine59685592018-09-18 12:11:34 +02004535exit:
4536 psa_generator_abort( &generator );
4537 psa_destroy_key( our_key );
4538 mbedtls_psa_crypto_free( );
4539}
4540/* END_CASE */
4541
4542/* BEGIN_CASE */
4543void key_agreement_output( int alg_arg,
4544 int our_key_type_arg, data_t *our_key_data,
4545 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004546 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004547{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004548 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004549 psa_algorithm_t alg = alg_arg;
4550 psa_key_type_t our_key_type = our_key_type_arg;
4551 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004552 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004553 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004554
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004555 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4556 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004557
Gilles Peskine8817f612018-12-18 00:18:46 +01004558 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004559
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004560 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4561 psa_set_key_algorithm( &attributes, alg );
4562 psa_set_key_type( &attributes, our_key_type );
4563 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004564 our_key_data->x, our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004565
Gilles Peskine969c5d62019-01-16 15:53:06 +01004566 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4567 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004568 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004569 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004570 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4571 {
4572 /* The test data is for info="" */
4573 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4574 PSA_KDF_STEP_INFO,
4575 NULL, 0 ) );
4576 }
Gilles Peskine59685592018-09-18 12:11:34 +02004577
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004578 PSA_ASSERT( psa_generator_read( &generator,
4579 actual_output,
4580 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004581 ASSERT_COMPARE( actual_output, expected_output1->len,
4582 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004583 if( expected_output2->len != 0 )
4584 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004585 PSA_ASSERT( psa_generator_read( &generator,
4586 actual_output,
4587 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004588 ASSERT_COMPARE( actual_output, expected_output2->len,
4589 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004590 }
Gilles Peskine59685592018-09-18 12:11:34 +02004591
4592exit:
4593 psa_generator_abort( &generator );
4594 psa_destroy_key( our_key );
4595 mbedtls_psa_crypto_free( );
4596 mbedtls_free( actual_output );
4597}
4598/* END_CASE */
4599
4600/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004601void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004602{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004603 size_t bytes = bytes_arg;
4604 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004605 unsigned char *output = NULL;
4606 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004607 size_t i;
4608 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004609
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004610 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4611 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004612 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004613
Gilles Peskine8817f612018-12-18 00:18:46 +01004614 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004615
Gilles Peskinea50d7392018-06-21 10:22:13 +02004616 /* Run several times, to ensure that every output byte will be
4617 * nonzero at least once with overwhelming probability
4618 * (2^(-8*number_of_runs)). */
4619 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004620 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004621 if( bytes != 0 )
4622 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004623 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004624
4625 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004626 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4627 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004628
4629 for( i = 0; i < bytes; i++ )
4630 {
4631 if( output[i] != 0 )
4632 ++changed[i];
4633 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004634 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004635
4636 /* Check that every byte was changed to nonzero at least once. This
4637 * validates that psa_generate_random is overwriting every byte of
4638 * the output buffer. */
4639 for( i = 0; i < bytes; i++ )
4640 {
4641 TEST_ASSERT( changed[i] != 0 );
4642 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004643
4644exit:
4645 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004646 mbedtls_free( output );
4647 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004648}
4649/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004650
4651/* BEGIN_CASE */
4652void generate_key( int type_arg,
4653 int bits_arg,
4654 int usage_arg,
4655 int alg_arg,
4656 int expected_status_arg )
4657{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004658 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004659 psa_key_type_t type = type_arg;
4660 psa_key_usage_t usage = usage_arg;
4661 size_t bits = bits_arg;
4662 psa_algorithm_t alg = alg_arg;
4663 psa_status_t expected_status = expected_status_arg;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004664 psa_status_t expected_info_status =
David Saadab4ecc272019-02-14 13:48:10 +02004665 expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004666 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004667 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004668
Gilles Peskine8817f612018-12-18 00:18:46 +01004669 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004670
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004671 psa_set_key_usage_flags( &attributes, usage );
4672 psa_set_key_algorithm( &attributes, alg );
4673 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004674 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004675
4676 /* Generate a key */
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004677 TEST_EQUAL( psa_generate_key( &attributes, &handle, NULL, 0 ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004678 expected_status );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004679 if( expected_info_status != PSA_SUCCESS )
4680 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004681
4682 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004683 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4684 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4685 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004686
Gilles Peskine818ca122018-06-20 18:16:48 +02004687 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004688 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004689 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004690
4691exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004692 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004693 mbedtls_psa_crypto_free( );
4694}
4695/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004696
Darryl Greend49a4992018-06-18 17:27:26 +01004697/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004698void persistent_key_load_key_from_storage( data_t *data,
4699 int type_arg, int bits_arg,
4700 int usage_flags_arg, int alg_arg,
4701 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004702{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004703 psa_key_id_t key_id = 1;
4704 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004705 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004706 psa_key_handle_t base_key = 0;
4707 psa_key_type_t type = type_arg;
4708 size_t bits = bits_arg;
4709 psa_key_usage_t usage_flags = usage_flags_arg;
4710 psa_algorithm_t alg = alg_arg;
Darryl Green0c6575a2018-11-07 16:05:30 +00004711 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004712 unsigned char *first_export = NULL;
4713 unsigned char *second_export = NULL;
4714 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4715 size_t first_exported_length;
4716 size_t second_exported_length;
4717
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004718 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4719 {
4720 ASSERT_ALLOC( first_export, export_size );
4721 ASSERT_ALLOC( second_export, export_size );
4722 }
Darryl Greend49a4992018-06-18 17:27:26 +01004723
Gilles Peskine8817f612018-12-18 00:18:46 +01004724 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004725
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004726 psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT );
4727 psa_set_key_usage_flags( &attributes, usage_flags );
4728 psa_set_key_algorithm( &attributes, alg );
4729 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004730 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004731
Darryl Green0c6575a2018-11-07 16:05:30 +00004732 switch( generation_method )
4733 {
4734 case IMPORT_KEY:
4735 /* Import the key */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004736 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004737 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004738 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004739
Darryl Green0c6575a2018-11-07 16:05:30 +00004740 case GENERATE_KEY:
4741 /* Generate a key */
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004742 PSA_ASSERT( psa_generate_key( &attributes, &handle, NULL, 0 ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004743 break;
4744
4745 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004746 {
4747 /* Create base key */
4748 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4749 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4750 psa_set_key_usage_flags( &base_attributes,
4751 PSA_KEY_USAGE_DERIVE );
4752 psa_set_key_algorithm( &base_attributes, derive_alg );
4753 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4754 PSA_ASSERT( psa_import_key( &base_attributes, &base_key,
4755 data->x, data->len ) );
4756 /* Derive a key. */
4757 PSA_ASSERT( psa_key_derivation_setup( &generator, derive_alg ) );
4758 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4759 PSA_KDF_STEP_SECRET,
4760 base_key ) );
4761 PSA_ASSERT( psa_key_derivation_input_bytes(
4762 &generator, PSA_KDF_STEP_INFO,
4763 NULL, 0 ) );
4764 PSA_ASSERT( psa_generator_import_key( &attributes, &handle,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004765 &generator ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004766 PSA_ASSERT( psa_generator_abort( &generator ) );
4767 PSA_ASSERT( psa_destroy_key( base_key ) );
4768 base_key = 0;
4769 }
Darryl Green0c6575a2018-11-07 16:05:30 +00004770 break;
4771 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004772 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004773
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004774 /* Export the key if permitted by the key policy. */
4775 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4776 {
4777 PSA_ASSERT( psa_export_key( handle,
4778 first_export, export_size,
4779 &first_exported_length ) );
4780 if( generation_method == IMPORT_KEY )
4781 ASSERT_COMPARE( data->x, data->len,
4782 first_export, first_exported_length );
4783 }
Darryl Greend49a4992018-06-18 17:27:26 +01004784
4785 /* Shutdown and restart */
4786 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004787 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004788
Darryl Greend49a4992018-06-18 17:27:26 +01004789 /* Check key slot still contains key data */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004790 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
Gilles Peskine8817f612018-12-18 00:18:46 +01004791 &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004792 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4793 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4794 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4795 PSA_KEY_LIFETIME_PERSISTENT );
4796 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4797 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4798 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4799 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004800
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004801 /* Export the key again if permitted by the key policy. */
4802 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004803 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004804 PSA_ASSERT( psa_export_key( handle,
4805 second_export, export_size,
4806 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004807 ASSERT_COMPARE( first_export, first_exported_length,
4808 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004809 }
4810
4811 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004812 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004813 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004814
4815exit:
4816 mbedtls_free( first_export );
4817 mbedtls_free( second_export );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004818 psa_generator_abort( &generator );
4819 psa_destroy_key( base_key );
4820 if( handle == 0 )
4821 {
4822 /* In case there was a test failure after creating the persistent key
4823 * but while it was not open, try to re-open the persistent key
4824 * to delete it. */
4825 psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle );
4826 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004827 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004828 mbedtls_psa_crypto_free();
4829}
4830/* END_CASE */