blob: f6447520e1fbc57740a60a9bb9ecfc4cc33a52db [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
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02004#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02005#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02006#include "mbedtls/oid.h"
7
Gilles Peskine1838e822019-06-20 12:40:56 +02008#include "psa_crypto_helpers.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +03009
Gilles Peskinec744d992019-07-30 17:26:54 +020010/* Tests that require more than 128kB of RAM plus change have this symbol
11 * as a dependency. Currently we always define this symbol, so the tests
12 * are always executed. In the future we should make this conditional
13 * so that tests that require a lot of memory are skipped on constrained
14 * platforms. */
15#define HAVE_RAM_AVAILABLE_128k
16
Jaeden Amerof24c7f82018-06-27 17:20:43 +010017/** An invalid export length that will never be set by psa_export_key(). */
18static const size_t INVALID_EXPORT_LENGTH = ~0U;
19
Gilles Peskinef426e0f2019-02-25 17:42:03 +010020/* A hash algorithm that is known to be supported.
21 *
22 * This is used in some smoke tests.
23 */
24#if defined(MBEDTLS_MD2_C)
25#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
26#elif defined(MBEDTLS_MD4_C)
27#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
28#elif defined(MBEDTLS_MD5_C)
29#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
30/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
31 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
32 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
33 * implausible anyway. */
34#elif defined(MBEDTLS_SHA1_C)
35#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
36#elif defined(MBEDTLS_SHA256_C)
37#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
38#elif defined(MBEDTLS_SHA512_C)
39#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
40#elif defined(MBEDTLS_SHA3_C)
41#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
42#else
43#undef KNOWN_SUPPORTED_HASH_ALG
44#endif
45
46/* A block cipher that is known to be supported.
47 *
48 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
49 */
50#if defined(MBEDTLS_AES_C)
51#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
52#elif defined(MBEDTLS_ARIA_C)
53#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
54#elif defined(MBEDTLS_CAMELLIA_C)
55#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
56#undef KNOWN_SUPPORTED_BLOCK_CIPHER
57#endif
58
59/* A MAC mode that is known to be supported.
60 *
61 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
62 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
63 *
64 * This is used in some smoke tests.
65 */
66#if defined(KNOWN_SUPPORTED_HASH_ALG)
67#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
68#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
69#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
70#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
71#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
72#else
73#undef KNOWN_SUPPORTED_MAC_ALG
74#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
75#endif
76
77/* A cipher algorithm and key type that are known to be supported.
78 *
79 * This is used in some smoke tests.
80 */
81#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
82#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
83#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
84#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
85#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
86#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
87#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
88#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
89#else
90#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
91#endif
92#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
93#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
94#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
95#elif defined(MBEDTLS_RC4_C)
96#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
97#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
98#else
99#undef KNOWN_SUPPORTED_CIPHER_ALG
100#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
101#endif
102
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200103/** Test if a buffer contains a constant byte value.
104 *
105 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 *
107 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200108 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200109 * \param size Size of the buffer in bytes.
110 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200111 * \return 1 if the buffer is all-bits-zero.
112 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200113 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200114static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200115{
116 size_t i;
117 for( i = 0; i < size; i++ )
118 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200119 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200120 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200121 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200122 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200123}
Gilles Peskine818ca122018-06-20 18:16:48 +0200124
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200125/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
126static int asn1_write_10x( unsigned char **p,
127 unsigned char *start,
128 size_t bits,
129 unsigned char x )
130{
131 int ret;
132 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200133 if( bits == 0 )
134 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
135 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200136 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300137 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200138 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
139 *p -= len;
140 ( *p )[len-1] = x;
141 if( bits % 8 == 0 )
142 ( *p )[1] |= 1;
143 else
144 ( *p )[0] |= 1 << ( bits % 8 );
145 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
146 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
147 MBEDTLS_ASN1_INTEGER ) );
148 return( len );
149}
150
151static int construct_fake_rsa_key( unsigned char *buffer,
152 size_t buffer_size,
153 unsigned char **p,
154 size_t bits,
155 int keypair )
156{
157 size_t half_bits = ( bits + 1 ) / 2;
158 int ret;
159 int len = 0;
160 /* Construct something that looks like a DER encoding of
161 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
162 * RSAPrivateKey ::= SEQUENCE {
163 * version Version,
164 * modulus INTEGER, -- n
165 * publicExponent INTEGER, -- e
166 * privateExponent INTEGER, -- d
167 * prime1 INTEGER, -- p
168 * prime2 INTEGER, -- q
169 * exponent1 INTEGER, -- d mod (p-1)
170 * exponent2 INTEGER, -- d mod (q-1)
171 * coefficient INTEGER, -- (inverse of q) mod p
172 * otherPrimeInfos OtherPrimeInfos OPTIONAL
173 * }
174 * Or, for a public key, the same structure with only
175 * version, modulus and publicExponent.
176 */
177 *p = buffer + buffer_size;
178 if( keypair )
179 {
180 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
181 asn1_write_10x( p, buffer, half_bits, 1 ) );
182 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
183 asn1_write_10x( p, buffer, half_bits, 1 ) );
184 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
185 asn1_write_10x( p, buffer, half_bits, 1 ) );
186 MBEDTLS_ASN1_CHK_ADD( len, /* q */
187 asn1_write_10x( p, buffer, half_bits, 1 ) );
188 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
189 asn1_write_10x( p, buffer, half_bits, 3 ) );
190 MBEDTLS_ASN1_CHK_ADD( len, /* d */
191 asn1_write_10x( p, buffer, bits, 1 ) );
192 }
193 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
194 asn1_write_10x( p, buffer, 17, 1 ) );
195 MBEDTLS_ASN1_CHK_ADD( len, /* n */
196 asn1_write_10x( p, buffer, bits, 1 ) );
197 if( keypair )
198 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
199 mbedtls_asn1_write_int( p, buffer, 0 ) );
200 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
201 {
202 const unsigned char tag =
203 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
204 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
205 }
206 return( len );
207}
208
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100209int exercise_mac_setup( psa_key_type_t key_type,
210 const unsigned char *key_bytes,
211 size_t key_length,
212 psa_algorithm_t alg,
213 psa_mac_operation_t *operation,
214 psa_status_t *status )
215{
216 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200217 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100218
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200219 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
220 psa_set_key_algorithm( &attributes, alg );
221 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200222 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
223 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100224
225 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100226 /* Whether setup succeeded or failed, abort must succeed. */
227 PSA_ASSERT( psa_mac_abort( operation ) );
228 /* If setup failed, reproduce the failure, so that the caller can
229 * test the resulting state of the operation object. */
230 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100231 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100232 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
233 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100234 }
235
236 psa_destroy_key( handle );
237 return( 1 );
238
239exit:
240 psa_destroy_key( handle );
241 return( 0 );
242}
243
244int exercise_cipher_setup( psa_key_type_t key_type,
245 const unsigned char *key_bytes,
246 size_t key_length,
247 psa_algorithm_t alg,
248 psa_cipher_operation_t *operation,
249 psa_status_t *status )
250{
251 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200252 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100253
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200254 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
255 psa_set_key_algorithm( &attributes, alg );
256 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200257 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
258 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100259
260 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100261 /* Whether setup succeeded or failed, abort must succeed. */
262 PSA_ASSERT( psa_cipher_abort( operation ) );
263 /* If setup failed, reproduce the failure, so that the caller can
264 * test the resulting state of the operation object. */
265 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100266 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100267 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
268 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100269 }
270
271 psa_destroy_key( handle );
272 return( 1 );
273
274exit:
275 psa_destroy_key( handle );
276 return( 0 );
277}
278
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100279static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200280 psa_key_usage_t usage,
281 psa_algorithm_t alg )
282{
Jaeden Amero769ce272019-01-04 11:48:03 +0000283 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200284 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200285 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200286 size_t mac_length = sizeof( mac );
287
288 if( usage & PSA_KEY_USAGE_SIGN )
289 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100290 PSA_ASSERT( psa_mac_sign_setup( &operation,
291 handle, alg ) );
292 PSA_ASSERT( psa_mac_update( &operation,
293 input, sizeof( input ) ) );
294 PSA_ASSERT( psa_mac_sign_finish( &operation,
295 mac, sizeof( mac ),
296 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200297 }
298
299 if( usage & PSA_KEY_USAGE_VERIFY )
300 {
301 psa_status_t verify_status =
302 ( usage & PSA_KEY_USAGE_SIGN ?
303 PSA_SUCCESS :
304 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100305 PSA_ASSERT( psa_mac_verify_setup( &operation,
306 handle, alg ) );
307 PSA_ASSERT( psa_mac_update( &operation,
308 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100309 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
310 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200311 }
312
313 return( 1 );
314
315exit:
316 psa_mac_abort( &operation );
317 return( 0 );
318}
319
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100320static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200321 psa_key_usage_t usage,
322 psa_algorithm_t alg )
323{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000324 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200325 unsigned char iv[16] = {0};
326 size_t iv_length = sizeof( iv );
327 const unsigned char plaintext[16] = "Hello, world...";
328 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
329 size_t ciphertext_length = sizeof( ciphertext );
330 unsigned char decrypted[sizeof( ciphertext )];
331 size_t part_length;
332
333 if( usage & PSA_KEY_USAGE_ENCRYPT )
334 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100335 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
336 handle, alg ) );
337 PSA_ASSERT( psa_cipher_generate_iv( &operation,
338 iv, sizeof( iv ),
339 &iv_length ) );
340 PSA_ASSERT( psa_cipher_update( &operation,
341 plaintext, sizeof( plaintext ),
342 ciphertext, sizeof( ciphertext ),
343 &ciphertext_length ) );
344 PSA_ASSERT( psa_cipher_finish( &operation,
345 ciphertext + ciphertext_length,
346 sizeof( ciphertext ) - ciphertext_length,
347 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200348 ciphertext_length += part_length;
349 }
350
351 if( usage & PSA_KEY_USAGE_DECRYPT )
352 {
353 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200354 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200355 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
356 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200357 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
358 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
359 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
360 * have this macro yet. */
361 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
362 psa_get_key_type( &attributes ) );
363 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200364 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100365 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
366 handle, alg ) );
367 PSA_ASSERT( psa_cipher_set_iv( &operation,
368 iv, iv_length ) );
369 PSA_ASSERT( psa_cipher_update( &operation,
370 ciphertext, ciphertext_length,
371 decrypted, sizeof( decrypted ),
372 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200373 status = psa_cipher_finish( &operation,
374 decrypted + part_length,
375 sizeof( decrypted ) - part_length,
376 &part_length );
377 /* For a stream cipher, all inputs are valid. For a block cipher,
378 * if the input is some aribtrary data rather than an actual
379 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200380 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200381 TEST_ASSERT( status == PSA_SUCCESS ||
382 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200383 else
384 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200385 }
386
387 return( 1 );
388
389exit:
390 psa_cipher_abort( &operation );
391 return( 0 );
392}
393
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100394static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200395 psa_key_usage_t usage,
396 psa_algorithm_t alg )
397{
398 unsigned char nonce[16] = {0};
399 size_t nonce_length = sizeof( nonce );
400 unsigned char plaintext[16] = "Hello, world...";
401 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
402 size_t ciphertext_length = sizeof( ciphertext );
403 size_t plaintext_length = sizeof( ciphertext );
404
405 if( usage & PSA_KEY_USAGE_ENCRYPT )
406 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100407 PSA_ASSERT( psa_aead_encrypt( handle, alg,
408 nonce, nonce_length,
409 NULL, 0,
410 plaintext, sizeof( plaintext ),
411 ciphertext, sizeof( ciphertext ),
412 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200413 }
414
415 if( usage & PSA_KEY_USAGE_DECRYPT )
416 {
417 psa_status_t verify_status =
418 ( usage & PSA_KEY_USAGE_ENCRYPT ?
419 PSA_SUCCESS :
420 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100421 TEST_EQUAL( psa_aead_decrypt( handle, alg,
422 nonce, nonce_length,
423 NULL, 0,
424 ciphertext, ciphertext_length,
425 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100426 &plaintext_length ),
427 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200428 }
429
430 return( 1 );
431
432exit:
433 return( 0 );
434}
435
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100436static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200437 psa_key_usage_t usage,
438 psa_algorithm_t alg )
439{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200440 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
441 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200442 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200443 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100444 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
445
446 /* If the policy allows signing with any hash, just pick one. */
447 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
448 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100449#if defined(KNOWN_SUPPORTED_HASH_ALG)
450 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
451 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100452#else
453 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100454 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100455#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100456 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200457
458 if( usage & PSA_KEY_USAGE_SIGN )
459 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200460 /* Some algorithms require the payload to have the size of
461 * the hash encoded in the algorithm. Use this input size
462 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200463 if( hash_alg != 0 )
464 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100465 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
466 payload, payload_length,
467 signature, sizeof( signature ),
468 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200469 }
470
471 if( usage & PSA_KEY_USAGE_VERIFY )
472 {
473 psa_status_t verify_status =
474 ( usage & PSA_KEY_USAGE_SIGN ?
475 PSA_SUCCESS :
476 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100477 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
478 payload, payload_length,
479 signature, signature_length ),
480 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200481 }
482
483 return( 1 );
484
485exit:
486 return( 0 );
487}
488
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100489static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200490 psa_key_usage_t usage,
491 psa_algorithm_t alg )
492{
493 unsigned char plaintext[256] = "Hello, world...";
494 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
495 size_t ciphertext_length = sizeof( ciphertext );
496 size_t plaintext_length = 16;
497
498 if( usage & PSA_KEY_USAGE_ENCRYPT )
499 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100500 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
501 plaintext, plaintext_length,
502 NULL, 0,
503 ciphertext, sizeof( ciphertext ),
504 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200505 }
506
507 if( usage & PSA_KEY_USAGE_DECRYPT )
508 {
509 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100510 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200511 ciphertext, ciphertext_length,
512 NULL, 0,
513 plaintext, sizeof( plaintext ),
514 &plaintext_length );
515 TEST_ASSERT( status == PSA_SUCCESS ||
516 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
517 ( status == PSA_ERROR_INVALID_ARGUMENT ||
518 status == PSA_ERROR_INVALID_PADDING ) ) );
519 }
520
521 return( 1 );
522
523exit:
524 return( 0 );
525}
Gilles Peskine02b75072018-07-01 22:31:34 +0200526
Janos Follathf2815ea2019-07-03 12:41:36 +0100527static int setup_key_derivation_wrap( psa_key_derivation_operation_t* operation,
528 psa_key_handle_t handle,
529 psa_algorithm_t alg,
530 unsigned char* input1, size_t input1_length,
531 unsigned char* input2, size_t input2_length,
532 size_t capacity )
533{
534 PSA_ASSERT( psa_key_derivation_setup( operation, alg ) );
535 if( PSA_ALG_IS_HKDF( alg ) )
536 {
537 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
538 PSA_KEY_DERIVATION_INPUT_SALT,
539 input1, input1_length ) );
540 PSA_ASSERT( psa_key_derivation_input_key( operation,
541 PSA_KEY_DERIVATION_INPUT_SECRET,
542 handle ) );
543 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
544 PSA_KEY_DERIVATION_INPUT_INFO,
545 input2,
546 input2_length ) );
547 }
548 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
549 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
550 {
551 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
552 PSA_KEY_DERIVATION_INPUT_SEED,
553 input1, input1_length ) );
554 PSA_ASSERT( psa_key_derivation_input_key( operation,
555 PSA_KEY_DERIVATION_INPUT_SECRET,
556 handle ) );
557 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
558 PSA_KEY_DERIVATION_INPUT_LABEL,
559 input2, input2_length ) );
560 }
561 else
562 {
563 TEST_ASSERT( ! "Key derivation algorithm not supported" );
564 }
565
Gilles Peskinec744d992019-07-30 17:26:54 +0200566 if( capacity != SIZE_MAX )
567 PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
Janos Follathf2815ea2019-07-03 12:41:36 +0100568
569 return( 1 );
570
571exit:
572 return( 0 );
573}
574
575
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100576static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200577 psa_key_usage_t usage,
578 psa_algorithm_t alg )
579{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200580 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathf2815ea2019-07-03 12:41:36 +0100581 unsigned char input1[] = "Input 1";
582 size_t input1_length = sizeof( input1 );
583 unsigned char input2[] = "Input 2";
584 size_t input2_length = sizeof( input2 );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200585 unsigned char output[1];
Janos Follathf2815ea2019-07-03 12:41:36 +0100586 size_t capacity = sizeof( output );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200587
588 if( usage & PSA_KEY_USAGE_DERIVE )
589 {
Janos Follathf2815ea2019-07-03 12:41:36 +0100590 if( !setup_key_derivation_wrap( &operation, handle, alg,
591 input1, input1_length,
592 input2, input2_length, capacity ) )
593 goto exit;
Gilles Peskine7607cd62019-05-29 17:35:00 +0200594
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200595 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200596 output,
Janos Follathf2815ea2019-07-03 12:41:36 +0100597 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200598 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200599 }
600
601 return( 1 );
602
603exit:
604 return( 0 );
605}
606
Gilles Peskinec7998b72018-11-07 18:45:02 +0100607/* We need two keys to exercise key agreement. Exercise the
608 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200609static psa_status_t key_agreement_with_self(
610 psa_key_derivation_operation_t *operation,
611 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100612{
613 psa_key_type_t private_key_type;
614 psa_key_type_t public_key_type;
615 size_t key_bits;
616 uint8_t *public_key = NULL;
617 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200618 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200619 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
620 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200621 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200622 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100623
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200624 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
625 private_key_type = psa_get_key_type( &attributes );
626 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200627 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100628 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
629 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100630 PSA_ASSERT( psa_export_public_key( handle,
631 public_key, public_key_length,
632 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100633
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200634 status = psa_key_derivation_key_agreement(
635 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
636 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100637exit:
638 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200639 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100640 return( status );
641}
642
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200643/* We need two keys to exercise key agreement. Exercise the
644 * private key against its own public key. */
645static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
646 psa_key_handle_t handle )
647{
648 psa_key_type_t private_key_type;
649 psa_key_type_t public_key_type;
650 size_t key_bits;
651 uint8_t *public_key = NULL;
652 size_t public_key_length;
653 uint8_t output[1024];
654 size_t output_length;
655 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200656 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
657 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200658 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200659 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200660
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200661 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
662 private_key_type = psa_get_key_type( &attributes );
663 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200664 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200665 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
666 ASSERT_ALLOC( public_key, public_key_length );
667 PSA_ASSERT( psa_export_public_key( handle,
668 public_key, public_key_length,
669 &public_key_length ) );
670
Gilles Peskinebe697d82019-05-16 18:00:41 +0200671 status = psa_raw_key_agreement( alg, handle,
672 public_key, public_key_length,
673 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200674exit:
675 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200676 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200677 return( status );
678}
679
680static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
681 psa_key_usage_t usage,
682 psa_algorithm_t alg )
683{
684 int ok = 0;
685
686 if( usage & PSA_KEY_USAGE_DERIVE )
687 {
688 /* We need two keys to exercise key agreement. Exercise the
689 * private key against its own public key. */
690 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
691 }
692 ok = 1;
693
694exit:
695 return( ok );
696}
697
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100698static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200699 psa_key_usage_t usage,
700 psa_algorithm_t alg )
701{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200702 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200703 unsigned char output[1];
704 int ok = 0;
705
706 if( usage & PSA_KEY_USAGE_DERIVE )
707 {
708 /* We need two keys to exercise key agreement. Exercise the
709 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200710 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
711 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
712 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200713 output,
714 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200715 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200716 }
717 ok = 1;
718
719exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200720 return( ok );
721}
722
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200723static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
724 size_t min_bits, size_t max_bits,
725 int must_be_odd )
726{
727 size_t len;
728 size_t actual_bits;
729 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100730 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100731 MBEDTLS_ASN1_INTEGER ),
732 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200733 /* Tolerate a slight departure from DER encoding:
734 * - 0 may be represented by an empty string or a 1-byte string.
735 * - The sign bit may be used as a value bit. */
736 if( ( len == 1 && ( *p )[0] == 0 ) ||
737 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
738 {
739 ++( *p );
740 --len;
741 }
742 if( min_bits == 0 && len == 0 )
743 return( 1 );
744 msb = ( *p )[0];
745 TEST_ASSERT( msb != 0 );
746 actual_bits = 8 * ( len - 1 );
747 while( msb != 0 )
748 {
749 msb >>= 1;
750 ++actual_bits;
751 }
752 TEST_ASSERT( actual_bits >= min_bits );
753 TEST_ASSERT( actual_bits <= max_bits );
754 if( must_be_odd )
755 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
756 *p += len;
757 return( 1 );
758exit:
759 return( 0 );
760}
761
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200762static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
763 uint8_t *exported, size_t exported_length )
764{
765 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100766 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200767 else
768 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200769
770#if defined(MBEDTLS_DES_C)
771 if( type == PSA_KEY_TYPE_DES )
772 {
773 /* Check the parity bits. */
774 unsigned i;
775 for( i = 0; i < bits / 8; i++ )
776 {
777 unsigned bit_count = 0;
778 unsigned m;
779 for( m = 1; m <= 0x100; m <<= 1 )
780 {
781 if( exported[i] & m )
782 ++bit_count;
783 }
784 TEST_ASSERT( bit_count % 2 != 0 );
785 }
786 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200787 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200788#endif
789
790#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200791 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200792 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200793 uint8_t *p = exported;
794 uint8_t *end = exported + exported_length;
795 size_t len;
796 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200797 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200798 * modulus INTEGER, -- n
799 * publicExponent INTEGER, -- e
800 * privateExponent INTEGER, -- d
801 * prime1 INTEGER, -- p
802 * prime2 INTEGER, -- q
803 * exponent1 INTEGER, -- d mod (p-1)
804 * exponent2 INTEGER, -- d mod (q-1)
805 * coefficient INTEGER, -- (inverse of q) mod p
806 * }
807 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100808 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
809 MBEDTLS_ASN1_SEQUENCE |
810 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
811 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200812 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
813 goto exit;
814 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
815 goto exit;
816 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
817 goto exit;
818 /* Require d to be at least half the size of n. */
819 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
820 goto exit;
821 /* Require p and q to be at most half the size of n, rounded up. */
822 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
823 goto exit;
824 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
825 goto exit;
826 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
827 goto exit;
828 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
829 goto exit;
830 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
831 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100832 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100833 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200834 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200835#endif /* MBEDTLS_RSA_C */
836
837#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200838 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200839 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100840 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100841 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100842 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200843 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200844#endif /* MBEDTLS_ECP_C */
845
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200846 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
847 {
848 uint8_t *p = exported;
849 uint8_t *end = exported + exported_length;
850 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200851#if defined(MBEDTLS_RSA_C)
852 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
853 {
854 /* RSAPublicKey ::= SEQUENCE {
855 * modulus INTEGER, -- n
856 * publicExponent INTEGER } -- e
857 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100858 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
859 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100860 MBEDTLS_ASN1_CONSTRUCTED ),
861 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100862 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200863 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
864 goto exit;
865 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
866 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100867 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200868 }
869 else
870#endif /* MBEDTLS_RSA_C */
871#if defined(MBEDTLS_ECP_C)
872 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
873 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000874 /* The representation of an ECC public key is:
875 * - The byte 0x04;
876 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
877 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
878 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000879 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100880 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
881 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200882 }
883 else
884#endif /* MBEDTLS_ECP_C */
885 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100886 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200887 mbedtls_snprintf( message, sizeof( message ),
888 "No sanity check for public key type=0x%08lx",
889 (unsigned long) type );
890 test_fail( message, __LINE__, __FILE__ );
891 return( 0 );
892 }
893 }
894 else
895
896 {
897 /* No sanity checks for other types */
898 }
899
900 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200901
902exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200903 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200904}
905
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100906static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200907 psa_key_usage_t usage )
908{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200909 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200910 uint8_t *exported = NULL;
911 size_t exported_size = 0;
912 size_t exported_length = 0;
913 int ok = 0;
914
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200915 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200916
917 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200918 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200919 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100920 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
921 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200922 ok = 1;
923 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200924 }
925
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200926 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
927 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200928 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200929
Gilles Peskine8817f612018-12-18 00:18:46 +0100930 PSA_ASSERT( psa_export_key( handle,
931 exported, exported_size,
932 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200933 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
934 psa_get_key_bits( &attributes ),
935 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200936
937exit:
938 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200939 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200940 return( ok );
941}
942
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100943static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200944{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200945 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200946 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200947 uint8_t *exported = NULL;
948 size_t exported_size = 0;
949 size_t exported_length = 0;
950 int ok = 0;
951
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200952 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
953 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200954 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100955 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100956 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200957 return( 1 );
958 }
959
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200960 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200961 psa_get_key_type( &attributes ) );
962 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
963 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200964 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200965
Gilles Peskine8817f612018-12-18 00:18:46 +0100966 PSA_ASSERT( psa_export_public_key( handle,
967 exported, exported_size,
968 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200969 ok = exported_key_sanity_check( public_type,
970 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200971 exported, exported_length );
972
973exit:
974 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200975 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200976 return( ok );
977}
978
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100979/** Do smoke tests on a key.
980 *
981 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
982 * sign/verify, or derivation) that is permitted according to \p usage.
983 * \p usage and \p alg should correspond to the expected policy on the
984 * key.
985 *
986 * Export the key if permitted by \p usage, and check that the output
987 * looks sensible. If \p usage forbids export, check that
988 * \p psa_export_key correctly rejects the attempt. If the key is
989 * asymmetric, also check \p psa_export_public_key.
990 *
991 * If the key fails the tests, this function calls the test framework's
992 * `test_fail` function and returns false. Otherwise this function returns
993 * true. Therefore it should be used as follows:
994 * ```
995 * if( ! exercise_key( ... ) ) goto exit;
996 * ```
997 *
998 * \param handle The key to exercise. It should be capable of performing
999 * \p alg.
1000 * \param usage The usage flags to assume.
1001 * \param alg The algorithm to exercise.
1002 *
1003 * \retval 0 The key failed the smoke tests.
1004 * \retval 1 The key passed the smoke tests.
1005 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001006static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001007 psa_key_usage_t usage,
1008 psa_algorithm_t alg )
1009{
1010 int ok;
1011 if( alg == 0 )
1012 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1013 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001014 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001015 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001016 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001017 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001018 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001019 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001020 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001021 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001022 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001023 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001024 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001025 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1026 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001027 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001029 else
1030 {
1031 char message[40];
1032 mbedtls_snprintf( message, sizeof( message ),
1033 "No code to exercise alg=0x%08lx",
1034 (unsigned long) alg );
1035 test_fail( message, __LINE__, __FILE__ );
1036 ok = 0;
1037 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001038
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001039 ok = ok && exercise_export_key( handle, usage );
1040 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001041
Gilles Peskine02b75072018-07-01 22:31:34 +02001042 return( ok );
1043}
1044
Gilles Peskine10df3412018-10-25 22:35:43 +02001045static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1046 psa_algorithm_t alg )
1047{
1048 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1049 {
1050 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1051 PSA_KEY_USAGE_VERIFY :
1052 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1053 }
1054 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1055 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1056 {
1057 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1058 PSA_KEY_USAGE_ENCRYPT :
1059 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1060 }
1061 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1062 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1063 {
1064 return( PSA_KEY_USAGE_DERIVE );
1065 }
1066 else
1067 {
1068 return( 0 );
1069 }
1070
1071}
Darryl Green0c6575a2018-11-07 16:05:30 +00001072
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001073static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1074{
1075 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1076 uint8_t buffer[1];
1077 size_t length;
1078 int ok = 0;
1079
Gilles Peskinec87af662019-05-15 16:12:22 +02001080 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001081 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1082 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1083 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1084 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1085 PSA_ERROR_INVALID_HANDLE );
1086 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001087 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001088 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1089 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1090 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1091 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1092
1093 TEST_EQUAL( psa_export_key( handle,
1094 buffer, sizeof( buffer ), &length ),
1095 PSA_ERROR_INVALID_HANDLE );
1096 TEST_EQUAL( psa_export_public_key( handle,
1097 buffer, sizeof( buffer ), &length ),
1098 PSA_ERROR_INVALID_HANDLE );
1099
1100 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1101 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1102
1103 ok = 1;
1104
1105exit:
1106 psa_reset_key_attributes( &attributes );
1107 return( ok );
1108}
1109
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001110/* An overapproximation of the amount of storage needed for a key of the
1111 * given type and with the given content. The API doesn't make it easy
1112 * to find a good value for the size. The current implementation doesn't
1113 * care about the value anyway. */
1114#define KEY_BITS_FROM_DATA( type, data ) \
1115 ( data )->len
1116
Darryl Green0c6575a2018-11-07 16:05:30 +00001117typedef enum {
1118 IMPORT_KEY = 0,
1119 GENERATE_KEY = 1,
1120 DERIVE_KEY = 2
1121} generate_method;
1122
Gilles Peskinee59236f2018-01-27 23:32:46 +01001123/* END_HEADER */
1124
1125/* BEGIN_DEPENDENCIES
1126 * depends_on:MBEDTLS_PSA_CRYPTO_C
1127 * END_DEPENDENCIES
1128 */
1129
1130/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001131void static_checks( )
1132{
1133 size_t max_truncated_mac_size =
1134 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1135
1136 /* Check that the length for a truncated MAC always fits in the algorithm
1137 * encoding. The shifted mask is the maximum truncated value. The
1138 * untruncated algorithm may be one byte larger. */
1139 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1140}
1141/* END_CASE */
1142
1143/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001144void attributes_set_get( int id_arg, int lifetime_arg,
1145 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001146 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001147{
Gilles Peskine4747d192019-04-17 15:05:45 +02001148 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001149 psa_key_id_t id = id_arg;
1150 psa_key_lifetime_t lifetime = lifetime_arg;
1151 psa_key_usage_t usage_flags = usage_flags_arg;
1152 psa_algorithm_t alg = alg_arg;
1153 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001154 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001155
1156 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1157 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1158 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1159 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1160 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001161 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001162
Gilles Peskinec87af662019-05-15 16:12:22 +02001163 psa_set_key_id( &attributes, id );
1164 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001165 psa_set_key_usage_flags( &attributes, usage_flags );
1166 psa_set_key_algorithm( &attributes, alg );
1167 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001168 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001169
1170 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1171 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1172 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1173 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1174 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001175 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001176
1177 psa_reset_key_attributes( &attributes );
1178
1179 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1182 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1183 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001184 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001185}
1186/* END_CASE */
1187
1188/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001189void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1190 int expected_id_arg, int expected_lifetime_arg )
1191{
1192 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1193 psa_key_id_t id1 = id1_arg;
1194 psa_key_lifetime_t lifetime = lifetime_arg;
1195 psa_key_id_t id2 = id2_arg;
1196 psa_key_id_t expected_id = expected_id_arg;
1197 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1198
1199 if( id1_arg != -1 )
1200 psa_set_key_id( &attributes, id1 );
1201 if( lifetime_arg != -1 )
1202 psa_set_key_lifetime( &attributes, lifetime );
1203 if( id2_arg != -1 )
1204 psa_set_key_id( &attributes, id2 );
1205
1206 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1207 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1208}
1209/* END_CASE */
1210
1211/* BEGIN_CASE */
Gilles Peskine6edfa292019-07-31 15:53:45 +02001212void import_with_policy( int type_arg,
1213 int usage_arg, int alg_arg,
1214 int expected_status_arg )
1215{
1216 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1217 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1218 psa_key_handle_t handle = 0;
1219 psa_key_type_t type = type_arg;
1220 psa_key_usage_t usage = usage_arg;
1221 psa_algorithm_t alg = alg_arg;
1222 psa_status_t expected_status = expected_status_arg;
1223 const uint8_t key_material[16] = {0};
1224 psa_status_t status;
1225
1226 PSA_ASSERT( psa_crypto_init( ) );
1227
1228 psa_set_key_type( &attributes, type );
1229 psa_set_key_usage_flags( &attributes, usage );
1230 psa_set_key_algorithm( &attributes, alg );
1231
1232 status = psa_import_key( &attributes,
1233 key_material, sizeof( key_material ),
1234 &handle );
1235 TEST_EQUAL( status, expected_status );
1236 if( status != PSA_SUCCESS )
1237 goto exit;
1238
1239 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1240 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1241 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1242 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1243
1244 PSA_ASSERT( psa_destroy_key( handle ) );
1245 test_operations_on_invalid_handle( handle );
1246
1247exit:
1248 psa_destroy_key( handle );
1249 psa_reset_key_attributes( &got_attributes );
1250 PSA_DONE( );
1251}
1252/* END_CASE */
1253
1254/* BEGIN_CASE */
1255void import_with_data( data_t *data, int type_arg,
1256 int attr_bits_arg,
1257 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001258{
1259 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1260 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001261 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001262 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001263 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001264 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001265 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001266
Gilles Peskine8817f612018-12-18 00:18:46 +01001267 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001268
Gilles Peskine4747d192019-04-17 15:05:45 +02001269 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001270 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001271
Gilles Peskine73676cb2019-05-15 20:15:10 +02001272 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001273 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001274 if( status != PSA_SUCCESS )
1275 goto exit;
1276
1277 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1278 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001279 if( attr_bits != 0 )
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001280 TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001281
1282 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001283 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001284
1285exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001286 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001287 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001288 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001289}
1290/* END_CASE */
1291
1292/* BEGIN_CASE */
Gilles Peskinec744d992019-07-30 17:26:54 +02001293void import_large_key( int type_arg, int byte_size_arg,
1294 int expected_status_arg )
1295{
1296 psa_key_type_t type = type_arg;
1297 size_t byte_size = byte_size_arg;
1298 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1299 psa_status_t expected_status = expected_status_arg;
1300 psa_key_handle_t handle = 0;
1301 psa_status_t status;
1302 uint8_t *buffer = NULL;
1303 size_t buffer_size = byte_size + 1;
1304 size_t n;
1305
1306 /* It would be better to skip the test than fail it if the allocation
1307 * fails, but the test framework doesn't support this yet. */
1308 ASSERT_ALLOC( buffer, buffer_size );
1309 memset( buffer, 'K', byte_size );
1310
1311 PSA_ASSERT( psa_crypto_init( ) );
1312
1313 /* Try importing the key */
1314 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1315 psa_set_key_type( &attributes, type );
1316 status = psa_import_key( &attributes, buffer, byte_size, &handle );
1317 TEST_EQUAL( status, expected_status );
1318
1319 if( status == PSA_SUCCESS )
1320 {
1321 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1322 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1323 TEST_EQUAL( psa_get_key_bits( &attributes ),
1324 PSA_BYTES_TO_BITS( byte_size ) );
1325 memset( buffer, 0, byte_size + 1 );
1326 PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) );
1327 for( n = 0; n < byte_size; n++ )
1328 TEST_EQUAL( buffer[n], 'K' );
1329 for( n = byte_size; n < buffer_size; n++ )
1330 TEST_EQUAL( buffer[n], 0 );
1331 }
1332
1333exit:
1334 psa_destroy_key( handle );
1335 PSA_DONE( );
1336 mbedtls_free( buffer );
1337}
1338/* END_CASE */
1339
1340/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001341void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1342{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001343 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001344 size_t bits = bits_arg;
1345 psa_status_t expected_status = expected_status_arg;
1346 psa_status_t status;
1347 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001348 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001349 size_t buffer_size = /* Slight overapproximations */
1350 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001351 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001352 unsigned char *p;
1353 int ret;
1354 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001355 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001356
Gilles Peskine8817f612018-12-18 00:18:46 +01001357 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001358 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001359
1360 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1361 bits, keypair ) ) >= 0 );
1362 length = ret;
1363
1364 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001365 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001366 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001367 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001368
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001369 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001370 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001371
1372exit:
1373 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001374 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001375}
1376/* END_CASE */
1377
1378/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001379void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001380 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001381 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001382 int expected_bits,
1383 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001384 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001385 int canonical_input )
1386{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001387 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001388 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001389 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001390 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001391 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001392 unsigned char *exported = NULL;
1393 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001394 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001395 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001396 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001397 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001398 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001399
Moran Pekercb088e72018-07-17 17:36:59 +03001400 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001401 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001402 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001403 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001404 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001405
Gilles Peskine4747d192019-04-17 15:05:45 +02001406 psa_set_key_usage_flags( &attributes, usage_arg );
1407 psa_set_key_algorithm( &attributes, alg );
1408 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001409
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001410 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001411 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001412
1413 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001414 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1415 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1416 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001417
1418 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001419 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001420 exported, export_size,
1421 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001422 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001423
1424 /* The exported length must be set by psa_export_key() to a value between 0
1425 * and export_size. On errors, the exported length must be 0. */
1426 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1427 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1428 TEST_ASSERT( exported_length <= export_size );
1429
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001430 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001431 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001432 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001433 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001434 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001435 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001436 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001437
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001438 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001439 goto exit;
1440
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001441 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001442 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001443 else
1444 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001445 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001446 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1447 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001448 PSA_ASSERT( psa_export_key( handle2,
1449 reexported,
1450 export_size,
1451 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001452 ASSERT_COMPARE( exported, exported_length,
1453 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001454 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001455 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001456 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001457
1458destroy:
1459 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001460 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001461 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001462
1463exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001464 mbedtls_free( exported );
1465 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001466 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001467 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001468}
1469/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001470
Moran Pekerf709f4a2018-06-06 17:26:04 +03001471/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001472void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001473{
Gilles Peskine8817f612018-12-18 00:18:46 +01001474 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001475 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001476
1477exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001478 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001479}
1480/* END_CASE */
1481
1482/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001483void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001484 int type_arg,
1485 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001486 int export_size_delta,
1487 int expected_export_status_arg,
1488 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001489{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001490 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001491 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001492 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001493 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001494 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001495 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001496 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001497 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001498 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001499
Gilles Peskine8817f612018-12-18 00:18:46 +01001500 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001501
Gilles Peskine4747d192019-04-17 15:05:45 +02001502 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1503 psa_set_key_algorithm( &attributes, alg );
1504 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001505
1506 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001507 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001508
Gilles Peskine49c25912018-10-29 15:15:31 +01001509 /* Export the public key */
1510 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001511 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001512 exported, export_size,
1513 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001514 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001515 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001516 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001517 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001518 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001519 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1520 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001521 TEST_ASSERT( expected_public_key->len <=
1522 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001523 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1524 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001525 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001526
1527exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001528 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001529 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001530 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001531 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001532}
1533/* END_CASE */
1534
Gilles Peskine20035e32018-02-03 22:44:14 +01001535/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001536void import_and_exercise_key( data_t *data,
1537 int type_arg,
1538 int bits_arg,
1539 int alg_arg )
1540{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001541 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001542 psa_key_type_t type = type_arg;
1543 size_t bits = bits_arg;
1544 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001545 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001546 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001547 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001548
Gilles Peskine8817f612018-12-18 00:18:46 +01001549 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001550
Gilles Peskine4747d192019-04-17 15:05:45 +02001551 psa_set_key_usage_flags( &attributes, usage );
1552 psa_set_key_algorithm( &attributes, alg );
1553 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001554
1555 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001556 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001557
1558 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001559 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1560 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1561 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001562
1563 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001564 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001565 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001566
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001567 PSA_ASSERT( psa_destroy_key( handle ) );
1568 test_operations_on_invalid_handle( handle );
1569
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001570exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001571 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001572 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001573 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001574}
1575/* END_CASE */
1576
1577/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001578void key_policy( int usage_arg, int alg_arg )
1579{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001580 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001581 psa_algorithm_t alg = alg_arg;
1582 psa_key_usage_t usage = usage_arg;
1583 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1584 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001585 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001586
1587 memset( key, 0x2a, sizeof( key ) );
1588
Gilles Peskine8817f612018-12-18 00:18:46 +01001589 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001590
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001591 psa_set_key_usage_flags( &attributes, usage );
1592 psa_set_key_algorithm( &attributes, alg );
1593 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001594
Gilles Peskine73676cb2019-05-15 20:15:10 +02001595 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001596
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001597 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1598 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1599 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1600 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001601
1602exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001603 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001604 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001605 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001606}
1607/* END_CASE */
1608
1609/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001610void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001611{
1612 /* Test each valid way of initializing the object, except for `= {0}`, as
1613 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1614 * though it's OK by the C standard. We could test for this, but we'd need
1615 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001616 psa_key_attributes_t func = psa_key_attributes_init( );
1617 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1618 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001619
1620 memset( &zero, 0, sizeof( zero ) );
1621
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001622 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1623 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1624 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001625
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001626 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1627 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1628 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1629
1630 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1631 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1632 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1633
1634 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1635 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1636 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1637
1638 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1639 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1640 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001641}
1642/* END_CASE */
1643
1644/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001645void mac_key_policy( int policy_usage,
1646 int policy_alg,
1647 int key_type,
1648 data_t *key_data,
1649 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001650{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001651 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001652 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001653 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654 psa_status_t status;
1655 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001656
Gilles Peskine8817f612018-12-18 00:18:46 +01001657 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001658
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001659 psa_set_key_usage_flags( &attributes, policy_usage );
1660 psa_set_key_algorithm( &attributes, policy_alg );
1661 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001662
Gilles Peskine049c7532019-05-15 20:22:09 +02001663 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1664 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001665
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001666 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001667 if( policy_alg == exercise_alg &&
1668 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001669 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001670 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001671 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001672 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001673
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001674 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001675 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001676 if( policy_alg == exercise_alg &&
1677 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001678 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001679 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001680 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001681
1682exit:
1683 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001684 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001685 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001686}
1687/* END_CASE */
1688
1689/* BEGIN_CASE */
1690void cipher_key_policy( int policy_usage,
1691 int policy_alg,
1692 int key_type,
1693 data_t *key_data,
1694 int exercise_alg )
1695{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001696 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001697 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001698 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001699 psa_status_t status;
1700
Gilles Peskine8817f612018-12-18 00:18:46 +01001701 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001702
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001703 psa_set_key_usage_flags( &attributes, policy_usage );
1704 psa_set_key_algorithm( &attributes, policy_alg );
1705 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001706
Gilles Peskine049c7532019-05-15 20:22:09 +02001707 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1708 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001709
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001710 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001711 if( policy_alg == exercise_alg &&
1712 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001713 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001714 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001715 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716 psa_cipher_abort( &operation );
1717
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001718 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001719 if( policy_alg == exercise_alg &&
1720 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001721 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001722 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001723 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001724
1725exit:
1726 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001727 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001728 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001729}
1730/* END_CASE */
1731
1732/* BEGIN_CASE */
1733void aead_key_policy( int policy_usage,
1734 int policy_alg,
1735 int key_type,
1736 data_t *key_data,
1737 int nonce_length_arg,
1738 int tag_length_arg,
1739 int exercise_alg )
1740{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001741 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001742 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001743 psa_status_t status;
1744 unsigned char nonce[16] = {0};
1745 size_t nonce_length = nonce_length_arg;
1746 unsigned char tag[16];
1747 size_t tag_length = tag_length_arg;
1748 size_t output_length;
1749
1750 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1751 TEST_ASSERT( tag_length <= sizeof( tag ) );
1752
Gilles Peskine8817f612018-12-18 00:18:46 +01001753 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001754
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001755 psa_set_key_usage_flags( &attributes, policy_usage );
1756 psa_set_key_algorithm( &attributes, policy_alg );
1757 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758
Gilles Peskine049c7532019-05-15 20:22:09 +02001759 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1760 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001761
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001762 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001763 nonce, nonce_length,
1764 NULL, 0,
1765 NULL, 0,
1766 tag, tag_length,
1767 &output_length );
1768 if( policy_alg == exercise_alg &&
1769 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001770 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001771 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001772 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001773
1774 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001775 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001776 nonce, nonce_length,
1777 NULL, 0,
1778 tag, tag_length,
1779 NULL, 0,
1780 &output_length );
1781 if( policy_alg == exercise_alg &&
1782 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001783 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001784 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001785 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001786
1787exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001788 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001789 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001790}
1791/* END_CASE */
1792
1793/* BEGIN_CASE */
1794void asymmetric_encryption_key_policy( int policy_usage,
1795 int policy_alg,
1796 int key_type,
1797 data_t *key_data,
1798 int exercise_alg )
1799{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001800 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001801 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001802 psa_status_t status;
1803 size_t key_bits;
1804 size_t buffer_length;
1805 unsigned char *buffer = NULL;
1806 size_t output_length;
1807
Gilles Peskine8817f612018-12-18 00:18:46 +01001808 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001809
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001810 psa_set_key_usage_flags( &attributes, policy_usage );
1811 psa_set_key_algorithm( &attributes, policy_alg );
1812 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001813
Gilles Peskine049c7532019-05-15 20:22:09 +02001814 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1815 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001816
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001817 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1818 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001819 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1820 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001821 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001823 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001824 NULL, 0,
1825 NULL, 0,
1826 buffer, buffer_length,
1827 &output_length );
1828 if( policy_alg == exercise_alg &&
1829 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001830 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001831 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001832 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001833
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001834 if( buffer_length != 0 )
1835 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001836 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001837 buffer, buffer_length,
1838 NULL, 0,
1839 buffer, buffer_length,
1840 &output_length );
1841 if( policy_alg == exercise_alg &&
1842 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001843 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001844 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001845 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001846
1847exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001848 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001849 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001850 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001851 mbedtls_free( buffer );
1852}
1853/* END_CASE */
1854
1855/* BEGIN_CASE */
1856void asymmetric_signature_key_policy( int policy_usage,
1857 int policy_alg,
1858 int key_type,
1859 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001860 int exercise_alg,
1861 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001862{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001863 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001864 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001865 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001866 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1867 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1868 * compatible with the policy and `payload_length_arg` is supposed to be
1869 * a valid input length to sign. If `payload_length_arg <= 0`,
1870 * `exercise_alg` is supposed to be forbidden by the policy. */
1871 int compatible_alg = payload_length_arg > 0;
1872 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001873 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1874 size_t signature_length;
1875
Gilles Peskine8817f612018-12-18 00:18:46 +01001876 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001877
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001878 psa_set_key_usage_flags( &attributes, policy_usage );
1879 psa_set_key_algorithm( &attributes, policy_alg );
1880 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001881
Gilles Peskine049c7532019-05-15 20:22:09 +02001882 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1883 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001884
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001885 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001886 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001887 signature, sizeof( signature ),
1888 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001889 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001890 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001891 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001892 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001893
1894 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001895 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001896 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001897 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001898 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001899 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001900 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001901 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001902
1903exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001904 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001905 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001906}
1907/* END_CASE */
1908
Janos Follathba3fab92019-06-11 14:50:16 +01001909/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001910void derive_key_policy( int policy_usage,
1911 int policy_alg,
1912 int key_type,
1913 data_t *key_data,
1914 int exercise_alg )
1915{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001916 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001917 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001918 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001919 psa_status_t status;
1920
Gilles Peskine8817f612018-12-18 00:18:46 +01001921 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001922
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001923 psa_set_key_usage_flags( &attributes, policy_usage );
1924 psa_set_key_algorithm( &attributes, policy_alg );
1925 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001926
Gilles Peskine049c7532019-05-15 20:22:09 +02001927 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1928 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001929
Janos Follathba3fab92019-06-11 14:50:16 +01001930 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1931
1932 if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
1933 PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
Janos Follath0c1ed842019-06-28 13:35:36 +01001934 {
Janos Follathba3fab92019-06-11 14:50:16 +01001935 PSA_ASSERT( psa_key_derivation_input_bytes(
1936 &operation,
1937 PSA_KEY_DERIVATION_INPUT_SEED,
1938 (const uint8_t*) "", 0) );
Janos Follath0c1ed842019-06-28 13:35:36 +01001939 }
Janos Follathba3fab92019-06-11 14:50:16 +01001940
1941 status = psa_key_derivation_input_key( &operation,
1942 PSA_KEY_DERIVATION_INPUT_SECRET,
1943 handle );
1944
Gilles Peskineea0fb492018-07-12 17:17:20 +02001945 if( policy_alg == exercise_alg &&
1946 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001947 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001948 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001949 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001950
1951exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001952 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001953 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001954 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001955}
1956/* END_CASE */
1957
1958/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001959void agreement_key_policy( int policy_usage,
1960 int policy_alg,
1961 int key_type_arg,
1962 data_t *key_data,
1963 int exercise_alg )
1964{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001965 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001966 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001967 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001968 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001969 psa_status_t status;
1970
Gilles Peskine8817f612018-12-18 00:18:46 +01001971 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001972
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001973 psa_set_key_usage_flags( &attributes, policy_usage );
1974 psa_set_key_algorithm( &attributes, policy_alg );
1975 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001976
Gilles Peskine049c7532019-05-15 20:22:09 +02001977 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1978 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001979
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001980 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1981 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001982
Gilles Peskine01d718c2018-09-18 12:01:02 +02001983 if( policy_alg == exercise_alg &&
1984 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001985 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001986 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001987 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001988
1989exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001990 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001991 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001992 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001993}
1994/* END_CASE */
1995
1996/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001997void key_policy_alg2( int key_type_arg, data_t *key_data,
1998 int usage_arg, int alg_arg, int alg2_arg )
1999{
2000 psa_key_handle_t handle = 0;
2001 psa_key_type_t key_type = key_type_arg;
2002 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
2003 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
2004 psa_key_usage_t usage = usage_arg;
2005 psa_algorithm_t alg = alg_arg;
2006 psa_algorithm_t alg2 = alg2_arg;
2007
2008 PSA_ASSERT( psa_crypto_init( ) );
2009
2010 psa_set_key_usage_flags( &attributes, usage );
2011 psa_set_key_algorithm( &attributes, alg );
2012 psa_set_key_enrollment_algorithm( &attributes, alg2 );
2013 psa_set_key_type( &attributes, key_type );
2014 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2015 &handle ) );
2016
2017 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
2018 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
2019 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
2020 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
2021
2022 if( ! exercise_key( handle, usage, alg ) )
2023 goto exit;
2024 if( ! exercise_key( handle, usage, alg2 ) )
2025 goto exit;
2026
2027exit:
2028 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002029 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002030}
2031/* END_CASE */
2032
2033/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002034void raw_agreement_key_policy( int policy_usage,
2035 int policy_alg,
2036 int key_type_arg,
2037 data_t *key_data,
2038 int exercise_alg )
2039{
2040 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002041 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002042 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002043 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002044 psa_status_t status;
2045
2046 PSA_ASSERT( psa_crypto_init( ) );
2047
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002048 psa_set_key_usage_flags( &attributes, policy_usage );
2049 psa_set_key_algorithm( &attributes, policy_alg );
2050 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002051
Gilles Peskine049c7532019-05-15 20:22:09 +02002052 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2053 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002054
2055 status = raw_key_agreement_with_self( exercise_alg, handle );
2056
2057 if( policy_alg == exercise_alg &&
2058 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
2059 PSA_ASSERT( status );
2060 else
2061 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
2062
2063exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002064 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002065 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002066 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002067}
2068/* END_CASE */
2069
2070/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002071void copy_success( int source_usage_arg,
2072 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002073 int type_arg, data_t *material,
2074 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002075 int target_usage_arg,
2076 int target_alg_arg, int target_alg2_arg,
2077 int expected_usage_arg,
2078 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01002079{
Gilles Peskineca25db92019-04-19 11:43:08 +02002080 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2081 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002082 psa_key_usage_t expected_usage = expected_usage_arg;
2083 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002084 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002085 psa_key_handle_t source_handle = 0;
2086 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002087 uint8_t *export_buffer = NULL;
2088
Gilles Peskine57ab7212019-01-28 13:03:09 +01002089 PSA_ASSERT( psa_crypto_init( ) );
2090
Gilles Peskineca25db92019-04-19 11:43:08 +02002091 /* Prepare the source key. */
2092 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2093 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002094 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002095 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002096 PSA_ASSERT( psa_import_key( &source_attributes,
2097 material->x, material->len,
2098 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002099 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002100
Gilles Peskineca25db92019-04-19 11:43:08 +02002101 /* Prepare the target attributes. */
2102 if( copy_attributes )
2103 target_attributes = source_attributes;
2104 if( target_usage_arg != -1 )
2105 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2106 if( target_alg_arg != -1 )
2107 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002108 if( target_alg2_arg != -1 )
2109 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002110
2111 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002112 PSA_ASSERT( psa_copy_key( source_handle,
2113 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002114
2115 /* Destroy the source to ensure that this doesn't affect the target. */
2116 PSA_ASSERT( psa_destroy_key( source_handle ) );
2117
2118 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002119 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2120 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2121 psa_get_key_type( &target_attributes ) );
2122 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2123 psa_get_key_bits( &target_attributes ) );
2124 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2125 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002126 TEST_EQUAL( expected_alg2,
2127 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002128 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2129 {
2130 size_t length;
2131 ASSERT_ALLOC( export_buffer, material->len );
2132 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2133 material->len, &length ) );
2134 ASSERT_COMPARE( material->x, material->len,
2135 export_buffer, length );
2136 }
2137 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2138 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002139 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2140 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002141
2142 PSA_ASSERT( psa_close_key( target_handle ) );
2143
2144exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002145 psa_reset_key_attributes( &source_attributes );
2146 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002147 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002148 mbedtls_free( export_buffer );
2149}
2150/* END_CASE */
2151
2152/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002153void copy_fail( int source_usage_arg,
2154 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002155 int type_arg, data_t *material,
2156 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002157 int target_usage_arg,
2158 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002159 int expected_status_arg )
2160{
2161 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2162 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2163 psa_key_handle_t source_handle = 0;
2164 psa_key_handle_t target_handle = 0;
2165
2166 PSA_ASSERT( psa_crypto_init( ) );
2167
2168 /* Prepare the source key. */
2169 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2170 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002171 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002172 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002173 PSA_ASSERT( psa_import_key( &source_attributes,
2174 material->x, material->len,
2175 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002176
2177 /* Prepare the target attributes. */
2178 psa_set_key_type( &target_attributes, target_type_arg );
2179 psa_set_key_bits( &target_attributes, target_bits_arg );
2180 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2181 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002182 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002183
2184 /* Try to copy the key. */
2185 TEST_EQUAL( psa_copy_key( source_handle,
2186 &target_attributes, &target_handle ),
2187 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002188
2189 PSA_ASSERT( psa_destroy_key( source_handle ) );
2190
Gilles Peskine4a644642019-05-03 17:14:08 +02002191exit:
2192 psa_reset_key_attributes( &source_attributes );
2193 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002194 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002195}
2196/* END_CASE */
2197
2198/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002199void hash_operation_init( )
2200{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002201 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002202 /* Test each valid way of initializing the object, except for `= {0}`, as
2203 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2204 * though it's OK by the C standard. We could test for this, but we'd need
2205 * to supress the Clang warning for the test. */
2206 psa_hash_operation_t func = psa_hash_operation_init( );
2207 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2208 psa_hash_operation_t zero;
2209
2210 memset( &zero, 0, sizeof( zero ) );
2211
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002212 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002213 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2214 PSA_ERROR_BAD_STATE );
2215 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2216 PSA_ERROR_BAD_STATE );
2217 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2218 PSA_ERROR_BAD_STATE );
2219
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002220 /* A default hash operation should be abortable without error. */
2221 PSA_ASSERT( psa_hash_abort( &func ) );
2222 PSA_ASSERT( psa_hash_abort( &init ) );
2223 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002224}
2225/* END_CASE */
2226
2227/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002228void hash_setup( int alg_arg,
2229 int expected_status_arg )
2230{
2231 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002232 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002233 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002234 psa_status_t status;
2235
Gilles Peskine8817f612018-12-18 00:18:46 +01002236 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002237
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002238 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002239 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002240
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002241 /* Whether setup succeeded or failed, abort must succeed. */
2242 PSA_ASSERT( psa_hash_abort( &operation ) );
2243
2244 /* If setup failed, reproduce the failure, so as to
2245 * test the resulting state of the operation object. */
2246 if( status != PSA_SUCCESS )
2247 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2248
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002249 /* Now the operation object should be reusable. */
2250#if defined(KNOWN_SUPPORTED_HASH_ALG)
2251 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2252 PSA_ASSERT( psa_hash_abort( &operation ) );
2253#endif
2254
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002255exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002256 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002257}
2258/* END_CASE */
2259
2260/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002261void hash_bad_order( )
2262{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002263 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002264 unsigned char input[] = "";
2265 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002266 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002267 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2268 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2269 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002270 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002271 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002272 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002273
Gilles Peskine8817f612018-12-18 00:18:46 +01002274 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002275
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002276 /* Call setup twice in a row. */
2277 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2278 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2279 PSA_ERROR_BAD_STATE );
2280 PSA_ASSERT( psa_hash_abort( &operation ) );
2281
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002282 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002283 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002284 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002285 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002286
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002287 /* Call update after finish. */
2288 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2289 PSA_ASSERT( psa_hash_finish( &operation,
2290 hash, sizeof( hash ), &hash_len ) );
2291 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002292 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002293 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002294
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002295 /* Call verify without calling setup beforehand. */
2296 TEST_EQUAL( psa_hash_verify( &operation,
2297 valid_hash, sizeof( valid_hash ) ),
2298 PSA_ERROR_BAD_STATE );
2299 PSA_ASSERT( psa_hash_abort( &operation ) );
2300
2301 /* Call verify after finish. */
2302 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2303 PSA_ASSERT( psa_hash_finish( &operation,
2304 hash, sizeof( hash ), &hash_len ) );
2305 TEST_EQUAL( psa_hash_verify( &operation,
2306 valid_hash, sizeof( valid_hash ) ),
2307 PSA_ERROR_BAD_STATE );
2308 PSA_ASSERT( psa_hash_abort( &operation ) );
2309
2310 /* Call verify twice in a row. */
2311 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2312 PSA_ASSERT( psa_hash_verify( &operation,
2313 valid_hash, sizeof( valid_hash ) ) );
2314 TEST_EQUAL( psa_hash_verify( &operation,
2315 valid_hash, sizeof( valid_hash ) ),
2316 PSA_ERROR_BAD_STATE );
2317 PSA_ASSERT( psa_hash_abort( &operation ) );
2318
2319 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002320 TEST_EQUAL( psa_hash_finish( &operation,
2321 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002322 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002323 PSA_ASSERT( psa_hash_abort( &operation ) );
2324
2325 /* Call finish twice in a row. */
2326 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2327 PSA_ASSERT( psa_hash_finish( &operation,
2328 hash, sizeof( hash ), &hash_len ) );
2329 TEST_EQUAL( psa_hash_finish( &operation,
2330 hash, sizeof( hash ), &hash_len ),
2331 PSA_ERROR_BAD_STATE );
2332 PSA_ASSERT( psa_hash_abort( &operation ) );
2333
2334 /* Call finish after calling verify. */
2335 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2336 PSA_ASSERT( psa_hash_verify( &operation,
2337 valid_hash, sizeof( valid_hash ) ) );
2338 TEST_EQUAL( psa_hash_finish( &operation,
2339 hash, sizeof( hash ), &hash_len ),
2340 PSA_ERROR_BAD_STATE );
2341 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002342
2343exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002344 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002345}
2346/* END_CASE */
2347
itayzafrir27e69452018-11-01 14:26:34 +02002348/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2349void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002350{
2351 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002352 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2353 * appended to it */
2354 unsigned char hash[] = {
2355 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2356 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2357 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002358 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002359 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002360
Gilles Peskine8817f612018-12-18 00:18:46 +01002361 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002362
itayzafrir27e69452018-11-01 14:26:34 +02002363 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002364 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002365 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002366 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002367
itayzafrir27e69452018-11-01 14:26:34 +02002368 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002369 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002370 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002371 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002372
itayzafrir27e69452018-11-01 14:26:34 +02002373 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002374 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002375 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002376 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002377
itayzafrirec93d302018-10-18 18:01:10 +03002378exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002379 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002380}
2381/* END_CASE */
2382
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002383/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2384void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002385{
2386 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002387 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002388 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002389 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002390 size_t hash_len;
2391
Gilles Peskine8817f612018-12-18 00:18:46 +01002392 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002393
itayzafrir58028322018-10-25 10:22:01 +03002394 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002395 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002396 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002397 hash, expected_size - 1, &hash_len ),
2398 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002399
2400exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002401 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002402}
2403/* END_CASE */
2404
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002405/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2406void hash_clone_source_state( )
2407{
2408 psa_algorithm_t alg = PSA_ALG_SHA_256;
2409 unsigned char hash[PSA_HASH_MAX_SIZE];
2410 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2411 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2412 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2413 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2414 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2415 size_t hash_len;
2416
2417 PSA_ASSERT( psa_crypto_init( ) );
2418 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2419
2420 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2421 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2422 PSA_ASSERT( psa_hash_finish( &op_finished,
2423 hash, sizeof( hash ), &hash_len ) );
2424 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2425 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2426
2427 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2428 PSA_ERROR_BAD_STATE );
2429
2430 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2431 PSA_ASSERT( psa_hash_finish( &op_init,
2432 hash, sizeof( hash ), &hash_len ) );
2433 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2434 PSA_ASSERT( psa_hash_finish( &op_finished,
2435 hash, sizeof( hash ), &hash_len ) );
2436 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2437 PSA_ASSERT( psa_hash_finish( &op_aborted,
2438 hash, sizeof( hash ), &hash_len ) );
2439
2440exit:
2441 psa_hash_abort( &op_source );
2442 psa_hash_abort( &op_init );
2443 psa_hash_abort( &op_setup );
2444 psa_hash_abort( &op_finished );
2445 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002446 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002447}
2448/* END_CASE */
2449
2450/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2451void hash_clone_target_state( )
2452{
2453 psa_algorithm_t alg = PSA_ALG_SHA_256;
2454 unsigned char hash[PSA_HASH_MAX_SIZE];
2455 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2456 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2457 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2458 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2459 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2460 size_t hash_len;
2461
2462 PSA_ASSERT( psa_crypto_init( ) );
2463
2464 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2465 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2466 PSA_ASSERT( psa_hash_finish( &op_finished,
2467 hash, sizeof( hash ), &hash_len ) );
2468 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2469 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2470
2471 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2472 PSA_ASSERT( psa_hash_finish( &op_target,
2473 hash, sizeof( hash ), &hash_len ) );
2474
2475 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2476 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2477 PSA_ERROR_BAD_STATE );
2478 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2479 PSA_ERROR_BAD_STATE );
2480
2481exit:
2482 psa_hash_abort( &op_target );
2483 psa_hash_abort( &op_init );
2484 psa_hash_abort( &op_setup );
2485 psa_hash_abort( &op_finished );
2486 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002487 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002488}
2489/* END_CASE */
2490
itayzafrir58028322018-10-25 10:22:01 +03002491/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002492void mac_operation_init( )
2493{
Jaeden Amero252ef282019-02-15 14:05:35 +00002494 const uint8_t input[1] = { 0 };
2495
Jaeden Amero769ce272019-01-04 11:48:03 +00002496 /* Test each valid way of initializing the object, except for `= {0}`, as
2497 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2498 * though it's OK by the C standard. We could test for this, but we'd need
2499 * to supress the Clang warning for the test. */
2500 psa_mac_operation_t func = psa_mac_operation_init( );
2501 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2502 psa_mac_operation_t zero;
2503
2504 memset( &zero, 0, sizeof( zero ) );
2505
Jaeden Amero252ef282019-02-15 14:05:35 +00002506 /* A freshly-initialized MAC operation should not be usable. */
2507 TEST_EQUAL( psa_mac_update( &func,
2508 input, sizeof( input ) ),
2509 PSA_ERROR_BAD_STATE );
2510 TEST_EQUAL( psa_mac_update( &init,
2511 input, sizeof( input ) ),
2512 PSA_ERROR_BAD_STATE );
2513 TEST_EQUAL( psa_mac_update( &zero,
2514 input, sizeof( input ) ),
2515 PSA_ERROR_BAD_STATE );
2516
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002517 /* A default MAC operation should be abortable without error. */
2518 PSA_ASSERT( psa_mac_abort( &func ) );
2519 PSA_ASSERT( psa_mac_abort( &init ) );
2520 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002521}
2522/* END_CASE */
2523
2524/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002525void mac_setup( int key_type_arg,
2526 data_t *key,
2527 int alg_arg,
2528 int expected_status_arg )
2529{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002530 psa_key_type_t key_type = key_type_arg;
2531 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002532 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002533 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002534 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2535#if defined(KNOWN_SUPPORTED_MAC_ALG)
2536 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2537#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002538
Gilles Peskine8817f612018-12-18 00:18:46 +01002539 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002540
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002541 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2542 &operation, &status ) )
2543 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002544 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002545
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002546 /* The operation object should be reusable. */
2547#if defined(KNOWN_SUPPORTED_MAC_ALG)
2548 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2549 smoke_test_key_data,
2550 sizeof( smoke_test_key_data ),
2551 KNOWN_SUPPORTED_MAC_ALG,
2552 &operation, &status ) )
2553 goto exit;
2554 TEST_EQUAL( status, PSA_SUCCESS );
2555#endif
2556
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002557exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002558 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002559}
2560/* END_CASE */
2561
2562/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002563void mac_bad_order( )
2564{
2565 psa_key_handle_t handle = 0;
2566 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2567 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2568 const uint8_t key[] = {
2569 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2570 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2571 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002572 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002573 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2574 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2575 size_t sign_mac_length = 0;
2576 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2577 const uint8_t verify_mac[] = {
2578 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2579 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2580 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2581
2582 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002583 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2584 psa_set_key_algorithm( &attributes, alg );
2585 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002586
Gilles Peskine73676cb2019-05-15 20:15:10 +02002587 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002588
Jaeden Amero252ef282019-02-15 14:05:35 +00002589 /* Call update without calling setup beforehand. */
2590 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2591 PSA_ERROR_BAD_STATE );
2592 PSA_ASSERT( psa_mac_abort( &operation ) );
2593
2594 /* Call sign finish without calling setup beforehand. */
2595 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2596 &sign_mac_length),
2597 PSA_ERROR_BAD_STATE );
2598 PSA_ASSERT( psa_mac_abort( &operation ) );
2599
2600 /* Call verify finish without calling setup beforehand. */
2601 TEST_EQUAL( psa_mac_verify_finish( &operation,
2602 verify_mac, sizeof( verify_mac ) ),
2603 PSA_ERROR_BAD_STATE );
2604 PSA_ASSERT( psa_mac_abort( &operation ) );
2605
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002606 /* Call setup twice in a row. */
2607 PSA_ASSERT( psa_mac_sign_setup( &operation,
2608 handle, alg ) );
2609 TEST_EQUAL( psa_mac_sign_setup( &operation,
2610 handle, alg ),
2611 PSA_ERROR_BAD_STATE );
2612 PSA_ASSERT( psa_mac_abort( &operation ) );
2613
Jaeden Amero252ef282019-02-15 14:05:35 +00002614 /* Call update after sign finish. */
2615 PSA_ASSERT( psa_mac_sign_setup( &operation,
2616 handle, alg ) );
2617 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2618 PSA_ASSERT( psa_mac_sign_finish( &operation,
2619 sign_mac, sizeof( sign_mac ),
2620 &sign_mac_length ) );
2621 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2622 PSA_ERROR_BAD_STATE );
2623 PSA_ASSERT( psa_mac_abort( &operation ) );
2624
2625 /* Call update after verify finish. */
2626 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002627 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002628 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2629 PSA_ASSERT( psa_mac_verify_finish( &operation,
2630 verify_mac, sizeof( verify_mac ) ) );
2631 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2632 PSA_ERROR_BAD_STATE );
2633 PSA_ASSERT( psa_mac_abort( &operation ) );
2634
2635 /* Call sign finish twice in a row. */
2636 PSA_ASSERT( psa_mac_sign_setup( &operation,
2637 handle, alg ) );
2638 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2639 PSA_ASSERT( psa_mac_sign_finish( &operation,
2640 sign_mac, sizeof( sign_mac ),
2641 &sign_mac_length ) );
2642 TEST_EQUAL( psa_mac_sign_finish( &operation,
2643 sign_mac, sizeof( sign_mac ),
2644 &sign_mac_length ),
2645 PSA_ERROR_BAD_STATE );
2646 PSA_ASSERT( psa_mac_abort( &operation ) );
2647
2648 /* Call verify finish twice in a row. */
2649 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002650 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002651 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2652 PSA_ASSERT( psa_mac_verify_finish( &operation,
2653 verify_mac, sizeof( verify_mac ) ) );
2654 TEST_EQUAL( psa_mac_verify_finish( &operation,
2655 verify_mac, sizeof( verify_mac ) ),
2656 PSA_ERROR_BAD_STATE );
2657 PSA_ASSERT( psa_mac_abort( &operation ) );
2658
2659 /* Setup sign but try verify. */
2660 PSA_ASSERT( psa_mac_sign_setup( &operation,
2661 handle, alg ) );
2662 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2663 TEST_EQUAL( psa_mac_verify_finish( &operation,
2664 verify_mac, sizeof( verify_mac ) ),
2665 PSA_ERROR_BAD_STATE );
2666 PSA_ASSERT( psa_mac_abort( &operation ) );
2667
2668 /* Setup verify but try sign. */
2669 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002670 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002671 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2672 TEST_EQUAL( psa_mac_sign_finish( &operation,
2673 sign_mac, sizeof( sign_mac ),
2674 &sign_mac_length ),
2675 PSA_ERROR_BAD_STATE );
2676 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002677
Gilles Peskine76b29a72019-05-28 14:08:50 +02002678 PSA_ASSERT( psa_destroy_key( handle ) );
2679
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002680exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002681 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002682}
2683/* END_CASE */
2684
2685/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002686void mac_sign( int key_type_arg,
2687 data_t *key,
2688 int alg_arg,
2689 data_t *input,
2690 data_t *expected_mac )
2691{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002692 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002693 psa_key_type_t key_type = key_type_arg;
2694 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002695 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002696 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002697 /* Leave a little extra room in the output buffer. At the end of the
2698 * test, we'll check that the implementation didn't overwrite onto
2699 * this extra room. */
2700 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2701 size_t mac_buffer_size =
2702 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2703 size_t mac_length = 0;
2704
2705 memset( actual_mac, '+', sizeof( actual_mac ) );
2706 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2707 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2708
Gilles Peskine8817f612018-12-18 00:18:46 +01002709 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002710
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002711 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2712 psa_set_key_algorithm( &attributes, alg );
2713 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002714
Gilles Peskine73676cb2019-05-15 20:15:10 +02002715 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002716
2717 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002718 PSA_ASSERT( psa_mac_sign_setup( &operation,
2719 handle, alg ) );
2720 PSA_ASSERT( psa_mac_update( &operation,
2721 input->x, input->len ) );
2722 PSA_ASSERT( psa_mac_sign_finish( &operation,
2723 actual_mac, mac_buffer_size,
2724 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002725
2726 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002727 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2728 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002729
2730 /* Verify that the end of the buffer is untouched. */
2731 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2732 sizeof( actual_mac ) - mac_length ) );
2733
2734exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002735 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002736 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002737}
2738/* END_CASE */
2739
2740/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002741void mac_verify( int key_type_arg,
2742 data_t *key,
2743 int alg_arg,
2744 data_t *input,
2745 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002746{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002747 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002748 psa_key_type_t key_type = key_type_arg;
2749 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002750 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002751 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002752
Gilles Peskine69c12672018-06-28 00:07:19 +02002753 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2754
Gilles Peskine8817f612018-12-18 00:18:46 +01002755 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002756
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002757 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2758 psa_set_key_algorithm( &attributes, alg );
2759 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002760
Gilles Peskine73676cb2019-05-15 20:15:10 +02002761 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002762
Gilles Peskine8817f612018-12-18 00:18:46 +01002763 PSA_ASSERT( psa_mac_verify_setup( &operation,
2764 handle, alg ) );
2765 PSA_ASSERT( psa_destroy_key( handle ) );
2766 PSA_ASSERT( psa_mac_update( &operation,
2767 input->x, input->len ) );
2768 PSA_ASSERT( psa_mac_verify_finish( &operation,
2769 expected_mac->x,
2770 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002771
2772exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002773 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002774 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002775}
2776/* END_CASE */
2777
2778/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002779void cipher_operation_init( )
2780{
Jaeden Ameroab439972019-02-15 14:12:05 +00002781 const uint8_t input[1] = { 0 };
2782 unsigned char output[1] = { 0 };
2783 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002784 /* Test each valid way of initializing the object, except for `= {0}`, as
2785 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2786 * though it's OK by the C standard. We could test for this, but we'd need
2787 * to supress the Clang warning for the test. */
2788 psa_cipher_operation_t func = psa_cipher_operation_init( );
2789 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2790 psa_cipher_operation_t zero;
2791
2792 memset( &zero, 0, sizeof( zero ) );
2793
Jaeden Ameroab439972019-02-15 14:12:05 +00002794 /* A freshly-initialized cipher operation should not be usable. */
2795 TEST_EQUAL( psa_cipher_update( &func,
2796 input, sizeof( input ),
2797 output, sizeof( output ),
2798 &output_length ),
2799 PSA_ERROR_BAD_STATE );
2800 TEST_EQUAL( psa_cipher_update( &init,
2801 input, sizeof( input ),
2802 output, sizeof( output ),
2803 &output_length ),
2804 PSA_ERROR_BAD_STATE );
2805 TEST_EQUAL( psa_cipher_update( &zero,
2806 input, sizeof( input ),
2807 output, sizeof( output ),
2808 &output_length ),
2809 PSA_ERROR_BAD_STATE );
2810
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002811 /* A default cipher operation should be abortable without error. */
2812 PSA_ASSERT( psa_cipher_abort( &func ) );
2813 PSA_ASSERT( psa_cipher_abort( &init ) );
2814 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002815}
2816/* END_CASE */
2817
2818/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002819void cipher_setup( int key_type_arg,
2820 data_t *key,
2821 int alg_arg,
2822 int expected_status_arg )
2823{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002824 psa_key_type_t key_type = key_type_arg;
2825 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002826 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002827 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002828 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002829#if defined(KNOWN_SUPPORTED_MAC_ALG)
2830 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2831#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002832
Gilles Peskine8817f612018-12-18 00:18:46 +01002833 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002834
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002835 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2836 &operation, &status ) )
2837 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002838 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002839
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002840 /* The operation object should be reusable. */
2841#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2842 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2843 smoke_test_key_data,
2844 sizeof( smoke_test_key_data ),
2845 KNOWN_SUPPORTED_CIPHER_ALG,
2846 &operation, &status ) )
2847 goto exit;
2848 TEST_EQUAL( status, PSA_SUCCESS );
2849#endif
2850
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002851exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002852 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002853}
2854/* END_CASE */
2855
2856/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002857void cipher_bad_order( )
2858{
2859 psa_key_handle_t handle = 0;
2860 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2861 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002862 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002863 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2864 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2865 const uint8_t key[] = {
2866 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2867 0xaa, 0xaa, 0xaa, 0xaa };
2868 const uint8_t text[] = {
2869 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2870 0xbb, 0xbb, 0xbb, 0xbb };
2871 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2872 size_t length = 0;
2873
2874 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002875 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2876 psa_set_key_algorithm( &attributes, alg );
2877 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002878 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002879
2880
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002881 /* Call encrypt setup twice in a row. */
2882 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2883 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2884 PSA_ERROR_BAD_STATE );
2885 PSA_ASSERT( psa_cipher_abort( &operation ) );
2886
2887 /* Call decrypt setup twice in a row. */
2888 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2889 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2890 PSA_ERROR_BAD_STATE );
2891 PSA_ASSERT( psa_cipher_abort( &operation ) );
2892
Jaeden Ameroab439972019-02-15 14:12:05 +00002893 /* Generate an IV without calling setup beforehand. */
2894 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2895 buffer, sizeof( buffer ),
2896 &length ),
2897 PSA_ERROR_BAD_STATE );
2898 PSA_ASSERT( psa_cipher_abort( &operation ) );
2899
2900 /* Generate an IV twice in a row. */
2901 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2902 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2903 buffer, sizeof( buffer ),
2904 &length ) );
2905 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2906 buffer, sizeof( buffer ),
2907 &length ),
2908 PSA_ERROR_BAD_STATE );
2909 PSA_ASSERT( psa_cipher_abort( &operation ) );
2910
2911 /* Generate an IV after it's already set. */
2912 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2913 PSA_ASSERT( psa_cipher_set_iv( &operation,
2914 iv, sizeof( iv ) ) );
2915 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2916 buffer, sizeof( buffer ),
2917 &length ),
2918 PSA_ERROR_BAD_STATE );
2919 PSA_ASSERT( psa_cipher_abort( &operation ) );
2920
2921 /* Set an IV without calling setup beforehand. */
2922 TEST_EQUAL( psa_cipher_set_iv( &operation,
2923 iv, sizeof( iv ) ),
2924 PSA_ERROR_BAD_STATE );
2925 PSA_ASSERT( psa_cipher_abort( &operation ) );
2926
2927 /* Set an IV after it's already set. */
2928 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2929 PSA_ASSERT( psa_cipher_set_iv( &operation,
2930 iv, sizeof( iv ) ) );
2931 TEST_EQUAL( psa_cipher_set_iv( &operation,
2932 iv, sizeof( iv ) ),
2933 PSA_ERROR_BAD_STATE );
2934 PSA_ASSERT( psa_cipher_abort( &operation ) );
2935
2936 /* Set an IV after it's already generated. */
2937 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2938 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2939 buffer, sizeof( buffer ),
2940 &length ) );
2941 TEST_EQUAL( psa_cipher_set_iv( &operation,
2942 iv, sizeof( iv ) ),
2943 PSA_ERROR_BAD_STATE );
2944 PSA_ASSERT( psa_cipher_abort( &operation ) );
2945
2946 /* Call update without calling setup beforehand. */
2947 TEST_EQUAL( psa_cipher_update( &operation,
2948 text, sizeof( text ),
2949 buffer, sizeof( buffer ),
2950 &length ),
2951 PSA_ERROR_BAD_STATE );
2952 PSA_ASSERT( psa_cipher_abort( &operation ) );
2953
2954 /* Call update without an IV where an IV is required. */
2955 TEST_EQUAL( psa_cipher_update( &operation,
2956 text, sizeof( text ),
2957 buffer, sizeof( buffer ),
2958 &length ),
2959 PSA_ERROR_BAD_STATE );
2960 PSA_ASSERT( psa_cipher_abort( &operation ) );
2961
2962 /* Call update after finish. */
2963 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2964 PSA_ASSERT( psa_cipher_set_iv( &operation,
2965 iv, sizeof( iv ) ) );
2966 PSA_ASSERT( psa_cipher_finish( &operation,
2967 buffer, sizeof( buffer ), &length ) );
2968 TEST_EQUAL( psa_cipher_update( &operation,
2969 text, sizeof( text ),
2970 buffer, sizeof( buffer ),
2971 &length ),
2972 PSA_ERROR_BAD_STATE );
2973 PSA_ASSERT( psa_cipher_abort( &operation ) );
2974
2975 /* Call finish without calling setup beforehand. */
2976 TEST_EQUAL( psa_cipher_finish( &operation,
2977 buffer, sizeof( buffer ), &length ),
2978 PSA_ERROR_BAD_STATE );
2979 PSA_ASSERT( psa_cipher_abort( &operation ) );
2980
2981 /* Call finish without an IV where an IV is required. */
2982 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2983 /* Not calling update means we are encrypting an empty buffer, which is OK
2984 * for cipher modes with padding. */
2985 TEST_EQUAL( psa_cipher_finish( &operation,
2986 buffer, sizeof( buffer ), &length ),
2987 PSA_ERROR_BAD_STATE );
2988 PSA_ASSERT( psa_cipher_abort( &operation ) );
2989
2990 /* Call finish twice in a row. */
2991 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2992 PSA_ASSERT( psa_cipher_set_iv( &operation,
2993 iv, sizeof( iv ) ) );
2994 PSA_ASSERT( psa_cipher_finish( &operation,
2995 buffer, sizeof( buffer ), &length ) );
2996 TEST_EQUAL( psa_cipher_finish( &operation,
2997 buffer, sizeof( buffer ), &length ),
2998 PSA_ERROR_BAD_STATE );
2999 PSA_ASSERT( psa_cipher_abort( &operation ) );
3000
Gilles Peskine76b29a72019-05-28 14:08:50 +02003001 PSA_ASSERT( psa_destroy_key( handle ) );
3002
Jaeden Ameroab439972019-02-15 14:12:05 +00003003exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003004 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003005}
3006/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003007
Gilles Peskine50e586b2018-06-08 14:28:46 +02003008/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003009void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003010 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003011 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003012 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003013{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003014 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003015 psa_status_t status;
3016 psa_key_type_t key_type = key_type_arg;
3017 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003018 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003019 unsigned char *output = NULL;
3020 size_t output_buffer_size = 0;
3021 size_t function_output_length = 0;
3022 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003023 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003024 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003025
Gilles Peskine8817f612018-12-18 00:18:46 +01003026 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003027
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003028 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3029 psa_set_key_algorithm( &attributes, alg );
3030 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003031
Gilles Peskine73676cb2019-05-15 20:15:10 +02003032 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003033
Gilles Peskine8817f612018-12-18 00:18:46 +01003034 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3035 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003036
Gilles Peskine423005e2019-05-06 15:22:57 +02003037 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003038 output_buffer_size = ( (size_t) input->len +
3039 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003040 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041
Gilles Peskine8817f612018-12-18 00:18:46 +01003042 PSA_ASSERT( psa_cipher_update( &operation,
3043 input->x, input->len,
3044 output, output_buffer_size,
3045 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003046 total_output_length += function_output_length;
3047 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003048 output + total_output_length,
3049 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003050 &function_output_length );
3051 total_output_length += function_output_length;
3052
Gilles Peskinefe11b722018-12-18 00:24:04 +01003053 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003054 if( expected_status == PSA_SUCCESS )
3055 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003056 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003057 ASSERT_COMPARE( expected_output->x, expected_output->len,
3058 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003059 }
3060
3061exit:
3062 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003063 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003064 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065}
3066/* END_CASE */
3067
3068/* BEGIN_CASE */
3069void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003070 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003071 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003072 int first_part_size_arg,
3073 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074 data_t *expected_output )
3075{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003076 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003077 psa_key_type_t key_type = key_type_arg;
3078 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003079 size_t first_part_size = first_part_size_arg;
3080 size_t output1_length = output1_length_arg;
3081 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003082 unsigned char *output = NULL;
3083 size_t output_buffer_size = 0;
3084 size_t function_output_length = 0;
3085 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003086 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003087 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003088
Gilles Peskine8817f612018-12-18 00:18:46 +01003089 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003090
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003091 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3092 psa_set_key_algorithm( &attributes, alg );
3093 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003094
Gilles Peskine73676cb2019-05-15 20:15:10 +02003095 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003096
Gilles Peskine8817f612018-12-18 00:18:46 +01003097 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3098 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003099
Gilles Peskine423005e2019-05-06 15:22:57 +02003100 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003101 output_buffer_size = ( (size_t) input->len +
3102 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003103 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003104
Gilles Peskinee0866522019-02-19 19:44:00 +01003105 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003106 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3107 output, output_buffer_size,
3108 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003109 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003110 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003111 PSA_ASSERT( psa_cipher_update( &operation,
3112 input->x + first_part_size,
3113 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003114 output + total_output_length,
3115 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003116 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003117 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003118 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003119 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003120 output + total_output_length,
3121 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003122 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003123 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003124 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003125
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003126 ASSERT_COMPARE( expected_output->x, expected_output->len,
3127 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003128
3129exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003130 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003131 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003132 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003133}
3134/* END_CASE */
3135
3136/* BEGIN_CASE */
3137void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003138 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003139 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003140 int first_part_size_arg,
3141 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003142 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003143{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003144 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003145
3146 psa_key_type_t key_type = key_type_arg;
3147 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003148 size_t first_part_size = first_part_size_arg;
3149 size_t output1_length = output1_length_arg;
3150 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003151 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003152 size_t output_buffer_size = 0;
3153 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003154 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003155 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003156 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003157
Gilles Peskine8817f612018-12-18 00:18:46 +01003158 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003159
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003160 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3161 psa_set_key_algorithm( &attributes, alg );
3162 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003163
Gilles Peskine73676cb2019-05-15 20:15:10 +02003164 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003165
Gilles Peskine8817f612018-12-18 00:18:46 +01003166 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3167 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003168
Gilles Peskine423005e2019-05-06 15:22:57 +02003169 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003170
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003171 output_buffer_size = ( (size_t) input->len +
3172 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003173 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003174
Gilles Peskinee0866522019-02-19 19:44:00 +01003175 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003176 PSA_ASSERT( psa_cipher_update( &operation,
3177 input->x, first_part_size,
3178 output, output_buffer_size,
3179 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003180 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003181 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003182 PSA_ASSERT( psa_cipher_update( &operation,
3183 input->x + first_part_size,
3184 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003185 output + total_output_length,
3186 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003187 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003188 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003189 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003190 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003191 output + total_output_length,
3192 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003193 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003194 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003195 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003196
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003197 ASSERT_COMPARE( expected_output->x, expected_output->len,
3198 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003199
3200exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003201 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003202 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003203 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003204}
3205/* END_CASE */
3206
Gilles Peskine50e586b2018-06-08 14:28:46 +02003207/* BEGIN_CASE */
3208void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003209 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003210 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003211 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003212{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003213 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003214 psa_status_t status;
3215 psa_key_type_t key_type = key_type_arg;
3216 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003217 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003218 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003219 size_t output_buffer_size = 0;
3220 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003221 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003222 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003223 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003224
Gilles Peskine8817f612018-12-18 00:18:46 +01003225 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003226
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003227 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3228 psa_set_key_algorithm( &attributes, alg );
3229 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003230
Gilles Peskine73676cb2019-05-15 20:15:10 +02003231 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003232
Gilles Peskine8817f612018-12-18 00:18:46 +01003233 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3234 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003235
Gilles Peskine423005e2019-05-06 15:22:57 +02003236 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003237
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003238 output_buffer_size = ( (size_t) input->len +
3239 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003240 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003241
Gilles Peskine8817f612018-12-18 00:18:46 +01003242 PSA_ASSERT( psa_cipher_update( &operation,
3243 input->x, input->len,
3244 output, output_buffer_size,
3245 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003246 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003247 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003248 output + total_output_length,
3249 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003250 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003251 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003252 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003253
3254 if( expected_status == PSA_SUCCESS )
3255 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003256 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003257 ASSERT_COMPARE( expected_output->x, expected_output->len,
3258 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003259 }
3260
Gilles Peskine50e586b2018-06-08 14:28:46 +02003261exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003262 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003263 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003264 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003265}
3266/* END_CASE */
3267
Gilles Peskine50e586b2018-06-08 14:28:46 +02003268/* BEGIN_CASE */
3269void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003270 data_t *key,
3271 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003272{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003273 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003274 psa_key_type_t key_type = key_type_arg;
3275 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003276 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003277 size_t iv_size = 16;
3278 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003279 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003280 size_t output1_size = 0;
3281 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003282 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003283 size_t output2_size = 0;
3284 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003285 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003286 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3287 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003288 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003289
Gilles Peskine8817f612018-12-18 00:18:46 +01003290 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003291
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003292 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3293 psa_set_key_algorithm( &attributes, alg );
3294 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003295
Gilles Peskine73676cb2019-05-15 20:15:10 +02003296 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003297
Gilles Peskine8817f612018-12-18 00:18:46 +01003298 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3299 handle, alg ) );
3300 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3301 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003302
Gilles Peskine8817f612018-12-18 00:18:46 +01003303 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3304 iv, iv_size,
3305 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003306 output1_size = ( (size_t) input->len +
3307 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003308 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003309
Gilles Peskine8817f612018-12-18 00:18:46 +01003310 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3311 output1, output1_size,
3312 &output1_length ) );
3313 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003314 output1 + output1_length,
3315 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003316 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003317
Gilles Peskine048b7f02018-06-08 14:20:49 +02003318 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003319
Gilles Peskine8817f612018-12-18 00:18:46 +01003320 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003321
3322 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003323 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003324
Gilles Peskine8817f612018-12-18 00:18:46 +01003325 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3326 iv, iv_length ) );
3327 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3328 output2, output2_size,
3329 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003330 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003331 PSA_ASSERT( psa_cipher_finish( &operation2,
3332 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003333 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003334 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003335
Gilles Peskine048b7f02018-06-08 14:20:49 +02003336 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003337
Gilles Peskine8817f612018-12-18 00:18:46 +01003338 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003339
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003340 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003341
3342exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003343 mbedtls_free( output1 );
3344 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003345 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003346 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003347}
3348/* END_CASE */
3349
3350/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003351void cipher_verify_output_multipart( int alg_arg,
3352 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003353 data_t *key,
3354 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003355 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003356{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003357 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003358 psa_key_type_t key_type = key_type_arg;
3359 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003360 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003361 unsigned char iv[16] = {0};
3362 size_t iv_size = 16;
3363 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003364 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003365 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003366 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003367 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003368 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003369 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003370 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003371 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3372 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003373 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003374
Gilles Peskine8817f612018-12-18 00:18:46 +01003375 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003376
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003377 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3378 psa_set_key_algorithm( &attributes, alg );
3379 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003380
Gilles Peskine73676cb2019-05-15 20:15:10 +02003381 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003382
Gilles Peskine8817f612018-12-18 00:18:46 +01003383 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3384 handle, alg ) );
3385 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3386 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003387
Gilles Peskine8817f612018-12-18 00:18:46 +01003388 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3389 iv, iv_size,
3390 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003391 output1_buffer_size = ( (size_t) input->len +
3392 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003393 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003394
Gilles Peskinee0866522019-02-19 19:44:00 +01003395 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003396
Gilles Peskine8817f612018-12-18 00:18:46 +01003397 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3398 output1, output1_buffer_size,
3399 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003400 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003401
Gilles Peskine8817f612018-12-18 00:18:46 +01003402 PSA_ASSERT( psa_cipher_update( &operation1,
3403 input->x + first_part_size,
3404 input->len - first_part_size,
3405 output1, output1_buffer_size,
3406 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003407 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003408
Gilles Peskine8817f612018-12-18 00:18:46 +01003409 PSA_ASSERT( psa_cipher_finish( &operation1,
3410 output1 + output1_length,
3411 output1_buffer_size - output1_length,
3412 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003413 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003414
Gilles Peskine8817f612018-12-18 00:18:46 +01003415 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003416
Gilles Peskine048b7f02018-06-08 14:20:49 +02003417 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003418 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003419
Gilles Peskine8817f612018-12-18 00:18:46 +01003420 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3421 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003422
Gilles Peskine8817f612018-12-18 00:18:46 +01003423 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3424 output2, output2_buffer_size,
3425 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003426 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003427
Gilles Peskine8817f612018-12-18 00:18:46 +01003428 PSA_ASSERT( psa_cipher_update( &operation2,
3429 output1 + first_part_size,
3430 output1_length - first_part_size,
3431 output2, output2_buffer_size,
3432 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003433 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003434
Gilles Peskine8817f612018-12-18 00:18:46 +01003435 PSA_ASSERT( psa_cipher_finish( &operation2,
3436 output2 + output2_length,
3437 output2_buffer_size - output2_length,
3438 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003439 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003440
Gilles Peskine8817f612018-12-18 00:18:46 +01003441 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003442
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003443 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003444
3445exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003446 mbedtls_free( output1 );
3447 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003448 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003449 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003450}
3451/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003452
Gilles Peskine20035e32018-02-03 22:44:14 +01003453/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003454void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003455 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003456 data_t *nonce,
3457 data_t *additional_data,
3458 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003459 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003460{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003461 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003462 psa_key_type_t key_type = key_type_arg;
3463 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003464 unsigned char *output_data = NULL;
3465 size_t output_size = 0;
3466 size_t output_length = 0;
3467 unsigned char *output_data2 = NULL;
3468 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003469 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003470 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003471 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003472
Gilles Peskine4abf7412018-06-18 16:35:34 +02003473 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003474 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3475 * should be exact. */
3476 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3477 TEST_EQUAL( output_size,
3478 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003479 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003480
Gilles Peskine8817f612018-12-18 00:18:46 +01003481 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003482
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003483 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3484 psa_set_key_algorithm( &attributes, alg );
3485 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003486
Gilles Peskine049c7532019-05-15 20:22:09 +02003487 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3488 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003489
Gilles Peskinefe11b722018-12-18 00:24:04 +01003490 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3491 nonce->x, nonce->len,
3492 additional_data->x,
3493 additional_data->len,
3494 input_data->x, input_data->len,
3495 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003496 &output_length ),
3497 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003498
3499 if( PSA_SUCCESS == expected_result )
3500 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003501 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003502
Gilles Peskine003a4a92019-05-14 16:09:40 +02003503 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3504 * should be exact. */
3505 TEST_EQUAL( input_data->len,
3506 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3507
Gilles Peskinefe11b722018-12-18 00:24:04 +01003508 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3509 nonce->x, nonce->len,
3510 additional_data->x,
3511 additional_data->len,
3512 output_data, output_length,
3513 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003514 &output_length2 ),
3515 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003516
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003517 ASSERT_COMPARE( input_data->x, input_data->len,
3518 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003519 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003520
Gilles Peskinea1cac842018-06-11 19:33:02 +02003521exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003522 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003523 mbedtls_free( output_data );
3524 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003525 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003526}
3527/* END_CASE */
3528
3529/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003530void aead_encrypt( int key_type_arg, data_t *key_data,
3531 int alg_arg,
3532 data_t *nonce,
3533 data_t *additional_data,
3534 data_t *input_data,
3535 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003536{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003537 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003538 psa_key_type_t key_type = key_type_arg;
3539 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003540 unsigned char *output_data = NULL;
3541 size_t output_size = 0;
3542 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003543 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003544 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003545
Gilles Peskine4abf7412018-06-18 16:35:34 +02003546 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003547 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3548 * should be exact. */
3549 TEST_EQUAL( output_size,
3550 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003551 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003552
Gilles Peskine8817f612018-12-18 00:18:46 +01003553 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003554
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003555 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3556 psa_set_key_algorithm( &attributes, alg );
3557 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003558
Gilles Peskine049c7532019-05-15 20:22:09 +02003559 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3560 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003561
Gilles Peskine8817f612018-12-18 00:18:46 +01003562 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3563 nonce->x, nonce->len,
3564 additional_data->x, additional_data->len,
3565 input_data->x, input_data->len,
3566 output_data, output_size,
3567 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003568
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003569 ASSERT_COMPARE( expected_result->x, expected_result->len,
3570 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003571
Gilles Peskinea1cac842018-06-11 19:33:02 +02003572exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003573 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003574 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003575 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003576}
3577/* END_CASE */
3578
3579/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003580void aead_decrypt( int key_type_arg, data_t *key_data,
3581 int alg_arg,
3582 data_t *nonce,
3583 data_t *additional_data,
3584 data_t *input_data,
3585 data_t *expected_data,
3586 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003587{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003588 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003589 psa_key_type_t key_type = key_type_arg;
3590 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003591 unsigned char *output_data = NULL;
3592 size_t output_size = 0;
3593 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003594 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003595 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003596 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003597
Gilles Peskine003a4a92019-05-14 16:09:40 +02003598 output_size = input_data->len - tag_length;
3599 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3600 * should be exact. */
3601 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3602 TEST_EQUAL( output_size,
3603 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003604 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003605
Gilles Peskine8817f612018-12-18 00:18:46 +01003606 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003607
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003608 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3609 psa_set_key_algorithm( &attributes, alg );
3610 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003611
Gilles Peskine049c7532019-05-15 20:22:09 +02003612 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3613 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003614
Gilles Peskinefe11b722018-12-18 00:24:04 +01003615 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3616 nonce->x, nonce->len,
3617 additional_data->x,
3618 additional_data->len,
3619 input_data->x, input_data->len,
3620 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003621 &output_length ),
3622 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003623
Gilles Peskine2d277862018-06-18 15:41:12 +02003624 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003625 ASSERT_COMPARE( expected_data->x, expected_data->len,
3626 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003627
Gilles Peskinea1cac842018-06-11 19:33:02 +02003628exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003629 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003630 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003631 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003632}
3633/* END_CASE */
3634
3635/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003636void signature_size( int type_arg,
3637 int bits,
3638 int alg_arg,
3639 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003640{
3641 psa_key_type_t type = type_arg;
3642 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003643 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003644 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003645exit:
3646 ;
3647}
3648/* END_CASE */
3649
3650/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003651void sign_deterministic( int key_type_arg, data_t *key_data,
3652 int alg_arg, data_t *input_data,
3653 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003654{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003655 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003656 psa_key_type_t key_type = key_type_arg;
3657 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003658 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003659 unsigned char *signature = NULL;
3660 size_t signature_size;
3661 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003662 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003663
Gilles Peskine8817f612018-12-18 00:18:46 +01003664 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003665
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003666 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3667 psa_set_key_algorithm( &attributes, alg );
3668 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003669
Gilles Peskine049c7532019-05-15 20:22:09 +02003670 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3671 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003672 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3673 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003674
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003675 /* Allocate a buffer which has the size advertized by the
3676 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003677 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3678 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003679 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003680 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003681 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003682
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003683 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003684 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3685 input_data->x, input_data->len,
3686 signature, signature_size,
3687 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003688 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003689 ASSERT_COMPARE( output_data->x, output_data->len,
3690 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003691
3692exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003693 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003694 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003695 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003696 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003697}
3698/* END_CASE */
3699
3700/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003701void sign_fail( int key_type_arg, data_t *key_data,
3702 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003703 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003704{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003705 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003706 psa_key_type_t key_type = key_type_arg;
3707 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003708 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003709 psa_status_t actual_status;
3710 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003711 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003712 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003713 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003714
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003715 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003716
Gilles Peskine8817f612018-12-18 00:18:46 +01003717 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003718
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003719 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3720 psa_set_key_algorithm( &attributes, alg );
3721 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003722
Gilles Peskine049c7532019-05-15 20:22:09 +02003723 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3724 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003725
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003726 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003727 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003728 signature, signature_size,
3729 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003730 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003731 /* The value of *signature_length is unspecified on error, but
3732 * whatever it is, it should be less than signature_size, so that
3733 * if the caller tries to read *signature_length bytes without
3734 * checking the error code then they don't overflow a buffer. */
3735 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003736
3737exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003738 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003739 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003740 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003741 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003742}
3743/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003744
3745/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003746void sign_verify( int key_type_arg, data_t *key_data,
3747 int alg_arg, data_t *input_data )
3748{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003749 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003750 psa_key_type_t key_type = key_type_arg;
3751 psa_algorithm_t alg = alg_arg;
3752 size_t key_bits;
3753 unsigned char *signature = NULL;
3754 size_t signature_size;
3755 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003756 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003757
Gilles Peskine8817f612018-12-18 00:18:46 +01003758 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003759
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003760 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3761 psa_set_key_algorithm( &attributes, alg );
3762 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003763
Gilles Peskine049c7532019-05-15 20:22:09 +02003764 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3765 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003766 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3767 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003768
3769 /* Allocate a buffer which has the size advertized by the
3770 * library. */
3771 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3772 key_bits, alg );
3773 TEST_ASSERT( signature_size != 0 );
3774 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003775 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003776
3777 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003778 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3779 input_data->x, input_data->len,
3780 signature, signature_size,
3781 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003782 /* Check that the signature length looks sensible. */
3783 TEST_ASSERT( signature_length <= signature_size );
3784 TEST_ASSERT( signature_length > 0 );
3785
3786 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003787 PSA_ASSERT( psa_asymmetric_verify(
3788 handle, alg,
3789 input_data->x, input_data->len,
3790 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003791
3792 if( input_data->len != 0 )
3793 {
3794 /* Flip a bit in the input and verify that the signature is now
3795 * detected as invalid. Flip a bit at the beginning, not at the end,
3796 * because ECDSA may ignore the last few bits of the input. */
3797 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003798 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3799 input_data->x, input_data->len,
3800 signature, signature_length ),
3801 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003802 }
3803
3804exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003805 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003806 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003807 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003808 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003809}
3810/* END_CASE */
3811
3812/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003813void asymmetric_verify( int key_type_arg, data_t *key_data,
3814 int alg_arg, data_t *hash_data,
3815 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003816{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003817 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003818 psa_key_type_t key_type = key_type_arg;
3819 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003820 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003821
Gilles Peskine69c12672018-06-28 00:07:19 +02003822 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3823
Gilles Peskine8817f612018-12-18 00:18:46 +01003824 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003825
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003826 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3827 psa_set_key_algorithm( &attributes, alg );
3828 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003829
Gilles Peskine049c7532019-05-15 20:22:09 +02003830 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3831 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003832
Gilles Peskine8817f612018-12-18 00:18:46 +01003833 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3834 hash_data->x, hash_data->len,
3835 signature_data->x,
3836 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003837exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003838 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003839 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003840 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003841}
3842/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003843
3844/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003845void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3846 int alg_arg, data_t *hash_data,
3847 data_t *signature_data,
3848 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003849{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003850 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003851 psa_key_type_t key_type = key_type_arg;
3852 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003853 psa_status_t actual_status;
3854 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003855 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003856
Gilles Peskine8817f612018-12-18 00:18:46 +01003857 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003858
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003859 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3860 psa_set_key_algorithm( &attributes, alg );
3861 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003862
Gilles Peskine049c7532019-05-15 20:22:09 +02003863 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3864 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003865
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003866 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003867 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003868 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003869 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003870
Gilles Peskinefe11b722018-12-18 00:24:04 +01003871 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003872
3873exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003874 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003875 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003876 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003877}
3878/* END_CASE */
3879
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003880/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003881void asymmetric_encrypt( int key_type_arg,
3882 data_t *key_data,
3883 int alg_arg,
3884 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003885 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003886 int expected_output_length_arg,
3887 int expected_status_arg )
3888{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003889 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003890 psa_key_type_t key_type = key_type_arg;
3891 psa_algorithm_t alg = alg_arg;
3892 size_t expected_output_length = expected_output_length_arg;
3893 size_t key_bits;
3894 unsigned char *output = NULL;
3895 size_t output_size;
3896 size_t output_length = ~0;
3897 psa_status_t actual_status;
3898 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003899 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003900
Gilles Peskine8817f612018-12-18 00:18:46 +01003901 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003902
Gilles Peskine656896e2018-06-29 19:12:28 +02003903 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003904 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3905 psa_set_key_algorithm( &attributes, alg );
3906 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003907 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3908 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003909
3910 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003911 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3912 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003913 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003914 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003915
3916 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003917 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003918 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003919 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003920 output, output_size,
3921 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003922 TEST_EQUAL( actual_status, expected_status );
3923 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003924
Gilles Peskine68428122018-06-30 18:42:41 +02003925 /* If the label is empty, the test framework puts a non-null pointer
3926 * in label->x. Test that a null pointer works as well. */
3927 if( label->len == 0 )
3928 {
3929 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003930 if( output_size != 0 )
3931 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003932 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003933 input_data->x, input_data->len,
3934 NULL, label->len,
3935 output, output_size,
3936 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003937 TEST_EQUAL( actual_status, expected_status );
3938 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003939 }
3940
Gilles Peskine656896e2018-06-29 19:12:28 +02003941exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003942 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003943 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003944 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003945 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02003946}
3947/* END_CASE */
3948
3949/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003950void asymmetric_encrypt_decrypt( int key_type_arg,
3951 data_t *key_data,
3952 int alg_arg,
3953 data_t *input_data,
3954 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003955{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003956 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003957 psa_key_type_t key_type = key_type_arg;
3958 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003959 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003960 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003961 size_t output_size;
3962 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003963 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003964 size_t output2_size;
3965 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003966 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003967
Gilles Peskine8817f612018-12-18 00:18:46 +01003968 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003969
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003970 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3971 psa_set_key_algorithm( &attributes, alg );
3972 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003973
Gilles Peskine049c7532019-05-15 20:22:09 +02003974 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3975 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003976
3977 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003978 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3979 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003980 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003981 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003982 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003983 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003984
Gilles Peskineeebd7382018-06-08 18:11:54 +02003985 /* We test encryption by checking that encrypt-then-decrypt gives back
3986 * the original plaintext because of the non-optional random
3987 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003988 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3989 input_data->x, input_data->len,
3990 label->x, label->len,
3991 output, output_size,
3992 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003993 /* We don't know what ciphertext length to expect, but check that
3994 * it looks sensible. */
3995 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003996
Gilles Peskine8817f612018-12-18 00:18:46 +01003997 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3998 output, output_length,
3999 label->x, label->len,
4000 output2, output2_size,
4001 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004002 ASSERT_COMPARE( input_data->x, input_data->len,
4003 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004004
4005exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004006 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004007 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004008 mbedtls_free( output );
4009 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004010 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004011}
4012/* END_CASE */
4013
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004014/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004015void asymmetric_decrypt( int key_type_arg,
4016 data_t *key_data,
4017 int alg_arg,
4018 data_t *input_data,
4019 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02004020 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004021{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004022 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004023 psa_key_type_t key_type = key_type_arg;
4024 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004025 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03004026 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004027 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004028 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004029
Jaeden Amero412654a2019-02-06 12:57:46 +00004030 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004031 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004032
Gilles Peskine8817f612018-12-18 00:18:46 +01004033 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004034
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004035 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4036 psa_set_key_algorithm( &attributes, alg );
4037 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004038
Gilles Peskine049c7532019-05-15 20:22:09 +02004039 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4040 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004041
Gilles Peskine8817f612018-12-18 00:18:46 +01004042 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4043 input_data->x, input_data->len,
4044 label->x, label->len,
4045 output,
4046 output_size,
4047 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004048 ASSERT_COMPARE( expected_data->x, expected_data->len,
4049 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004050
Gilles Peskine68428122018-06-30 18:42:41 +02004051 /* If the label is empty, the test framework puts a non-null pointer
4052 * in label->x. Test that a null pointer works as well. */
4053 if( label->len == 0 )
4054 {
4055 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004056 if( output_size != 0 )
4057 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004058 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4059 input_data->x, input_data->len,
4060 NULL, label->len,
4061 output,
4062 output_size,
4063 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004064 ASSERT_COMPARE( expected_data->x, expected_data->len,
4065 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004066 }
4067
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004068exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004069 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004070 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004071 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004072 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004073}
4074/* END_CASE */
4075
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004076/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004077void asymmetric_decrypt_fail( int key_type_arg,
4078 data_t *key_data,
4079 int alg_arg,
4080 data_t *input_data,
4081 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00004082 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02004083 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004084{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004085 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004086 psa_key_type_t key_type = key_type_arg;
4087 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004088 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004089 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004090 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004091 psa_status_t actual_status;
4092 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004093 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004094
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004095 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004096
Gilles Peskine8817f612018-12-18 00:18:46 +01004097 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004098
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004099 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4100 psa_set_key_algorithm( &attributes, alg );
4101 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004102
Gilles Peskine049c7532019-05-15 20:22:09 +02004103 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4104 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004105
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004106 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004107 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004108 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004109 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004110 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004111 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004112 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004113
Gilles Peskine68428122018-06-30 18:42:41 +02004114 /* If the label is empty, the test framework puts a non-null pointer
4115 * in label->x. Test that a null pointer works as well. */
4116 if( label->len == 0 )
4117 {
4118 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004119 if( output_size != 0 )
4120 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004121 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004122 input_data->x, input_data->len,
4123 NULL, label->len,
4124 output, output_size,
4125 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004126 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004127 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004128 }
4129
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004130exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004131 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004132 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004133 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004134 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004135}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004136/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004137
4138/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004139void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004140{
4141 /* Test each valid way of initializing the object, except for `= {0}`, as
4142 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4143 * though it's OK by the C standard. We could test for this, but we'd need
4144 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004145 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004146 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4147 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4148 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004149
4150 memset( &zero, 0, sizeof( zero ) );
4151
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004152 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004153 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004154 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004155 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004156 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004157 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004158 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004159
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004160 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004161 PSA_ASSERT( psa_key_derivation_abort(&func) );
4162 PSA_ASSERT( psa_key_derivation_abort(&init) );
4163 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004164}
4165/* END_CASE */
4166
Janos Follath16de4a42019-06-13 16:32:24 +01004167/* BEGIN_CASE */
4168void derive_setup( int alg_arg, int expected_status_arg )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004169{
Gilles Peskineea0fb492018-07-12 17:17:20 +02004170 psa_algorithm_t alg = alg_arg;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004171 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004172 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004173
Gilles Peskine8817f612018-12-18 00:18:46 +01004174 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004175
Janos Follath16de4a42019-06-13 16:32:24 +01004176 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004177 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004178
4179exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004180 psa_key_derivation_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004181 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004182}
4183/* END_CASE */
4184
Janos Follathaf3c2a02019-06-12 12:34:34 +01004185/* BEGIN_CASE */
Janos Follatha27c9272019-06-14 09:59:36 +01004186void derive_set_capacity( int alg_arg, int capacity_arg,
4187 int expected_status_arg )
4188{
4189 psa_algorithm_t alg = alg_arg;
4190 size_t capacity = capacity_arg;
4191 psa_status_t expected_status = expected_status_arg;
4192 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4193
4194 PSA_ASSERT( psa_crypto_init( ) );
4195
4196 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4197
4198 TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
4199 expected_status );
4200
4201exit:
4202 psa_key_derivation_abort( &operation );
4203 PSA_DONE( );
4204}
4205/* END_CASE */
4206
4207/* BEGIN_CASE */
Janos Follathaf3c2a02019-06-12 12:34:34 +01004208void derive_input( int alg_arg,
4209 int key_type_arg,
4210 int step1_arg, data_t *input1,
4211 int step2_arg, data_t *input2,
4212 int step3_arg, data_t *input3,
4213 int expected_status_arg1,
4214 int expected_status_arg2,
4215 int expected_status_arg3 )
4216{
4217 psa_algorithm_t alg = alg_arg;
4218 size_t key_type = key_type_arg;
4219 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4220 psa_status_t expected_statuses[] = {expected_status_arg1,
4221 expected_status_arg2,
4222 expected_status_arg3};
4223 data_t *inputs[] = {input1, input2, input3};
4224 psa_key_handle_t handles[] = {0, 0, 0};
4225 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4226 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4227 size_t i;
4228
4229 PSA_ASSERT( psa_crypto_init( ) );
4230
4231 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4232 psa_set_key_algorithm( &attributes, alg );
4233 psa_set_key_type( &attributes, key_type );
4234
4235 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4236
4237 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
4238 {
4239 switch( steps[i] )
4240 {
4241 case PSA_KEY_DERIVATION_INPUT_SECRET:
4242 PSA_ASSERT( psa_import_key( &attributes,
4243 inputs[i]->x, inputs[i]->len,
4244 &handles[i] ) );
4245 TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
4246 handles[i] ),
4247 expected_statuses[i] );
4248 break;
4249 default:
4250 TEST_EQUAL( psa_key_derivation_input_bytes(
4251 &operation, steps[i],
4252 inputs[i]->x, inputs[i]->len ),
4253 expected_statuses[i] );
4254 break;
4255 }
4256 }
4257
4258exit:
4259 psa_key_derivation_abort( &operation );
4260 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4261 psa_destroy_key( handles[i] );
4262 PSA_DONE( );
4263}
4264/* END_CASE */
4265
Janos Follathd958bb72019-07-03 15:02:16 +01004266/* BEGIN_CASE */
4267void test_derive_invalid_key_derivation_state( int alg_arg )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004268{
Janos Follathd958bb72019-07-03 15:02:16 +01004269 psa_algorithm_t alg = alg_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004270 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004271 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004272 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathd958bb72019-07-03 15:02:16 +01004273 unsigned char input1[] = "Input 1";
4274 size_t input1_length = sizeof( input1 );
4275 unsigned char input2[] = "Input 2";
4276 size_t input2_length = sizeof( input2 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004277 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004278 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004279 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4280 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4281 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004282 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004283
Gilles Peskine8817f612018-12-18 00:18:46 +01004284 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004285
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004286 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4287 psa_set_key_algorithm( &attributes, alg );
4288 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004289
Gilles Peskine73676cb2019-05-15 20:15:10 +02004290 PSA_ASSERT( psa_import_key( &attributes,
4291 key_data, sizeof( key_data ),
4292 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004293
4294 /* valid key derivation */
Janos Follathd958bb72019-07-03 15:02:16 +01004295 if( !setup_key_derivation_wrap( &operation, handle, alg,
4296 input1, input1_length,
4297 input2, input2_length,
4298 capacity ) )
4299 goto exit;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004300
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004301 /* state of operation shouldn't allow additional generation */
Janos Follathd958bb72019-07-03 15:02:16 +01004302 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004303 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004304
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004305 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004306
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004307 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004308 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004309
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004310exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004311 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004312 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004313 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004314}
4315/* END_CASE */
4316
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004317/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004318void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004319{
4320 uint8_t output_buffer[16];
4321 size_t buffer_size = 16;
4322 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004323 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004324
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004325 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4326 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004327 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004328
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004329 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004330 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004331
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004332 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004333
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004334 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4335 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004336 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004337
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004338 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004339 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004340
4341exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004342 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004343}
4344/* END_CASE */
4345
4346/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004347void derive_output( int alg_arg,
Gilles Peskine1468da72019-05-29 17:35:49 +02004348 int step1_arg, data_t *input1,
4349 int step2_arg, data_t *input2,
4350 int step3_arg, data_t *input3,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004351 int requested_capacity_arg,
4352 data_t *expected_output1,
4353 data_t *expected_output2 )
4354{
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004355 psa_algorithm_t alg = alg_arg;
Gilles Peskine1468da72019-05-29 17:35:49 +02004356 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4357 data_t *inputs[] = {input1, input2, input3};
4358 psa_key_handle_t handles[] = {0, 0, 0};
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004359 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004360 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004361 uint8_t *expected_outputs[2] =
4362 {expected_output1->x, expected_output2->x};
4363 size_t output_sizes[2] =
4364 {expected_output1->len, expected_output2->len};
4365 size_t output_buffer_size = 0;
4366 uint8_t *output_buffer = NULL;
4367 size_t expected_capacity;
4368 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004369 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004370 psa_status_t status;
Gilles Peskine1468da72019-05-29 17:35:49 +02004371 size_t i;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004372
4373 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4374 {
4375 if( output_sizes[i] > output_buffer_size )
4376 output_buffer_size = output_sizes[i];
4377 if( output_sizes[i] == 0 )
4378 expected_outputs[i] = NULL;
4379 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004380 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004381 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004382
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004383 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4384 psa_set_key_algorithm( &attributes, alg );
4385 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004386
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004387 /* Extraction phase. */
Gilles Peskine1468da72019-05-29 17:35:49 +02004388 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4389 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4390 requested_capacity ) );
4391 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004392 {
Gilles Peskine1468da72019-05-29 17:35:49 +02004393 switch( steps[i] )
4394 {
4395 case 0:
4396 break;
4397 case PSA_KEY_DERIVATION_INPUT_SECRET:
4398 PSA_ASSERT( psa_import_key( &attributes,
4399 inputs[i]->x, inputs[i]->len,
4400 &handles[i] ) );
4401 PSA_ASSERT( psa_key_derivation_input_key(
4402 &operation, steps[i],
4403 handles[i] ) );
4404 break;
4405 default:
4406 PSA_ASSERT( psa_key_derivation_input_bytes(
4407 &operation, steps[i],
4408 inputs[i]->x, inputs[i]->len ) );
4409 break;
4410 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004411 }
Gilles Peskine1468da72019-05-29 17:35:49 +02004412
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004413 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004414 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004415 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004416 expected_capacity = requested_capacity;
4417
4418 /* Expansion phase. */
4419 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4420 {
4421 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004422 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004423 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004424 if( expected_capacity == 0 && output_sizes[i] == 0 )
4425 {
4426 /* Reading 0 bytes when 0 bytes are available can go either way. */
4427 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004428 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004429 continue;
4430 }
4431 else if( expected_capacity == 0 ||
4432 output_sizes[i] > expected_capacity )
4433 {
4434 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004435 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004436 expected_capacity = 0;
4437 continue;
4438 }
4439 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004440 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004441 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004442 ASSERT_COMPARE( output_buffer, output_sizes[i],
4443 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004444 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004445 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004446 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004447 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004448 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004449 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004450 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004451
4452exit:
4453 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004454 psa_key_derivation_abort( &operation );
Gilles Peskine1468da72019-05-29 17:35:49 +02004455 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4456 psa_destroy_key( handles[i] );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004457 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004458}
4459/* END_CASE */
4460
4461/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004462void derive_full( int alg_arg,
4463 data_t *key_data,
Janos Follath47f27ed2019-06-25 13:24:52 +01004464 data_t *input1,
4465 data_t *input2,
Gilles Peskined54931c2018-07-17 21:06:59 +02004466 int requested_capacity_arg )
4467{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004468 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004469 psa_algorithm_t alg = alg_arg;
4470 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004471 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004472 unsigned char output_buffer[16];
4473 size_t expected_capacity = requested_capacity;
4474 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004475 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004476
Gilles Peskine8817f612018-12-18 00:18:46 +01004477 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004478
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004479 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4480 psa_set_key_algorithm( &attributes, alg );
4481 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004482
Gilles Peskine049c7532019-05-15 20:22:09 +02004483 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4484 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004485
Janos Follathf2815ea2019-07-03 12:41:36 +01004486 if( !setup_key_derivation_wrap( &operation, handle, alg,
4487 input1->x, input1->len,
4488 input2->x, input2->len,
4489 requested_capacity ) )
4490 goto exit;
Janos Follath47f27ed2019-06-25 13:24:52 +01004491
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004492 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004493 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004494 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004495
4496 /* Expansion phase. */
4497 while( current_capacity > 0 )
4498 {
4499 size_t read_size = sizeof( output_buffer );
4500 if( read_size > current_capacity )
4501 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004502 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004503 output_buffer,
4504 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004505 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004506 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004507 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004508 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004509 }
4510
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004511 /* Check that the operation refuses to go over capacity. */
4512 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004513 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004514
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004515 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004516
4517exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004518 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004519 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004520 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004521}
4522/* END_CASE */
4523
Janos Follathe60c9052019-07-03 13:51:30 +01004524/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004525void derive_key_exercise( int alg_arg,
4526 data_t *key_data,
Janos Follathe60c9052019-07-03 13:51:30 +01004527 data_t *input1,
4528 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004529 int derived_type_arg,
4530 int derived_bits_arg,
4531 int derived_usage_arg,
4532 int derived_alg_arg )
4533{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004534 psa_key_handle_t base_handle = 0;
4535 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004536 psa_algorithm_t alg = alg_arg;
4537 psa_key_type_t derived_type = derived_type_arg;
4538 size_t derived_bits = derived_bits_arg;
4539 psa_key_usage_t derived_usage = derived_usage_arg;
4540 psa_algorithm_t derived_alg = derived_alg_arg;
4541 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004542 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004543 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004544 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004545
Gilles Peskine8817f612018-12-18 00:18:46 +01004546 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004547
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004548 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4549 psa_set_key_algorithm( &attributes, alg );
4550 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004551 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4552 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004553
4554 /* Derive a key. */
Janos Follathe60c9052019-07-03 13:51:30 +01004555 if ( setup_key_derivation_wrap( &operation, base_handle, alg,
4556 input1->x, input1->len,
4557 input2->x, input2->len, capacity ) )
4558 goto exit;
4559
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004560 psa_set_key_usage_flags( &attributes, derived_usage );
4561 psa_set_key_algorithm( &attributes, derived_alg );
4562 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004563 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004564 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004565 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004566
4567 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004568 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4569 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4570 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004571
4572 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004573 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004574 goto exit;
4575
4576exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004577 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004578 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004579 psa_destroy_key( base_handle );
4580 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004581 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004582}
4583/* END_CASE */
4584
Janos Follath42fd8882019-07-03 14:17:09 +01004585/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004586void derive_key_export( int alg_arg,
4587 data_t *key_data,
Janos Follath42fd8882019-07-03 14:17:09 +01004588 data_t *input1,
4589 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004590 int bytes1_arg,
4591 int bytes2_arg )
4592{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004593 psa_key_handle_t base_handle = 0;
4594 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004595 psa_algorithm_t alg = alg_arg;
4596 size_t bytes1 = bytes1_arg;
4597 size_t bytes2 = bytes2_arg;
4598 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004599 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004600 uint8_t *output_buffer = NULL;
4601 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004602 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4603 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004604 size_t length;
4605
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004606 ASSERT_ALLOC( output_buffer, capacity );
4607 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004608 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004609
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004610 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4611 psa_set_key_algorithm( &base_attributes, alg );
4612 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004613 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4614 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004615
4616 /* Derive some material and output it. */
Janos Follath42fd8882019-07-03 14:17:09 +01004617 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4618 input1->x, input1->len,
4619 input2->x, input2->len, capacity ) )
4620 goto exit;
4621
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004622 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004623 output_buffer,
4624 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004625 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004626
4627 /* Derive the same output again, but this time store it in key objects. */
Janos Follath42fd8882019-07-03 14:17:09 +01004628 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4629 input1->x, input1->len,
4630 input2->x, input2->len, capacity ) )
4631 goto exit;
4632
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004633 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4634 psa_set_key_algorithm( &derived_attributes, 0 );
4635 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004636 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004637 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004638 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004639 PSA_ASSERT( psa_export_key( derived_handle,
4640 export_buffer, bytes1,
4641 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004642 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004643 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004644 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004645 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004646 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004647 PSA_ASSERT( psa_export_key( derived_handle,
4648 export_buffer + bytes1, bytes2,
4649 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004650 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004651
4652 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004653 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4654 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004655
4656exit:
4657 mbedtls_free( output_buffer );
4658 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004659 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004660 psa_destroy_key( base_handle );
4661 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004662 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004663}
4664/* END_CASE */
4665
4666/* BEGIN_CASE */
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004667void derive_key( int alg_arg,
4668 data_t *key_data, data_t *input1, data_t *input2,
4669 int type_arg, int bits_arg,
4670 int expected_status_arg )
Gilles Peskinec744d992019-07-30 17:26:54 +02004671{
4672 psa_key_handle_t base_handle = 0;
4673 psa_key_handle_t derived_handle = 0;
4674 psa_algorithm_t alg = alg_arg;
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004675 psa_key_type_t type = type_arg;
Gilles Peskinec744d992019-07-30 17:26:54 +02004676 size_t bits = bits_arg;
4677 psa_status_t expected_status = expected_status_arg;
4678 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4679 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4680 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
4681
4682 PSA_ASSERT( psa_crypto_init( ) );
4683
4684 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4685 psa_set_key_algorithm( &base_attributes, alg );
4686 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4687 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4688 &base_handle ) );
4689
4690 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4691 input1->x, input1->len,
4692 input2->x, input2->len, SIZE_MAX ) )
4693 goto exit;
4694
4695 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4696 psa_set_key_algorithm( &derived_attributes, 0 );
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004697 psa_set_key_type( &derived_attributes, type );
Gilles Peskinec744d992019-07-30 17:26:54 +02004698 psa_set_key_bits( &derived_attributes, bits );
4699 TEST_EQUAL( psa_key_derivation_output_key( &derived_attributes, &operation,
4700 &derived_handle ),
4701 expected_status );
4702
4703exit:
4704 psa_key_derivation_abort( &operation );
4705 psa_destroy_key( base_handle );
4706 psa_destroy_key( derived_handle );
4707 PSA_DONE( );
4708}
4709/* END_CASE */
4710
4711/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004712void key_agreement_setup( int alg_arg,
4713 int our_key_type_arg, data_t *our_key_data,
4714 data_t *peer_key_data,
4715 int expected_status_arg )
4716{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004717 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004718 psa_algorithm_t alg = alg_arg;
4719 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004720 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004721 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004722 psa_status_t expected_status = expected_status_arg;
4723 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004724
Gilles Peskine8817f612018-12-18 00:18:46 +01004725 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004726
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004727 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4728 psa_set_key_algorithm( &attributes, alg );
4729 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004730 PSA_ASSERT( psa_import_key( &attributes,
4731 our_key_data->x, our_key_data->len,
4732 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004733
Gilles Peskine77f40d82019-04-11 21:27:06 +02004734 /* The tests currently include inputs that should fail at either step.
4735 * Test cases that fail at the setup step should be changed to call
4736 * key_derivation_setup instead, and this function should be renamed
4737 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004738 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004739 if( status == PSA_SUCCESS )
4740 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004741 TEST_EQUAL( psa_key_derivation_key_agreement(
4742 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4743 our_key,
4744 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004745 expected_status );
4746 }
4747 else
4748 {
4749 TEST_ASSERT( status == expected_status );
4750 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004751
4752exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004753 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004754 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004755 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004756}
4757/* END_CASE */
4758
4759/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004760void raw_key_agreement( int alg_arg,
4761 int our_key_type_arg, data_t *our_key_data,
4762 data_t *peer_key_data,
4763 data_t *expected_output )
4764{
4765 psa_key_handle_t our_key = 0;
4766 psa_algorithm_t alg = alg_arg;
4767 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004768 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004769 unsigned char *output = NULL;
4770 size_t output_length = ~0;
4771
4772 ASSERT_ALLOC( output, expected_output->len );
4773 PSA_ASSERT( psa_crypto_init( ) );
4774
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004775 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4776 psa_set_key_algorithm( &attributes, alg );
4777 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004778 PSA_ASSERT( psa_import_key( &attributes,
4779 our_key_data->x, our_key_data->len,
4780 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004781
Gilles Peskinebe697d82019-05-16 18:00:41 +02004782 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4783 peer_key_data->x, peer_key_data->len,
4784 output, expected_output->len,
4785 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004786 ASSERT_COMPARE( output, output_length,
4787 expected_output->x, expected_output->len );
4788
4789exit:
4790 mbedtls_free( output );
4791 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004792 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004793}
4794/* END_CASE */
4795
4796/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004797void key_agreement_capacity( int alg_arg,
4798 int our_key_type_arg, data_t *our_key_data,
4799 data_t *peer_key_data,
4800 int expected_capacity_arg )
4801{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004802 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004803 psa_algorithm_t alg = alg_arg;
4804 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004805 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004806 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004807 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004808 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004809
Gilles Peskine8817f612018-12-18 00:18:46 +01004810 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004811
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004812 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4813 psa_set_key_algorithm( &attributes, alg );
4814 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004815 PSA_ASSERT( psa_import_key( &attributes,
4816 our_key_data->x, our_key_data->len,
4817 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004818
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004819 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004820 PSA_ASSERT( psa_key_derivation_key_agreement(
4821 &operation,
4822 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4823 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004824 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4825 {
4826 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004827 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004828 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004829 NULL, 0 ) );
4830 }
Gilles Peskine59685592018-09-18 12:11:34 +02004831
Gilles Peskinebf491972018-10-25 22:36:12 +02004832 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004833 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004834 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004835 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004836
Gilles Peskinebf491972018-10-25 22:36:12 +02004837 /* Test the actual capacity by reading the output. */
4838 while( actual_capacity > sizeof( output ) )
4839 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004840 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004841 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004842 actual_capacity -= sizeof( output );
4843 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004844 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004845 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004846 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004847 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004848
Gilles Peskine59685592018-09-18 12:11:34 +02004849exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004850 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004851 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004852 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004853}
4854/* END_CASE */
4855
4856/* BEGIN_CASE */
4857void key_agreement_output( int alg_arg,
4858 int our_key_type_arg, data_t *our_key_data,
4859 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004860 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004861{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004862 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004863 psa_algorithm_t alg = alg_arg;
4864 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004865 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004866 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004867 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004868
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004869 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4870 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004871
Gilles Peskine8817f612018-12-18 00:18:46 +01004872 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004873
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004874 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4875 psa_set_key_algorithm( &attributes, alg );
4876 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004877 PSA_ASSERT( psa_import_key( &attributes,
4878 our_key_data->x, our_key_data->len,
4879 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004880
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004881 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004882 PSA_ASSERT( psa_key_derivation_key_agreement(
4883 &operation,
4884 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4885 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004886 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4887 {
4888 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004889 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004890 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004891 NULL, 0 ) );
4892 }
Gilles Peskine59685592018-09-18 12:11:34 +02004893
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004894 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004895 actual_output,
4896 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004897 ASSERT_COMPARE( actual_output, expected_output1->len,
4898 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004899 if( expected_output2->len != 0 )
4900 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004901 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004902 actual_output,
4903 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004904 ASSERT_COMPARE( actual_output, expected_output2->len,
4905 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004906 }
Gilles Peskine59685592018-09-18 12:11:34 +02004907
4908exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004909 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004910 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004911 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004912 mbedtls_free( actual_output );
4913}
4914/* END_CASE */
4915
4916/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004917void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004918{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004919 size_t bytes = bytes_arg;
4920 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004921 unsigned char *output = NULL;
4922 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004923 size_t i;
4924 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004925
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004926 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4927 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004928 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004929
Gilles Peskine8817f612018-12-18 00:18:46 +01004930 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004931
Gilles Peskinea50d7392018-06-21 10:22:13 +02004932 /* Run several times, to ensure that every output byte will be
4933 * nonzero at least once with overwhelming probability
4934 * (2^(-8*number_of_runs)). */
4935 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004936 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004937 if( bytes != 0 )
4938 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004939 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004940
4941 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004942 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4943 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004944
4945 for( i = 0; i < bytes; i++ )
4946 {
4947 if( output[i] != 0 )
4948 ++changed[i];
4949 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004950 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004951
4952 /* Check that every byte was changed to nonzero at least once. This
4953 * validates that psa_generate_random is overwriting every byte of
4954 * the output buffer. */
4955 for( i = 0; i < bytes; i++ )
4956 {
4957 TEST_ASSERT( changed[i] != 0 );
4958 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004959
4960exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004961 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004962 mbedtls_free( output );
4963 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004964}
4965/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004966
4967/* BEGIN_CASE */
4968void generate_key( int type_arg,
4969 int bits_arg,
4970 int usage_arg,
4971 int alg_arg,
4972 int expected_status_arg )
4973{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004974 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004975 psa_key_type_t type = type_arg;
4976 psa_key_usage_t usage = usage_arg;
4977 size_t bits = bits_arg;
4978 psa_algorithm_t alg = alg_arg;
4979 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004980 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004981 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004982
Gilles Peskine8817f612018-12-18 00:18:46 +01004983 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004984
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004985 psa_set_key_usage_flags( &attributes, usage );
4986 psa_set_key_algorithm( &attributes, alg );
4987 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004988 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004989
4990 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004991 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004992 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004993 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004994
4995 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004996 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4997 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4998 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004999
Gilles Peskine818ca122018-06-20 18:16:48 +02005000 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005001 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02005002 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005003
5004exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005005 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005006 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005007 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005008}
5009/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03005010
Gilles Peskinee56e8782019-04-26 17:34:02 +02005011/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
5012void generate_key_rsa( int bits_arg,
5013 data_t *e_arg,
5014 int expected_status_arg )
5015{
5016 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02005017 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02005018 size_t bits = bits_arg;
5019 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
5020 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
5021 psa_status_t expected_status = expected_status_arg;
5022 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5023 uint8_t *exported = NULL;
5024 size_t exported_size =
5025 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
5026 size_t exported_length = SIZE_MAX;
5027 uint8_t *e_read_buffer = NULL;
5028 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02005029 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005030 size_t e_read_length = SIZE_MAX;
5031
5032 if( e_arg->len == 0 ||
5033 ( e_arg->len == 3 &&
5034 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
5035 {
5036 is_default_public_exponent = 1;
5037 e_read_size = 0;
5038 }
5039 ASSERT_ALLOC( e_read_buffer, e_read_size );
5040 ASSERT_ALLOC( exported, exported_size );
5041
5042 PSA_ASSERT( psa_crypto_init( ) );
5043
5044 psa_set_key_usage_flags( &attributes, usage );
5045 psa_set_key_algorithm( &attributes, alg );
5046 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
5047 e_arg->x, e_arg->len ) );
5048 psa_set_key_bits( &attributes, bits );
5049
5050 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005051 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005052 if( expected_status != PSA_SUCCESS )
5053 goto exit;
5054
5055 /* Test the key information */
5056 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5057 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5058 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5059 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
5060 e_read_buffer, e_read_size,
5061 &e_read_length ) );
5062 if( is_default_public_exponent )
5063 TEST_EQUAL( e_read_length, 0 );
5064 else
5065 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
5066
5067 /* Do something with the key according to its type and permitted usage. */
5068 if( ! exercise_key( handle, usage, alg ) )
5069 goto exit;
5070
5071 /* Export the key and check the public exponent. */
5072 PSA_ASSERT( psa_export_public_key( handle,
5073 exported, exported_size,
5074 &exported_length ) );
5075 {
5076 uint8_t *p = exported;
5077 uint8_t *end = exported + exported_length;
5078 size_t len;
5079 /* RSAPublicKey ::= SEQUENCE {
5080 * modulus INTEGER, -- n
5081 * publicExponent INTEGER } -- e
5082 */
5083 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005084 MBEDTLS_ASN1_SEQUENCE |
5085 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005086 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
5087 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
5088 MBEDTLS_ASN1_INTEGER ) );
5089 if( len >= 1 && p[0] == 0 )
5090 {
5091 ++p;
5092 --len;
5093 }
5094 if( e_arg->len == 0 )
5095 {
5096 TEST_EQUAL( len, 3 );
5097 TEST_EQUAL( p[0], 1 );
5098 TEST_EQUAL( p[1], 0 );
5099 TEST_EQUAL( p[2], 1 );
5100 }
5101 else
5102 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
5103 }
5104
5105exit:
5106 psa_reset_key_attributes( &attributes );
5107 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005108 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005109 mbedtls_free( e_read_buffer );
5110 mbedtls_free( exported );
5111}
5112/* END_CASE */
5113
Darryl Greend49a4992018-06-18 17:27:26 +01005114/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005115void persistent_key_load_key_from_storage( data_t *data,
5116 int type_arg, int bits_arg,
5117 int usage_flags_arg, int alg_arg,
5118 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01005119{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005120 psa_key_id_t key_id = 1;
5121 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005122 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005123 psa_key_handle_t base_key = 0;
5124 psa_key_type_t type = type_arg;
5125 size_t bits = bits_arg;
5126 psa_key_usage_t usage_flags = usage_flags_arg;
5127 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005128 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01005129 unsigned char *first_export = NULL;
5130 unsigned char *second_export = NULL;
5131 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
5132 size_t first_exported_length;
5133 size_t second_exported_length;
5134
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005135 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5136 {
5137 ASSERT_ALLOC( first_export, export_size );
5138 ASSERT_ALLOC( second_export, export_size );
5139 }
Darryl Greend49a4992018-06-18 17:27:26 +01005140
Gilles Peskine8817f612018-12-18 00:18:46 +01005141 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005142
Gilles Peskinec87af662019-05-15 16:12:22 +02005143 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005144 psa_set_key_usage_flags( &attributes, usage_flags );
5145 psa_set_key_algorithm( &attributes, alg );
5146 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005147 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01005148
Darryl Green0c6575a2018-11-07 16:05:30 +00005149 switch( generation_method )
5150 {
5151 case IMPORT_KEY:
5152 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02005153 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
5154 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005155 break;
Darryl Greend49a4992018-06-18 17:27:26 +01005156
Darryl Green0c6575a2018-11-07 16:05:30 +00005157 case GENERATE_KEY:
5158 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005159 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005160 break;
5161
5162 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005163 {
5164 /* Create base key */
5165 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
5166 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5167 psa_set_key_usage_flags( &base_attributes,
5168 PSA_KEY_USAGE_DERIVE );
5169 psa_set_key_algorithm( &base_attributes, derive_alg );
5170 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005171 PSA_ASSERT( psa_import_key( &base_attributes,
5172 data->x, data->len,
5173 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005174 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005175 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005176 PSA_ASSERT( psa_key_derivation_input_key(
5177 &operation,
5178 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005179 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005180 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005181 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005182 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5183 &operation,
5184 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005185 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005186 PSA_ASSERT( psa_destroy_key( base_key ) );
5187 base_key = 0;
5188 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005189 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005190 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005191 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005192
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005193 /* Export the key if permitted by the key policy. */
5194 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5195 {
5196 PSA_ASSERT( psa_export_key( handle,
5197 first_export, export_size,
5198 &first_exported_length ) );
5199 if( generation_method == IMPORT_KEY )
5200 ASSERT_COMPARE( data->x, data->len,
5201 first_export, first_exported_length );
5202 }
Darryl Greend49a4992018-06-18 17:27:26 +01005203
5204 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005205 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005206 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005207 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005208
Darryl Greend49a4992018-06-18 17:27:26 +01005209 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005210 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005211 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5212 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5213 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5214 PSA_KEY_LIFETIME_PERSISTENT );
5215 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5216 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5217 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5218 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005219
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005220 /* Export the key again if permitted by the key policy. */
5221 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005222 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005223 PSA_ASSERT( psa_export_key( handle,
5224 second_export, export_size,
5225 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005226 ASSERT_COMPARE( first_export, first_exported_length,
5227 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005228 }
5229
5230 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005231 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005232 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005233
5234exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005235 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005236 mbedtls_free( first_export );
5237 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005238 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005239 psa_destroy_key( base_key );
5240 if( handle == 0 )
5241 {
5242 /* In case there was a test failure after creating the persistent key
5243 * but while it was not open, try to re-open the persistent key
5244 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005245 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005246 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005247 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005248 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005249}
5250/* END_CASE */