blob: 81ccb4ce31a2ad3b2c609155df4d331f0df9ca16 [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 Peskinebdc96fd2019-08-07 12:08:04 +02008/* For MBEDTLS_CTR_DRBG_MAX_REQUEST, knowing that psa_generate_random()
9 * uses mbedtls_ctr_drbg internally. */
10#include "mbedtls/ctr_drbg.h"
11
Gilles Peskine1838e822019-06-20 12:40:56 +020012#include "psa_crypto_helpers.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +030013
Gilles Peskinec744d992019-07-30 17:26:54 +020014/* Tests that require more than 128kB of RAM plus change have this symbol
15 * as a dependency. Currently we always define this symbol, so the tests
16 * are always executed. In the future we should make this conditional
17 * so that tests that require a lot of memory are skipped on constrained
18 * platforms. */
Gilles Peskine49232e82019-08-07 11:01:30 +020019#define HAVE_RAM_AVAILABLE_128K
Gilles Peskinec744d992019-07-30 17:26:54 +020020
Gilles Peskinebdc96fd2019-08-07 12:08:04 +020021#include "psa/crypto.h"
22
Jaeden Amerof24c7f82018-06-27 17:20:43 +010023/** An invalid export length that will never be set by psa_export_key(). */
24static const size_t INVALID_EXPORT_LENGTH = ~0U;
25
Gilles Peskinef426e0f2019-02-25 17:42:03 +010026/* A hash algorithm that is known to be supported.
27 *
28 * This is used in some smoke tests.
29 */
30#if defined(MBEDTLS_MD2_C)
31#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
32#elif defined(MBEDTLS_MD4_C)
33#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
34#elif defined(MBEDTLS_MD5_C)
35#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
36/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
37 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
38 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
39 * implausible anyway. */
40#elif defined(MBEDTLS_SHA1_C)
41#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
42#elif defined(MBEDTLS_SHA256_C)
43#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
44#elif defined(MBEDTLS_SHA512_C)
45#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
46#elif defined(MBEDTLS_SHA3_C)
47#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
48#else
49#undef KNOWN_SUPPORTED_HASH_ALG
50#endif
51
52/* A block cipher that is known to be supported.
53 *
54 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
55 */
56#if defined(MBEDTLS_AES_C)
57#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
58#elif defined(MBEDTLS_ARIA_C)
59#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
60#elif defined(MBEDTLS_CAMELLIA_C)
61#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
62#undef KNOWN_SUPPORTED_BLOCK_CIPHER
63#endif
64
65/* A MAC mode that is known to be supported.
66 *
67 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
68 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
69 *
70 * This is used in some smoke tests.
71 */
72#if defined(KNOWN_SUPPORTED_HASH_ALG)
73#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
74#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
75#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
76#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
77#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
78#else
79#undef KNOWN_SUPPORTED_MAC_ALG
80#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
81#endif
82
83/* A cipher algorithm and key type that are known to be supported.
84 *
85 * This is used in some smoke tests.
86 */
87#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
88#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
89#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
90#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
91#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
92#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
93#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
94#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
95#else
96#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
97#endif
98#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
99#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
100#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
101#elif defined(MBEDTLS_RC4_C)
102#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
103#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
104#else
105#undef KNOWN_SUPPORTED_CIPHER_ALG
106#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
107#endif
108
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200109/** Test if a buffer contains a constant byte value.
110 *
111 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200112 *
113 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200114 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200115 * \param size Size of the buffer in bytes.
116 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200117 * \return 1 if the buffer is all-bits-zero.
118 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200119 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200120static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200121{
122 size_t i;
123 for( i = 0; i < size; i++ )
124 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200125 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200126 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200127 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200128 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200129}
Gilles Peskine818ca122018-06-20 18:16:48 +0200130
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200131/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
132static int asn1_write_10x( unsigned char **p,
133 unsigned char *start,
134 size_t bits,
135 unsigned char x )
136{
137 int ret;
138 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200139 if( bits == 0 )
140 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
141 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200142 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300143 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200144 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
145 *p -= len;
146 ( *p )[len-1] = x;
147 if( bits % 8 == 0 )
148 ( *p )[1] |= 1;
149 else
150 ( *p )[0] |= 1 << ( bits % 8 );
151 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
152 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
153 MBEDTLS_ASN1_INTEGER ) );
154 return( len );
155}
156
157static int construct_fake_rsa_key( unsigned char *buffer,
158 size_t buffer_size,
159 unsigned char **p,
160 size_t bits,
161 int keypair )
162{
163 size_t half_bits = ( bits + 1 ) / 2;
164 int ret;
165 int len = 0;
166 /* Construct something that looks like a DER encoding of
167 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
168 * RSAPrivateKey ::= SEQUENCE {
169 * version Version,
170 * modulus INTEGER, -- n
171 * publicExponent INTEGER, -- e
172 * privateExponent INTEGER, -- d
173 * prime1 INTEGER, -- p
174 * prime2 INTEGER, -- q
175 * exponent1 INTEGER, -- d mod (p-1)
176 * exponent2 INTEGER, -- d mod (q-1)
177 * coefficient INTEGER, -- (inverse of q) mod p
178 * otherPrimeInfos OtherPrimeInfos OPTIONAL
179 * }
180 * Or, for a public key, the same structure with only
181 * version, modulus and publicExponent.
182 */
183 *p = buffer + buffer_size;
184 if( keypair )
185 {
186 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
187 asn1_write_10x( p, buffer, half_bits, 1 ) );
188 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
189 asn1_write_10x( p, buffer, half_bits, 1 ) );
190 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
191 asn1_write_10x( p, buffer, half_bits, 1 ) );
192 MBEDTLS_ASN1_CHK_ADD( len, /* q */
193 asn1_write_10x( p, buffer, half_bits, 1 ) );
194 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
195 asn1_write_10x( p, buffer, half_bits, 3 ) );
196 MBEDTLS_ASN1_CHK_ADD( len, /* d */
197 asn1_write_10x( p, buffer, bits, 1 ) );
198 }
199 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
200 asn1_write_10x( p, buffer, 17, 1 ) );
201 MBEDTLS_ASN1_CHK_ADD( len, /* n */
202 asn1_write_10x( p, buffer, bits, 1 ) );
203 if( keypair )
204 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
205 mbedtls_asn1_write_int( p, buffer, 0 ) );
206 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
207 {
208 const unsigned char tag =
209 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
210 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
211 }
212 return( len );
213}
214
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100215int exercise_mac_setup( psa_key_type_t key_type,
216 const unsigned char *key_bytes,
217 size_t key_length,
218 psa_algorithm_t alg,
219 psa_mac_operation_t *operation,
220 psa_status_t *status )
221{
222 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200223 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100224
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200225 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
226 psa_set_key_algorithm( &attributes, alg );
227 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200228 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
229 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100230
231 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100232 /* Whether setup succeeded or failed, abort must succeed. */
233 PSA_ASSERT( psa_mac_abort( operation ) );
234 /* If setup failed, reproduce the failure, so that the caller can
235 * test the resulting state of the operation object. */
236 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100237 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100238 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
239 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100240 }
241
242 psa_destroy_key( handle );
243 return( 1 );
244
245exit:
246 psa_destroy_key( handle );
247 return( 0 );
248}
249
250int exercise_cipher_setup( psa_key_type_t key_type,
251 const unsigned char *key_bytes,
252 size_t key_length,
253 psa_algorithm_t alg,
254 psa_cipher_operation_t *operation,
255 psa_status_t *status )
256{
257 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200258 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100259
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200260 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
261 psa_set_key_algorithm( &attributes, alg );
262 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200263 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
264 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100265
266 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100267 /* Whether setup succeeded or failed, abort must succeed. */
268 PSA_ASSERT( psa_cipher_abort( operation ) );
269 /* If setup failed, reproduce the failure, so that the caller can
270 * test the resulting state of the operation object. */
271 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100272 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100273 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
274 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100275 }
276
277 psa_destroy_key( handle );
278 return( 1 );
279
280exit:
281 psa_destroy_key( handle );
282 return( 0 );
283}
284
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100285static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200286 psa_key_usage_t usage,
287 psa_algorithm_t alg )
288{
Jaeden Amero769ce272019-01-04 11:48:03 +0000289 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200290 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200291 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200292 size_t mac_length = sizeof( mac );
293
294 if( usage & PSA_KEY_USAGE_SIGN )
295 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100296 PSA_ASSERT( psa_mac_sign_setup( &operation,
297 handle, alg ) );
298 PSA_ASSERT( psa_mac_update( &operation,
299 input, sizeof( input ) ) );
300 PSA_ASSERT( psa_mac_sign_finish( &operation,
301 mac, sizeof( mac ),
302 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200303 }
304
305 if( usage & PSA_KEY_USAGE_VERIFY )
306 {
307 psa_status_t verify_status =
308 ( usage & PSA_KEY_USAGE_SIGN ?
309 PSA_SUCCESS :
310 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100311 PSA_ASSERT( psa_mac_verify_setup( &operation,
312 handle, alg ) );
313 PSA_ASSERT( psa_mac_update( &operation,
314 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100315 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
316 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200317 }
318
319 return( 1 );
320
321exit:
322 psa_mac_abort( &operation );
323 return( 0 );
324}
325
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100326static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200327 psa_key_usage_t usage,
328 psa_algorithm_t alg )
329{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000330 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200331 unsigned char iv[16] = {0};
332 size_t iv_length = sizeof( iv );
333 const unsigned char plaintext[16] = "Hello, world...";
334 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
335 size_t ciphertext_length = sizeof( ciphertext );
336 unsigned char decrypted[sizeof( ciphertext )];
337 size_t part_length;
338
339 if( usage & PSA_KEY_USAGE_ENCRYPT )
340 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100341 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
342 handle, alg ) );
343 PSA_ASSERT( psa_cipher_generate_iv( &operation,
344 iv, sizeof( iv ),
345 &iv_length ) );
346 PSA_ASSERT( psa_cipher_update( &operation,
347 plaintext, sizeof( plaintext ),
348 ciphertext, sizeof( ciphertext ),
349 &ciphertext_length ) );
350 PSA_ASSERT( psa_cipher_finish( &operation,
351 ciphertext + ciphertext_length,
352 sizeof( ciphertext ) - ciphertext_length,
353 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200354 ciphertext_length += part_length;
355 }
356
357 if( usage & PSA_KEY_USAGE_DECRYPT )
358 {
359 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200360 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200361 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
362 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200363 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
364 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
365 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
366 * have this macro yet. */
367 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
368 psa_get_key_type( &attributes ) );
369 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200370 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100371 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
372 handle, alg ) );
373 PSA_ASSERT( psa_cipher_set_iv( &operation,
374 iv, iv_length ) );
375 PSA_ASSERT( psa_cipher_update( &operation,
376 ciphertext, ciphertext_length,
377 decrypted, sizeof( decrypted ),
378 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200379 status = psa_cipher_finish( &operation,
380 decrypted + part_length,
381 sizeof( decrypted ) - part_length,
382 &part_length );
383 /* For a stream cipher, all inputs are valid. For a block cipher,
384 * if the input is some aribtrary data rather than an actual
385 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200386 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200387 TEST_ASSERT( status == PSA_SUCCESS ||
388 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200389 else
390 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200391 }
392
393 return( 1 );
394
395exit:
396 psa_cipher_abort( &operation );
397 return( 0 );
398}
399
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100400static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200401 psa_key_usage_t usage,
402 psa_algorithm_t alg )
403{
404 unsigned char nonce[16] = {0};
405 size_t nonce_length = sizeof( nonce );
406 unsigned char plaintext[16] = "Hello, world...";
407 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
408 size_t ciphertext_length = sizeof( ciphertext );
409 size_t plaintext_length = sizeof( ciphertext );
410
411 if( usage & PSA_KEY_USAGE_ENCRYPT )
412 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100413 PSA_ASSERT( psa_aead_encrypt( handle, alg,
414 nonce, nonce_length,
415 NULL, 0,
416 plaintext, sizeof( plaintext ),
417 ciphertext, sizeof( ciphertext ),
418 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200419 }
420
421 if( usage & PSA_KEY_USAGE_DECRYPT )
422 {
423 psa_status_t verify_status =
424 ( usage & PSA_KEY_USAGE_ENCRYPT ?
425 PSA_SUCCESS :
426 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100427 TEST_EQUAL( psa_aead_decrypt( handle, alg,
428 nonce, nonce_length,
429 NULL, 0,
430 ciphertext, ciphertext_length,
431 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100432 &plaintext_length ),
433 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200434 }
435
436 return( 1 );
437
438exit:
439 return( 0 );
440}
441
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100442static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200443 psa_key_usage_t usage,
444 psa_algorithm_t alg )
445{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200446 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
447 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200448 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200449 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100450 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
451
452 /* If the policy allows signing with any hash, just pick one. */
453 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
454 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100455#if defined(KNOWN_SUPPORTED_HASH_ALG)
456 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
457 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100458#else
459 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100460 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100461#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100462 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200463
464 if( usage & PSA_KEY_USAGE_SIGN )
465 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200466 /* Some algorithms require the payload to have the size of
467 * the hash encoded in the algorithm. Use this input size
468 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200469 if( hash_alg != 0 )
470 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100471 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
472 payload, payload_length,
473 signature, sizeof( signature ),
474 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200475 }
476
477 if( usage & PSA_KEY_USAGE_VERIFY )
478 {
479 psa_status_t verify_status =
480 ( usage & PSA_KEY_USAGE_SIGN ?
481 PSA_SUCCESS :
482 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100483 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
484 payload, payload_length,
485 signature, signature_length ),
486 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200487 }
488
489 return( 1 );
490
491exit:
492 return( 0 );
493}
494
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100495static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200496 psa_key_usage_t usage,
497 psa_algorithm_t alg )
498{
499 unsigned char plaintext[256] = "Hello, world...";
500 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
501 size_t ciphertext_length = sizeof( ciphertext );
502 size_t plaintext_length = 16;
503
504 if( usage & PSA_KEY_USAGE_ENCRYPT )
505 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100506 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
507 plaintext, plaintext_length,
508 NULL, 0,
509 ciphertext, sizeof( ciphertext ),
510 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200511 }
512
513 if( usage & PSA_KEY_USAGE_DECRYPT )
514 {
515 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100516 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200517 ciphertext, ciphertext_length,
518 NULL, 0,
519 plaintext, sizeof( plaintext ),
520 &plaintext_length );
521 TEST_ASSERT( status == PSA_SUCCESS ||
522 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
523 ( status == PSA_ERROR_INVALID_ARGUMENT ||
524 status == PSA_ERROR_INVALID_PADDING ) ) );
525 }
526
527 return( 1 );
528
529exit:
530 return( 0 );
531}
Gilles Peskine02b75072018-07-01 22:31:34 +0200532
Janos Follathf2815ea2019-07-03 12:41:36 +0100533static int setup_key_derivation_wrap( psa_key_derivation_operation_t* operation,
534 psa_key_handle_t handle,
535 psa_algorithm_t alg,
536 unsigned char* input1, size_t input1_length,
537 unsigned char* input2, size_t input2_length,
538 size_t capacity )
539{
540 PSA_ASSERT( psa_key_derivation_setup( operation, alg ) );
541 if( PSA_ALG_IS_HKDF( alg ) )
542 {
543 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
544 PSA_KEY_DERIVATION_INPUT_SALT,
545 input1, input1_length ) );
546 PSA_ASSERT( psa_key_derivation_input_key( operation,
547 PSA_KEY_DERIVATION_INPUT_SECRET,
548 handle ) );
549 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
550 PSA_KEY_DERIVATION_INPUT_INFO,
551 input2,
552 input2_length ) );
553 }
554 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
555 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
556 {
557 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
558 PSA_KEY_DERIVATION_INPUT_SEED,
559 input1, input1_length ) );
560 PSA_ASSERT( psa_key_derivation_input_key( operation,
561 PSA_KEY_DERIVATION_INPUT_SECRET,
562 handle ) );
563 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
564 PSA_KEY_DERIVATION_INPUT_LABEL,
565 input2, input2_length ) );
566 }
567 else
568 {
569 TEST_ASSERT( ! "Key derivation algorithm not supported" );
570 }
571
Gilles Peskinec744d992019-07-30 17:26:54 +0200572 if( capacity != SIZE_MAX )
573 PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
Janos Follathf2815ea2019-07-03 12:41:36 +0100574
575 return( 1 );
576
577exit:
578 return( 0 );
579}
580
581
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100582static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200583 psa_key_usage_t usage,
584 psa_algorithm_t alg )
585{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200586 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathf2815ea2019-07-03 12:41:36 +0100587 unsigned char input1[] = "Input 1";
588 size_t input1_length = sizeof( input1 );
589 unsigned char input2[] = "Input 2";
590 size_t input2_length = sizeof( input2 );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200591 unsigned char output[1];
Janos Follathf2815ea2019-07-03 12:41:36 +0100592 size_t capacity = sizeof( output );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200593
594 if( usage & PSA_KEY_USAGE_DERIVE )
595 {
Janos Follathf2815ea2019-07-03 12:41:36 +0100596 if( !setup_key_derivation_wrap( &operation, handle, alg,
597 input1, input1_length,
598 input2, input2_length, capacity ) )
599 goto exit;
Gilles Peskine7607cd62019-05-29 17:35:00 +0200600
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200601 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200602 output,
Janos Follathf2815ea2019-07-03 12:41:36 +0100603 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200604 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200605 }
606
607 return( 1 );
608
609exit:
610 return( 0 );
611}
612
Gilles Peskinec7998b72018-11-07 18:45:02 +0100613/* We need two keys to exercise key agreement. Exercise the
614 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200615static psa_status_t key_agreement_with_self(
616 psa_key_derivation_operation_t *operation,
617 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100618{
619 psa_key_type_t private_key_type;
620 psa_key_type_t public_key_type;
621 size_t key_bits;
622 uint8_t *public_key = NULL;
623 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200624 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200625 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
626 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200627 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200628 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100629
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200630 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
631 private_key_type = psa_get_key_type( &attributes );
632 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200633 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100634 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
635 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100636 PSA_ASSERT( psa_export_public_key( handle,
637 public_key, public_key_length,
638 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100639
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200640 status = psa_key_derivation_key_agreement(
641 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
642 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100643exit:
644 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200645 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100646 return( status );
647}
648
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200649/* We need two keys to exercise key agreement. Exercise the
650 * private key against its own public key. */
651static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
652 psa_key_handle_t handle )
653{
654 psa_key_type_t private_key_type;
655 psa_key_type_t public_key_type;
656 size_t key_bits;
657 uint8_t *public_key = NULL;
658 size_t public_key_length;
659 uint8_t output[1024];
660 size_t output_length;
661 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200662 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
663 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200664 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200665 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200666
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200667 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
668 private_key_type = psa_get_key_type( &attributes );
669 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200670 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200671 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
672 ASSERT_ALLOC( public_key, public_key_length );
673 PSA_ASSERT( psa_export_public_key( handle,
674 public_key, public_key_length,
675 &public_key_length ) );
676
Gilles Peskinebe697d82019-05-16 18:00:41 +0200677 status = psa_raw_key_agreement( alg, handle,
678 public_key, public_key_length,
679 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200680exit:
681 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200682 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200683 return( status );
684}
685
686static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
687 psa_key_usage_t usage,
688 psa_algorithm_t alg )
689{
690 int ok = 0;
691
692 if( usage & PSA_KEY_USAGE_DERIVE )
693 {
694 /* We need two keys to exercise key agreement. Exercise the
695 * private key against its own public key. */
696 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
697 }
698 ok = 1;
699
700exit:
701 return( ok );
702}
703
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100704static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200705 psa_key_usage_t usage,
706 psa_algorithm_t alg )
707{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200708 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200709 unsigned char output[1];
710 int ok = 0;
711
712 if( usage & PSA_KEY_USAGE_DERIVE )
713 {
714 /* We need two keys to exercise key agreement. Exercise the
715 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200716 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
717 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
718 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200719 output,
720 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200721 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200722 }
723 ok = 1;
724
725exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200726 return( ok );
727}
728
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200729static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
730 size_t min_bits, size_t max_bits,
731 int must_be_odd )
732{
733 size_t len;
734 size_t actual_bits;
735 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100736 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100737 MBEDTLS_ASN1_INTEGER ),
738 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200739 /* Tolerate a slight departure from DER encoding:
740 * - 0 may be represented by an empty string or a 1-byte string.
741 * - The sign bit may be used as a value bit. */
742 if( ( len == 1 && ( *p )[0] == 0 ) ||
743 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
744 {
745 ++( *p );
746 --len;
747 }
748 if( min_bits == 0 && len == 0 )
749 return( 1 );
750 msb = ( *p )[0];
751 TEST_ASSERT( msb != 0 );
752 actual_bits = 8 * ( len - 1 );
753 while( msb != 0 )
754 {
755 msb >>= 1;
756 ++actual_bits;
757 }
758 TEST_ASSERT( actual_bits >= min_bits );
759 TEST_ASSERT( actual_bits <= max_bits );
760 if( must_be_odd )
761 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
762 *p += len;
763 return( 1 );
764exit:
765 return( 0 );
766}
767
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200768static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
769 uint8_t *exported, size_t exported_length )
770{
771 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100772 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200773 else
774 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200775
776#if defined(MBEDTLS_DES_C)
777 if( type == PSA_KEY_TYPE_DES )
778 {
779 /* Check the parity bits. */
780 unsigned i;
781 for( i = 0; i < bits / 8; i++ )
782 {
783 unsigned bit_count = 0;
784 unsigned m;
785 for( m = 1; m <= 0x100; m <<= 1 )
786 {
787 if( exported[i] & m )
788 ++bit_count;
789 }
790 TEST_ASSERT( bit_count % 2 != 0 );
791 }
792 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200793 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200794#endif
795
796#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200797 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200798 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200799 uint8_t *p = exported;
800 uint8_t *end = exported + exported_length;
801 size_t len;
802 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200803 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200804 * modulus INTEGER, -- n
805 * publicExponent INTEGER, -- e
806 * privateExponent INTEGER, -- d
807 * prime1 INTEGER, -- p
808 * prime2 INTEGER, -- q
809 * exponent1 INTEGER, -- d mod (p-1)
810 * exponent2 INTEGER, -- d mod (q-1)
811 * coefficient INTEGER, -- (inverse of q) mod p
812 * }
813 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100814 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
815 MBEDTLS_ASN1_SEQUENCE |
816 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
817 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200818 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
819 goto exit;
820 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
821 goto exit;
822 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
823 goto exit;
824 /* Require d to be at least half the size of n. */
825 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
826 goto exit;
827 /* Require p and q to be at most half the size of n, rounded up. */
828 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
829 goto exit;
830 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
831 goto exit;
832 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
833 goto exit;
834 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
835 goto exit;
836 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
837 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100838 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100839 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200840 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200841#endif /* MBEDTLS_RSA_C */
842
843#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200844 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200845 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100846 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100847 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100848 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200849 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200850#endif /* MBEDTLS_ECP_C */
851
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200852 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
853 {
854 uint8_t *p = exported;
855 uint8_t *end = exported + exported_length;
856 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200857#if defined(MBEDTLS_RSA_C)
858 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
859 {
860 /* RSAPublicKey ::= SEQUENCE {
861 * modulus INTEGER, -- n
862 * publicExponent INTEGER } -- e
863 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100864 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
865 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100866 MBEDTLS_ASN1_CONSTRUCTED ),
867 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100868 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200869 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
870 goto exit;
871 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
872 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100873 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200874 }
875 else
876#endif /* MBEDTLS_RSA_C */
877#if defined(MBEDTLS_ECP_C)
878 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
879 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000880 /* The representation of an ECC public key is:
881 * - The byte 0x04;
882 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
883 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
884 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000885 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100886 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
887 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200888 }
889 else
890#endif /* MBEDTLS_ECP_C */
891 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100892 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200893 mbedtls_snprintf( message, sizeof( message ),
894 "No sanity check for public key type=0x%08lx",
895 (unsigned long) type );
896 test_fail( message, __LINE__, __FILE__ );
897 return( 0 );
898 }
899 }
900 else
901
902 {
903 /* No sanity checks for other types */
904 }
905
906 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200907
908exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200909 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200910}
911
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100912static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200913 psa_key_usage_t usage )
914{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200915 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200916 uint8_t *exported = NULL;
917 size_t exported_size = 0;
918 size_t exported_length = 0;
919 int ok = 0;
920
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200921 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200922
923 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200924 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200925 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100926 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
927 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200928 ok = 1;
929 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200930 }
931
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200932 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
933 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200934 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200935
Gilles Peskine8817f612018-12-18 00:18:46 +0100936 PSA_ASSERT( psa_export_key( handle,
937 exported, exported_size,
938 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200939 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
940 psa_get_key_bits( &attributes ),
941 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200942
943exit:
944 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200945 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200946 return( ok );
947}
948
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100949static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200950{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200951 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200952 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200953 uint8_t *exported = NULL;
954 size_t exported_size = 0;
955 size_t exported_length = 0;
956 int ok = 0;
957
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200958 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
959 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200960 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100961 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100962 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200963 return( 1 );
964 }
965
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200966 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 psa_get_key_type( &attributes ) );
968 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
969 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200970 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200971
Gilles Peskine8817f612018-12-18 00:18:46 +0100972 PSA_ASSERT( psa_export_public_key( handle,
973 exported, exported_size,
974 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200975 ok = exported_key_sanity_check( public_type,
976 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200977 exported, exported_length );
978
979exit:
980 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200981 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200982 return( ok );
983}
984
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100985/** Do smoke tests on a key.
986 *
987 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
988 * sign/verify, or derivation) that is permitted according to \p usage.
989 * \p usage and \p alg should correspond to the expected policy on the
990 * key.
991 *
992 * Export the key if permitted by \p usage, and check that the output
993 * looks sensible. If \p usage forbids export, check that
994 * \p psa_export_key correctly rejects the attempt. If the key is
995 * asymmetric, also check \p psa_export_public_key.
996 *
997 * If the key fails the tests, this function calls the test framework's
998 * `test_fail` function and returns false. Otherwise this function returns
999 * true. Therefore it should be used as follows:
1000 * ```
1001 * if( ! exercise_key( ... ) ) goto exit;
1002 * ```
1003 *
1004 * \param handle The key to exercise. It should be capable of performing
1005 * \p alg.
1006 * \param usage The usage flags to assume.
1007 * \param alg The algorithm to exercise.
1008 *
1009 * \retval 0 The key failed the smoke tests.
1010 * \retval 1 The key passed the smoke tests.
1011 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001012static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001013 psa_key_usage_t usage,
1014 psa_algorithm_t alg )
1015{
1016 int ok;
1017 if( alg == 0 )
1018 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1019 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001020 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001021 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001022 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001023 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001024 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001025 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001026 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001027 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001029 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001030 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001031 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1032 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001033 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001034 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001035 else
1036 {
1037 char message[40];
1038 mbedtls_snprintf( message, sizeof( message ),
1039 "No code to exercise alg=0x%08lx",
1040 (unsigned long) alg );
1041 test_fail( message, __LINE__, __FILE__ );
1042 ok = 0;
1043 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001044
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001045 ok = ok && exercise_export_key( handle, usage );
1046 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001047
Gilles Peskine02b75072018-07-01 22:31:34 +02001048 return( ok );
1049}
1050
Gilles Peskine10df3412018-10-25 22:35:43 +02001051static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1052 psa_algorithm_t alg )
1053{
1054 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1055 {
1056 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1057 PSA_KEY_USAGE_VERIFY :
1058 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1059 }
1060 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1061 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1062 {
1063 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1064 PSA_KEY_USAGE_ENCRYPT :
1065 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1066 }
1067 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1068 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1069 {
1070 return( PSA_KEY_USAGE_DERIVE );
1071 }
1072 else
1073 {
1074 return( 0 );
1075 }
1076
1077}
Darryl Green0c6575a2018-11-07 16:05:30 +00001078
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001079static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1080{
1081 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1082 uint8_t buffer[1];
1083 size_t length;
1084 int ok = 0;
1085
Gilles Peskinec87af662019-05-15 16:12:22 +02001086 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001087 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1088 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1089 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1090 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1091 PSA_ERROR_INVALID_HANDLE );
1092 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001093 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001094 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1095 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1096 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1097 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1098
1099 TEST_EQUAL( psa_export_key( handle,
1100 buffer, sizeof( buffer ), &length ),
1101 PSA_ERROR_INVALID_HANDLE );
1102 TEST_EQUAL( psa_export_public_key( handle,
1103 buffer, sizeof( buffer ), &length ),
1104 PSA_ERROR_INVALID_HANDLE );
1105
1106 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1107 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1108
1109 ok = 1;
1110
1111exit:
1112 psa_reset_key_attributes( &attributes );
1113 return( ok );
1114}
1115
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001116/* An overapproximation of the amount of storage needed for a key of the
1117 * given type and with the given content. The API doesn't make it easy
1118 * to find a good value for the size. The current implementation doesn't
1119 * care about the value anyway. */
1120#define KEY_BITS_FROM_DATA( type, data ) \
1121 ( data )->len
1122
Darryl Green0c6575a2018-11-07 16:05:30 +00001123typedef enum {
1124 IMPORT_KEY = 0,
1125 GENERATE_KEY = 1,
1126 DERIVE_KEY = 2
1127} generate_method;
1128
Gilles Peskinee59236f2018-01-27 23:32:46 +01001129/* END_HEADER */
1130
1131/* BEGIN_DEPENDENCIES
1132 * depends_on:MBEDTLS_PSA_CRYPTO_C
1133 * END_DEPENDENCIES
1134 */
1135
1136/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001137void static_checks( )
1138{
1139 size_t max_truncated_mac_size =
1140 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1141
1142 /* Check that the length for a truncated MAC always fits in the algorithm
1143 * encoding. The shifted mask is the maximum truncated value. The
1144 * untruncated algorithm may be one byte larger. */
1145 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1146}
1147/* END_CASE */
1148
1149/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001150void attributes_set_get( int id_arg, int lifetime_arg,
1151 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001152 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001153{
Gilles Peskine4747d192019-04-17 15:05:45 +02001154 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001155 psa_key_id_t id = id_arg;
1156 psa_key_lifetime_t lifetime = lifetime_arg;
1157 psa_key_usage_t usage_flags = usage_flags_arg;
1158 psa_algorithm_t alg = alg_arg;
1159 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001160 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001161
1162 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1163 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1164 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1165 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1166 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001167 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001168
Gilles Peskinec87af662019-05-15 16:12:22 +02001169 psa_set_key_id( &attributes, id );
1170 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001171 psa_set_key_usage_flags( &attributes, usage_flags );
1172 psa_set_key_algorithm( &attributes, alg );
1173 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001174 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001175
1176 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1177 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1178 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1179 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1180 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001181 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001182
1183 psa_reset_key_attributes( &attributes );
1184
1185 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1186 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1187 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1188 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1189 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001190 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001191}
1192/* END_CASE */
1193
1194/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001195void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1196 int expected_id_arg, int expected_lifetime_arg )
1197{
1198 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1199 psa_key_id_t id1 = id1_arg;
1200 psa_key_lifetime_t lifetime = lifetime_arg;
1201 psa_key_id_t id2 = id2_arg;
1202 psa_key_id_t expected_id = expected_id_arg;
1203 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1204
1205 if( id1_arg != -1 )
1206 psa_set_key_id( &attributes, id1 );
1207 if( lifetime_arg != -1 )
1208 psa_set_key_lifetime( &attributes, lifetime );
1209 if( id2_arg != -1 )
1210 psa_set_key_id( &attributes, id2 );
1211
1212 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1213 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1214}
1215/* END_CASE */
1216
1217/* BEGIN_CASE */
Gilles Peskine6edfa292019-07-31 15:53:45 +02001218void import_with_policy( int type_arg,
1219 int usage_arg, int alg_arg,
1220 int expected_status_arg )
1221{
1222 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1223 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1224 psa_key_handle_t handle = 0;
1225 psa_key_type_t type = type_arg;
1226 psa_key_usage_t usage = usage_arg;
1227 psa_algorithm_t alg = alg_arg;
1228 psa_status_t expected_status = expected_status_arg;
1229 const uint8_t key_material[16] = {0};
1230 psa_status_t status;
1231
1232 PSA_ASSERT( psa_crypto_init( ) );
1233
1234 psa_set_key_type( &attributes, type );
1235 psa_set_key_usage_flags( &attributes, usage );
1236 psa_set_key_algorithm( &attributes, alg );
1237
1238 status = psa_import_key( &attributes,
1239 key_material, sizeof( key_material ),
1240 &handle );
1241 TEST_EQUAL( status, expected_status );
1242 if( status != PSA_SUCCESS )
1243 goto exit;
1244
1245 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1246 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1247 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1248 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1249
1250 PSA_ASSERT( psa_destroy_key( handle ) );
1251 test_operations_on_invalid_handle( handle );
1252
1253exit:
1254 psa_destroy_key( handle );
1255 psa_reset_key_attributes( &got_attributes );
1256 PSA_DONE( );
1257}
1258/* END_CASE */
1259
1260/* BEGIN_CASE */
1261void import_with_data( data_t *data, int type_arg,
1262 int attr_bits_arg,
1263 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001264{
1265 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1266 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001267 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001268 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001269 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001270 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001271 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001272
Gilles Peskine8817f612018-12-18 00:18:46 +01001273 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001274
Gilles Peskine4747d192019-04-17 15:05:45 +02001275 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001276 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001277
Gilles Peskine73676cb2019-05-15 20:15:10 +02001278 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001279 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001280 if( status != PSA_SUCCESS )
1281 goto exit;
1282
1283 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1284 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001285 if( attr_bits != 0 )
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001286 TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001287
1288 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001289 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001290
1291exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001292 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001293 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001294 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001295}
1296/* END_CASE */
1297
1298/* BEGIN_CASE */
Gilles Peskinec744d992019-07-30 17:26:54 +02001299void import_large_key( int type_arg, int byte_size_arg,
1300 int expected_status_arg )
1301{
1302 psa_key_type_t type = type_arg;
1303 size_t byte_size = byte_size_arg;
1304 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1305 psa_status_t expected_status = expected_status_arg;
1306 psa_key_handle_t handle = 0;
1307 psa_status_t status;
1308 uint8_t *buffer = NULL;
1309 size_t buffer_size = byte_size + 1;
1310 size_t n;
1311
1312 /* It would be better to skip the test than fail it if the allocation
1313 * fails, but the test framework doesn't support this yet. */
1314 ASSERT_ALLOC( buffer, buffer_size );
1315 memset( buffer, 'K', byte_size );
1316
1317 PSA_ASSERT( psa_crypto_init( ) );
1318
1319 /* Try importing the key */
1320 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1321 psa_set_key_type( &attributes, type );
1322 status = psa_import_key( &attributes, buffer, byte_size, &handle );
1323 TEST_EQUAL( status, expected_status );
1324
1325 if( status == PSA_SUCCESS )
1326 {
1327 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1328 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1329 TEST_EQUAL( psa_get_key_bits( &attributes ),
1330 PSA_BYTES_TO_BITS( byte_size ) );
1331 memset( buffer, 0, byte_size + 1 );
1332 PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) );
1333 for( n = 0; n < byte_size; n++ )
1334 TEST_EQUAL( buffer[n], 'K' );
1335 for( n = byte_size; n < buffer_size; n++ )
1336 TEST_EQUAL( buffer[n], 0 );
1337 }
1338
1339exit:
1340 psa_destroy_key( handle );
1341 PSA_DONE( );
1342 mbedtls_free( buffer );
1343}
1344/* END_CASE */
1345
1346/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001347void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1348{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001349 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001350 size_t bits = bits_arg;
1351 psa_status_t expected_status = expected_status_arg;
1352 psa_status_t status;
1353 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001354 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001355 size_t buffer_size = /* Slight overapproximations */
1356 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001357 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001358 unsigned char *p;
1359 int ret;
1360 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001361 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001362
Gilles Peskine8817f612018-12-18 00:18:46 +01001363 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001364 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001365
1366 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1367 bits, keypair ) ) >= 0 );
1368 length = ret;
1369
1370 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001371 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001372 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001373 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001374
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001375 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001376 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001377
1378exit:
1379 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001380 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001381}
1382/* END_CASE */
1383
1384/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001385void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001386 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001387 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001388 int expected_bits,
1389 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001390 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001391 int canonical_input )
1392{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001393 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001394 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001395 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001396 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001397 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001398 unsigned char *exported = NULL;
1399 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001400 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001401 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001402 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001403 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001404 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001405
Moran Pekercb088e72018-07-17 17:36:59 +03001406 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001407 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001408 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001409 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001410 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001411
Gilles Peskine4747d192019-04-17 15:05:45 +02001412 psa_set_key_usage_flags( &attributes, usage_arg );
1413 psa_set_key_algorithm( &attributes, alg );
1414 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001415
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001416 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001417 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001418
1419 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001420 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1421 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1422 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001423
1424 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001425 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001426 exported, export_size,
1427 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001428 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001429
1430 /* The exported length must be set by psa_export_key() to a value between 0
1431 * and export_size. On errors, the exported length must be 0. */
1432 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1433 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1434 TEST_ASSERT( exported_length <= export_size );
1435
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001436 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001437 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001438 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001439 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001440 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001441 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001442 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001443
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001444 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001445 goto exit;
1446
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001447 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001448 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001449 else
1450 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001451 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001452 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1453 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001454 PSA_ASSERT( psa_export_key( handle2,
1455 reexported,
1456 export_size,
1457 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001458 ASSERT_COMPARE( exported, exported_length,
1459 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001460 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001461 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001462 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001463
1464destroy:
1465 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001466 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001467 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001468
1469exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001470 mbedtls_free( exported );
1471 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001472 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001473 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001474}
1475/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001476
Moran Pekerf709f4a2018-06-06 17:26:04 +03001477/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001478void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001479{
Gilles Peskine8817f612018-12-18 00:18:46 +01001480 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001481 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001482
1483exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001484 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001485}
1486/* END_CASE */
1487
1488/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001489void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001490 int type_arg,
1491 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001492 int export_size_delta,
1493 int expected_export_status_arg,
1494 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001495{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001496 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001497 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001498 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001499 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001500 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001501 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001502 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001503 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001504 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001505
Gilles Peskine8817f612018-12-18 00:18:46 +01001506 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001507
Gilles Peskine4747d192019-04-17 15:05:45 +02001508 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1509 psa_set_key_algorithm( &attributes, alg );
1510 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001511
1512 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001513 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001514
Gilles Peskine49c25912018-10-29 15:15:31 +01001515 /* Export the public key */
1516 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001517 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001518 exported, export_size,
1519 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001520 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001521 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001522 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001523 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001524 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001525 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1526 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001527 TEST_ASSERT( expected_public_key->len <=
1528 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001529 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1530 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001531 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001532
1533exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001534 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001535 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001536 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001537 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001538}
1539/* END_CASE */
1540
Gilles Peskine20035e32018-02-03 22:44:14 +01001541/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001542void import_and_exercise_key( data_t *data,
1543 int type_arg,
1544 int bits_arg,
1545 int alg_arg )
1546{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001547 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001548 psa_key_type_t type = type_arg;
1549 size_t bits = bits_arg;
1550 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001551 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001552 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001553 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001554
Gilles Peskine8817f612018-12-18 00:18:46 +01001555 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001556
Gilles Peskine4747d192019-04-17 15:05:45 +02001557 psa_set_key_usage_flags( &attributes, usage );
1558 psa_set_key_algorithm( &attributes, alg );
1559 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001560
1561 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001562 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001563
1564 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001565 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1566 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1567 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001568
1569 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001570 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001571 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001572
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001573 PSA_ASSERT( psa_destroy_key( handle ) );
1574 test_operations_on_invalid_handle( handle );
1575
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001576exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001577 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001578 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001579 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001580}
1581/* END_CASE */
1582
1583/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001584void key_policy( int usage_arg, int alg_arg )
1585{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001586 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001587 psa_algorithm_t alg = alg_arg;
1588 psa_key_usage_t usage = usage_arg;
1589 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1590 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001591 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001592
1593 memset( key, 0x2a, sizeof( key ) );
1594
Gilles Peskine8817f612018-12-18 00:18:46 +01001595 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001596
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001597 psa_set_key_usage_flags( &attributes, usage );
1598 psa_set_key_algorithm( &attributes, alg );
1599 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001600
Gilles Peskine73676cb2019-05-15 20:15:10 +02001601 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001602
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001603 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1604 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1605 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1606 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001607
1608exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001609 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001610 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001611 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001612}
1613/* END_CASE */
1614
1615/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001616void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001617{
1618 /* Test each valid way of initializing the object, except for `= {0}`, as
1619 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1620 * though it's OK by the C standard. We could test for this, but we'd need
1621 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001622 psa_key_attributes_t func = psa_key_attributes_init( );
1623 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1624 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001625
1626 memset( &zero, 0, sizeof( zero ) );
1627
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001628 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1629 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1630 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001631
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001632 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1633 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1634 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1635
1636 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1637 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1638 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1639
1640 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1641 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1642 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1643
1644 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1645 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1646 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001647}
1648/* END_CASE */
1649
1650/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001651void mac_key_policy( int policy_usage,
1652 int policy_alg,
1653 int key_type,
1654 data_t *key_data,
1655 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001656{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001657 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001658 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001659 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001660 psa_status_t status;
1661 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001662
Gilles Peskine8817f612018-12-18 00:18:46 +01001663 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001664
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001665 psa_set_key_usage_flags( &attributes, policy_usage );
1666 psa_set_key_algorithm( &attributes, policy_alg );
1667 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001668
Gilles Peskine049c7532019-05-15 20:22:09 +02001669 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1670 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001671
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001672 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001673 if( policy_alg == exercise_alg &&
1674 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001675 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001676 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001677 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001678 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001679
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001680 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001681 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001682 if( policy_alg == exercise_alg &&
1683 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001684 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001685 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001686 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001687
1688exit:
1689 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001690 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001691 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692}
1693/* END_CASE */
1694
1695/* BEGIN_CASE */
1696void cipher_key_policy( int policy_usage,
1697 int policy_alg,
1698 int key_type,
1699 data_t *key_data,
1700 int exercise_alg )
1701{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001702 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001703 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001704 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705 psa_status_t status;
1706
Gilles Peskine8817f612018-12-18 00:18:46 +01001707 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001708
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001709 psa_set_key_usage_flags( &attributes, policy_usage );
1710 psa_set_key_algorithm( &attributes, policy_alg );
1711 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001712
Gilles Peskine049c7532019-05-15 20:22:09 +02001713 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1714 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001715
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001716 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001717 if( policy_alg == exercise_alg &&
1718 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001719 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001720 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001721 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001722 psa_cipher_abort( &operation );
1723
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001724 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001725 if( policy_alg == exercise_alg &&
1726 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001727 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001728 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001729 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001730
1731exit:
1732 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001733 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001734 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001735}
1736/* END_CASE */
1737
1738/* BEGIN_CASE */
1739void aead_key_policy( int policy_usage,
1740 int policy_alg,
1741 int key_type,
1742 data_t *key_data,
1743 int nonce_length_arg,
1744 int tag_length_arg,
1745 int exercise_alg )
1746{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001747 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001748 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001749 psa_status_t status;
1750 unsigned char nonce[16] = {0};
1751 size_t nonce_length = nonce_length_arg;
1752 unsigned char tag[16];
1753 size_t tag_length = tag_length_arg;
1754 size_t output_length;
1755
1756 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1757 TEST_ASSERT( tag_length <= sizeof( tag ) );
1758
Gilles Peskine8817f612018-12-18 00:18:46 +01001759 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001760
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001761 psa_set_key_usage_flags( &attributes, policy_usage );
1762 psa_set_key_algorithm( &attributes, policy_alg );
1763 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001764
Gilles Peskine049c7532019-05-15 20:22:09 +02001765 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1766 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001768 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001769 nonce, nonce_length,
1770 NULL, 0,
1771 NULL, 0,
1772 tag, tag_length,
1773 &output_length );
1774 if( policy_alg == exercise_alg &&
1775 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001776 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001777 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001778 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001779
1780 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001781 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001782 nonce, nonce_length,
1783 NULL, 0,
1784 tag, tag_length,
1785 NULL, 0,
1786 &output_length );
1787 if( policy_alg == exercise_alg &&
1788 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001789 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001790 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001791 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001792
1793exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001794 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001795 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796}
1797/* END_CASE */
1798
1799/* BEGIN_CASE */
1800void asymmetric_encryption_key_policy( int policy_usage,
1801 int policy_alg,
1802 int key_type,
1803 data_t *key_data,
1804 int exercise_alg )
1805{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001806 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001807 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001808 psa_status_t status;
1809 size_t key_bits;
1810 size_t buffer_length;
1811 unsigned char *buffer = NULL;
1812 size_t output_length;
1813
Gilles Peskine8817f612018-12-18 00:18:46 +01001814 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001815
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001816 psa_set_key_usage_flags( &attributes, policy_usage );
1817 psa_set_key_algorithm( &attributes, policy_alg );
1818 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001819
Gilles Peskine049c7532019-05-15 20:22:09 +02001820 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1821 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001823 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1824 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001825 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1826 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001827 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001828
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001829 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001830 NULL, 0,
1831 NULL, 0,
1832 buffer, buffer_length,
1833 &output_length );
1834 if( policy_alg == exercise_alg &&
1835 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001836 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001837 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001838 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001839
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001840 if( buffer_length != 0 )
1841 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001842 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001843 buffer, buffer_length,
1844 NULL, 0,
1845 buffer, buffer_length,
1846 &output_length );
1847 if( policy_alg == exercise_alg &&
1848 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001849 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001850 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001851 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001852
1853exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001854 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001855 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001856 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001857 mbedtls_free( buffer );
1858}
1859/* END_CASE */
1860
1861/* BEGIN_CASE */
1862void asymmetric_signature_key_policy( int policy_usage,
1863 int policy_alg,
1864 int key_type,
1865 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001866 int exercise_alg,
1867 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001868{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001869 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001870 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001871 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001872 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1873 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1874 * compatible with the policy and `payload_length_arg` is supposed to be
1875 * a valid input length to sign. If `payload_length_arg <= 0`,
1876 * `exercise_alg` is supposed to be forbidden by the policy. */
1877 int compatible_alg = payload_length_arg > 0;
1878 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001879 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1880 size_t signature_length;
1881
Gilles Peskine8817f612018-12-18 00:18:46 +01001882 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001883
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001884 psa_set_key_usage_flags( &attributes, policy_usage );
1885 psa_set_key_algorithm( &attributes, policy_alg );
1886 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001887
Gilles Peskine049c7532019-05-15 20:22:09 +02001888 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1889 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001890
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001891 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001892 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001893 signature, sizeof( signature ),
1894 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001895 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001896 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001897 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001898 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001899
1900 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001901 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001902 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001903 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001904 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001905 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001906 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001907 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001908
1909exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001910 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001911 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001912}
1913/* END_CASE */
1914
Janos Follathba3fab92019-06-11 14:50:16 +01001915/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001916void derive_key_policy( int policy_usage,
1917 int policy_alg,
1918 int key_type,
1919 data_t *key_data,
1920 int exercise_alg )
1921{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001922 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001923 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001924 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001925 psa_status_t status;
1926
Gilles Peskine8817f612018-12-18 00:18:46 +01001927 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001928
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001929 psa_set_key_usage_flags( &attributes, policy_usage );
1930 psa_set_key_algorithm( &attributes, policy_alg );
1931 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001932
Gilles Peskine049c7532019-05-15 20:22:09 +02001933 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1934 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001935
Janos Follathba3fab92019-06-11 14:50:16 +01001936 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1937
1938 if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
1939 PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
Janos Follath0c1ed842019-06-28 13:35:36 +01001940 {
Janos Follathba3fab92019-06-11 14:50:16 +01001941 PSA_ASSERT( psa_key_derivation_input_bytes(
1942 &operation,
1943 PSA_KEY_DERIVATION_INPUT_SEED,
1944 (const uint8_t*) "", 0) );
Janos Follath0c1ed842019-06-28 13:35:36 +01001945 }
Janos Follathba3fab92019-06-11 14:50:16 +01001946
1947 status = psa_key_derivation_input_key( &operation,
1948 PSA_KEY_DERIVATION_INPUT_SECRET,
1949 handle );
1950
Gilles Peskineea0fb492018-07-12 17:17:20 +02001951 if( policy_alg == exercise_alg &&
1952 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001953 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001954 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001955 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001956
1957exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001958 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001959 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001960 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001961}
1962/* END_CASE */
1963
1964/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001965void agreement_key_policy( int policy_usage,
1966 int policy_alg,
1967 int key_type_arg,
1968 data_t *key_data,
1969 int exercise_alg )
1970{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001971 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001972 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001973 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001974 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001975 psa_status_t status;
1976
Gilles Peskine8817f612018-12-18 00:18:46 +01001977 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001978
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001979 psa_set_key_usage_flags( &attributes, policy_usage );
1980 psa_set_key_algorithm( &attributes, policy_alg );
1981 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001982
Gilles Peskine049c7532019-05-15 20:22:09 +02001983 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1984 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001985
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001986 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1987 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001988
Gilles Peskine01d718c2018-09-18 12:01:02 +02001989 if( policy_alg == exercise_alg &&
1990 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001991 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001992 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001993 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001994
1995exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001996 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001997 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001998 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001999}
2000/* END_CASE */
2001
2002/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002003void key_policy_alg2( int key_type_arg, data_t *key_data,
2004 int usage_arg, int alg_arg, int alg2_arg )
2005{
2006 psa_key_handle_t handle = 0;
2007 psa_key_type_t key_type = key_type_arg;
2008 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
2009 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
2010 psa_key_usage_t usage = usage_arg;
2011 psa_algorithm_t alg = alg_arg;
2012 psa_algorithm_t alg2 = alg2_arg;
2013
2014 PSA_ASSERT( psa_crypto_init( ) );
2015
2016 psa_set_key_usage_flags( &attributes, usage );
2017 psa_set_key_algorithm( &attributes, alg );
2018 psa_set_key_enrollment_algorithm( &attributes, alg2 );
2019 psa_set_key_type( &attributes, key_type );
2020 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2021 &handle ) );
2022
2023 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
2024 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
2025 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
2026 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
2027
2028 if( ! exercise_key( handle, usage, alg ) )
2029 goto exit;
2030 if( ! exercise_key( handle, usage, alg2 ) )
2031 goto exit;
2032
2033exit:
2034 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002035 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002036}
2037/* END_CASE */
2038
2039/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002040void raw_agreement_key_policy( int policy_usage,
2041 int policy_alg,
2042 int key_type_arg,
2043 data_t *key_data,
2044 int exercise_alg )
2045{
2046 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002047 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002048 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002049 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002050 psa_status_t status;
2051
2052 PSA_ASSERT( psa_crypto_init( ) );
2053
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002054 psa_set_key_usage_flags( &attributes, policy_usage );
2055 psa_set_key_algorithm( &attributes, policy_alg );
2056 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002057
Gilles Peskine049c7532019-05-15 20:22:09 +02002058 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2059 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002060
2061 status = raw_key_agreement_with_self( exercise_alg, handle );
2062
2063 if( policy_alg == exercise_alg &&
2064 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
2065 PSA_ASSERT( status );
2066 else
2067 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
2068
2069exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002070 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002071 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002072 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002073}
2074/* END_CASE */
2075
2076/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002077void copy_success( int source_usage_arg,
2078 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002079 int type_arg, data_t *material,
2080 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002081 int target_usage_arg,
2082 int target_alg_arg, int target_alg2_arg,
2083 int expected_usage_arg,
2084 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01002085{
Gilles Peskineca25db92019-04-19 11:43:08 +02002086 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2087 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002088 psa_key_usage_t expected_usage = expected_usage_arg;
2089 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002090 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002091 psa_key_handle_t source_handle = 0;
2092 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002093 uint8_t *export_buffer = NULL;
2094
Gilles Peskine57ab7212019-01-28 13:03:09 +01002095 PSA_ASSERT( psa_crypto_init( ) );
2096
Gilles Peskineca25db92019-04-19 11:43:08 +02002097 /* Prepare the source key. */
2098 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2099 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002100 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002101 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002102 PSA_ASSERT( psa_import_key( &source_attributes,
2103 material->x, material->len,
2104 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002105 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002106
Gilles Peskineca25db92019-04-19 11:43:08 +02002107 /* Prepare the target attributes. */
2108 if( copy_attributes )
2109 target_attributes = source_attributes;
2110 if( target_usage_arg != -1 )
2111 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2112 if( target_alg_arg != -1 )
2113 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002114 if( target_alg2_arg != -1 )
2115 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002116
2117 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002118 PSA_ASSERT( psa_copy_key( source_handle,
2119 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002120
2121 /* Destroy the source to ensure that this doesn't affect the target. */
2122 PSA_ASSERT( psa_destroy_key( source_handle ) );
2123
2124 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002125 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2126 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2127 psa_get_key_type( &target_attributes ) );
2128 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2129 psa_get_key_bits( &target_attributes ) );
2130 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2131 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002132 TEST_EQUAL( expected_alg2,
2133 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002134 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2135 {
2136 size_t length;
2137 ASSERT_ALLOC( export_buffer, material->len );
2138 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2139 material->len, &length ) );
2140 ASSERT_COMPARE( material->x, material->len,
2141 export_buffer, length );
2142 }
2143 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2144 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002145 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2146 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002147
2148 PSA_ASSERT( psa_close_key( target_handle ) );
2149
2150exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002151 psa_reset_key_attributes( &source_attributes );
2152 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002153 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002154 mbedtls_free( export_buffer );
2155}
2156/* END_CASE */
2157
2158/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002159void copy_fail( int source_usage_arg,
2160 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002161 int type_arg, data_t *material,
2162 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002163 int target_usage_arg,
2164 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002165 int expected_status_arg )
2166{
2167 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2168 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2169 psa_key_handle_t source_handle = 0;
2170 psa_key_handle_t target_handle = 0;
2171
2172 PSA_ASSERT( psa_crypto_init( ) );
2173
2174 /* Prepare the source key. */
2175 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2176 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002177 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002178 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002179 PSA_ASSERT( psa_import_key( &source_attributes,
2180 material->x, material->len,
2181 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002182
2183 /* Prepare the target attributes. */
2184 psa_set_key_type( &target_attributes, target_type_arg );
2185 psa_set_key_bits( &target_attributes, target_bits_arg );
2186 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2187 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002188 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002189
2190 /* Try to copy the key. */
2191 TEST_EQUAL( psa_copy_key( source_handle,
2192 &target_attributes, &target_handle ),
2193 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002194
2195 PSA_ASSERT( psa_destroy_key( source_handle ) );
2196
Gilles Peskine4a644642019-05-03 17:14:08 +02002197exit:
2198 psa_reset_key_attributes( &source_attributes );
2199 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002200 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002201}
2202/* END_CASE */
2203
2204/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002205void hash_operation_init( )
2206{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002207 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002208 /* Test each valid way of initializing the object, except for `= {0}`, as
2209 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2210 * though it's OK by the C standard. We could test for this, but we'd need
2211 * to supress the Clang warning for the test. */
2212 psa_hash_operation_t func = psa_hash_operation_init( );
2213 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2214 psa_hash_operation_t zero;
2215
2216 memset( &zero, 0, sizeof( zero ) );
2217
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002218 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002219 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2220 PSA_ERROR_BAD_STATE );
2221 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2222 PSA_ERROR_BAD_STATE );
2223 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2224 PSA_ERROR_BAD_STATE );
2225
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002226 /* A default hash operation should be abortable without error. */
2227 PSA_ASSERT( psa_hash_abort( &func ) );
2228 PSA_ASSERT( psa_hash_abort( &init ) );
2229 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002230}
2231/* END_CASE */
2232
2233/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002234void hash_setup( int alg_arg,
2235 int expected_status_arg )
2236{
2237 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002238 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002239 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002240 psa_status_t status;
2241
Gilles Peskine8817f612018-12-18 00:18:46 +01002242 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002243
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002244 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002245 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002246
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002247 /* Whether setup succeeded or failed, abort must succeed. */
2248 PSA_ASSERT( psa_hash_abort( &operation ) );
2249
2250 /* If setup failed, reproduce the failure, so as to
2251 * test the resulting state of the operation object. */
2252 if( status != PSA_SUCCESS )
2253 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2254
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002255 /* Now the operation object should be reusable. */
2256#if defined(KNOWN_SUPPORTED_HASH_ALG)
2257 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2258 PSA_ASSERT( psa_hash_abort( &operation ) );
2259#endif
2260
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002261exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002262 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002263}
2264/* END_CASE */
2265
2266/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002267void hash_bad_order( )
2268{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002269 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002270 unsigned char input[] = "";
2271 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002272 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002273 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2274 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2275 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002276 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002277 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002278 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002279
Gilles Peskine8817f612018-12-18 00:18:46 +01002280 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002281
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002282 /* Call setup twice in a row. */
2283 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2284 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2285 PSA_ERROR_BAD_STATE );
2286 PSA_ASSERT( psa_hash_abort( &operation ) );
2287
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002288 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002289 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002290 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002291 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002292
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002293 /* Call update after finish. */
2294 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2295 PSA_ASSERT( psa_hash_finish( &operation,
2296 hash, sizeof( hash ), &hash_len ) );
2297 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002298 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002299 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002300
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002301 /* Call verify without calling setup beforehand. */
2302 TEST_EQUAL( psa_hash_verify( &operation,
2303 valid_hash, sizeof( valid_hash ) ),
2304 PSA_ERROR_BAD_STATE );
2305 PSA_ASSERT( psa_hash_abort( &operation ) );
2306
2307 /* Call verify after finish. */
2308 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2309 PSA_ASSERT( psa_hash_finish( &operation,
2310 hash, sizeof( hash ), &hash_len ) );
2311 TEST_EQUAL( psa_hash_verify( &operation,
2312 valid_hash, sizeof( valid_hash ) ),
2313 PSA_ERROR_BAD_STATE );
2314 PSA_ASSERT( psa_hash_abort( &operation ) );
2315
2316 /* Call verify twice in a row. */
2317 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2318 PSA_ASSERT( psa_hash_verify( &operation,
2319 valid_hash, sizeof( valid_hash ) ) );
2320 TEST_EQUAL( psa_hash_verify( &operation,
2321 valid_hash, sizeof( valid_hash ) ),
2322 PSA_ERROR_BAD_STATE );
2323 PSA_ASSERT( psa_hash_abort( &operation ) );
2324
2325 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002326 TEST_EQUAL( psa_hash_finish( &operation,
2327 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002328 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002329 PSA_ASSERT( psa_hash_abort( &operation ) );
2330
2331 /* Call finish twice in a row. */
2332 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2333 PSA_ASSERT( psa_hash_finish( &operation,
2334 hash, sizeof( hash ), &hash_len ) );
2335 TEST_EQUAL( psa_hash_finish( &operation,
2336 hash, sizeof( hash ), &hash_len ),
2337 PSA_ERROR_BAD_STATE );
2338 PSA_ASSERT( psa_hash_abort( &operation ) );
2339
2340 /* Call finish after calling verify. */
2341 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2342 PSA_ASSERT( psa_hash_verify( &operation,
2343 valid_hash, sizeof( valid_hash ) ) );
2344 TEST_EQUAL( psa_hash_finish( &operation,
2345 hash, sizeof( hash ), &hash_len ),
2346 PSA_ERROR_BAD_STATE );
2347 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002348
2349exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002350 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002351}
2352/* END_CASE */
2353
itayzafrir27e69452018-11-01 14:26:34 +02002354/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2355void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002356{
2357 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002358 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2359 * appended to it */
2360 unsigned char hash[] = {
2361 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2362 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2363 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002364 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002365 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002366
Gilles Peskine8817f612018-12-18 00:18:46 +01002367 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002368
itayzafrir27e69452018-11-01 14:26:34 +02002369 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002370 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002371 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002372 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002373
itayzafrir27e69452018-11-01 14:26:34 +02002374 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002375 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002376 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002377 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002378
itayzafrir27e69452018-11-01 14:26:34 +02002379 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002380 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002381 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002382 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002383
itayzafrirec93d302018-10-18 18:01:10 +03002384exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002385 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002386}
2387/* END_CASE */
2388
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002389/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2390void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002391{
2392 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002393 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002394 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002395 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002396 size_t hash_len;
2397
Gilles Peskine8817f612018-12-18 00:18:46 +01002398 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002399
itayzafrir58028322018-10-25 10:22:01 +03002400 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002401 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002402 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002403 hash, expected_size - 1, &hash_len ),
2404 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002405
2406exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002407 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002408}
2409/* END_CASE */
2410
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002411/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2412void hash_clone_source_state( )
2413{
2414 psa_algorithm_t alg = PSA_ALG_SHA_256;
2415 unsigned char hash[PSA_HASH_MAX_SIZE];
2416 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2417 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2418 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2419 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2420 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2421 size_t hash_len;
2422
2423 PSA_ASSERT( psa_crypto_init( ) );
2424 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2425
2426 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2427 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2428 PSA_ASSERT( psa_hash_finish( &op_finished,
2429 hash, sizeof( hash ), &hash_len ) );
2430 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2431 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2432
2433 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2434 PSA_ERROR_BAD_STATE );
2435
2436 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2437 PSA_ASSERT( psa_hash_finish( &op_init,
2438 hash, sizeof( hash ), &hash_len ) );
2439 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2440 PSA_ASSERT( psa_hash_finish( &op_finished,
2441 hash, sizeof( hash ), &hash_len ) );
2442 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2443 PSA_ASSERT( psa_hash_finish( &op_aborted,
2444 hash, sizeof( hash ), &hash_len ) );
2445
2446exit:
2447 psa_hash_abort( &op_source );
2448 psa_hash_abort( &op_init );
2449 psa_hash_abort( &op_setup );
2450 psa_hash_abort( &op_finished );
2451 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002452 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002453}
2454/* END_CASE */
2455
2456/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2457void hash_clone_target_state( )
2458{
2459 psa_algorithm_t alg = PSA_ALG_SHA_256;
2460 unsigned char hash[PSA_HASH_MAX_SIZE];
2461 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2462 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2463 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2464 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2465 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2466 size_t hash_len;
2467
2468 PSA_ASSERT( psa_crypto_init( ) );
2469
2470 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2471 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2472 PSA_ASSERT( psa_hash_finish( &op_finished,
2473 hash, sizeof( hash ), &hash_len ) );
2474 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2475 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2476
2477 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2478 PSA_ASSERT( psa_hash_finish( &op_target,
2479 hash, sizeof( hash ), &hash_len ) );
2480
2481 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2482 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2483 PSA_ERROR_BAD_STATE );
2484 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2485 PSA_ERROR_BAD_STATE );
2486
2487exit:
2488 psa_hash_abort( &op_target );
2489 psa_hash_abort( &op_init );
2490 psa_hash_abort( &op_setup );
2491 psa_hash_abort( &op_finished );
2492 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002493 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002494}
2495/* END_CASE */
2496
itayzafrir58028322018-10-25 10:22:01 +03002497/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002498void mac_operation_init( )
2499{
Jaeden Amero252ef282019-02-15 14:05:35 +00002500 const uint8_t input[1] = { 0 };
2501
Jaeden Amero769ce272019-01-04 11:48:03 +00002502 /* Test each valid way of initializing the object, except for `= {0}`, as
2503 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2504 * though it's OK by the C standard. We could test for this, but we'd need
2505 * to supress the Clang warning for the test. */
2506 psa_mac_operation_t func = psa_mac_operation_init( );
2507 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2508 psa_mac_operation_t zero;
2509
2510 memset( &zero, 0, sizeof( zero ) );
2511
Jaeden Amero252ef282019-02-15 14:05:35 +00002512 /* A freshly-initialized MAC operation should not be usable. */
2513 TEST_EQUAL( psa_mac_update( &func,
2514 input, sizeof( input ) ),
2515 PSA_ERROR_BAD_STATE );
2516 TEST_EQUAL( psa_mac_update( &init,
2517 input, sizeof( input ) ),
2518 PSA_ERROR_BAD_STATE );
2519 TEST_EQUAL( psa_mac_update( &zero,
2520 input, sizeof( input ) ),
2521 PSA_ERROR_BAD_STATE );
2522
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002523 /* A default MAC operation should be abortable without error. */
2524 PSA_ASSERT( psa_mac_abort( &func ) );
2525 PSA_ASSERT( psa_mac_abort( &init ) );
2526 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002527}
2528/* END_CASE */
2529
2530/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002531void mac_setup( int key_type_arg,
2532 data_t *key,
2533 int alg_arg,
2534 int expected_status_arg )
2535{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002536 psa_key_type_t key_type = key_type_arg;
2537 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002538 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002539 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002540 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2541#if defined(KNOWN_SUPPORTED_MAC_ALG)
2542 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2543#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002544
Gilles Peskine8817f612018-12-18 00:18:46 +01002545 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002546
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002547 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2548 &operation, &status ) )
2549 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002550 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002551
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002552 /* The operation object should be reusable. */
2553#if defined(KNOWN_SUPPORTED_MAC_ALG)
2554 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2555 smoke_test_key_data,
2556 sizeof( smoke_test_key_data ),
2557 KNOWN_SUPPORTED_MAC_ALG,
2558 &operation, &status ) )
2559 goto exit;
2560 TEST_EQUAL( status, PSA_SUCCESS );
2561#endif
2562
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002563exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002564 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002565}
2566/* END_CASE */
2567
2568/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002569void mac_bad_order( )
2570{
2571 psa_key_handle_t handle = 0;
2572 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2573 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2574 const uint8_t key[] = {
2575 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2576 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2577 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002578 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002579 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2580 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2581 size_t sign_mac_length = 0;
2582 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2583 const uint8_t verify_mac[] = {
2584 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2585 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2586 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2587
2588 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002589 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2590 psa_set_key_algorithm( &attributes, alg );
2591 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002592
Gilles Peskine73676cb2019-05-15 20:15:10 +02002593 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002594
Jaeden Amero252ef282019-02-15 14:05:35 +00002595 /* Call update without calling setup beforehand. */
2596 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2597 PSA_ERROR_BAD_STATE );
2598 PSA_ASSERT( psa_mac_abort( &operation ) );
2599
2600 /* Call sign finish without calling setup beforehand. */
2601 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2602 &sign_mac_length),
2603 PSA_ERROR_BAD_STATE );
2604 PSA_ASSERT( psa_mac_abort( &operation ) );
2605
2606 /* Call verify finish without calling setup beforehand. */
2607 TEST_EQUAL( psa_mac_verify_finish( &operation,
2608 verify_mac, sizeof( verify_mac ) ),
2609 PSA_ERROR_BAD_STATE );
2610 PSA_ASSERT( psa_mac_abort( &operation ) );
2611
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002612 /* Call setup twice in a row. */
2613 PSA_ASSERT( psa_mac_sign_setup( &operation,
2614 handle, alg ) );
2615 TEST_EQUAL( psa_mac_sign_setup( &operation,
2616 handle, alg ),
2617 PSA_ERROR_BAD_STATE );
2618 PSA_ASSERT( psa_mac_abort( &operation ) );
2619
Jaeden Amero252ef282019-02-15 14:05:35 +00002620 /* Call update after sign finish. */
2621 PSA_ASSERT( psa_mac_sign_setup( &operation,
2622 handle, alg ) );
2623 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2624 PSA_ASSERT( psa_mac_sign_finish( &operation,
2625 sign_mac, sizeof( sign_mac ),
2626 &sign_mac_length ) );
2627 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2628 PSA_ERROR_BAD_STATE );
2629 PSA_ASSERT( psa_mac_abort( &operation ) );
2630
2631 /* Call update after verify finish. */
2632 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002633 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002634 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2635 PSA_ASSERT( psa_mac_verify_finish( &operation,
2636 verify_mac, sizeof( verify_mac ) ) );
2637 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2638 PSA_ERROR_BAD_STATE );
2639 PSA_ASSERT( psa_mac_abort( &operation ) );
2640
2641 /* Call sign finish twice in a row. */
2642 PSA_ASSERT( psa_mac_sign_setup( &operation,
2643 handle, alg ) );
2644 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2645 PSA_ASSERT( psa_mac_sign_finish( &operation,
2646 sign_mac, sizeof( sign_mac ),
2647 &sign_mac_length ) );
2648 TEST_EQUAL( psa_mac_sign_finish( &operation,
2649 sign_mac, sizeof( sign_mac ),
2650 &sign_mac_length ),
2651 PSA_ERROR_BAD_STATE );
2652 PSA_ASSERT( psa_mac_abort( &operation ) );
2653
2654 /* Call verify finish twice in a row. */
2655 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002656 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002657 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2658 PSA_ASSERT( psa_mac_verify_finish( &operation,
2659 verify_mac, sizeof( verify_mac ) ) );
2660 TEST_EQUAL( psa_mac_verify_finish( &operation,
2661 verify_mac, sizeof( verify_mac ) ),
2662 PSA_ERROR_BAD_STATE );
2663 PSA_ASSERT( psa_mac_abort( &operation ) );
2664
2665 /* Setup sign but try verify. */
2666 PSA_ASSERT( psa_mac_sign_setup( &operation,
2667 handle, alg ) );
2668 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2669 TEST_EQUAL( psa_mac_verify_finish( &operation,
2670 verify_mac, sizeof( verify_mac ) ),
2671 PSA_ERROR_BAD_STATE );
2672 PSA_ASSERT( psa_mac_abort( &operation ) );
2673
2674 /* Setup verify but try sign. */
2675 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002676 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002677 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2678 TEST_EQUAL( psa_mac_sign_finish( &operation,
2679 sign_mac, sizeof( sign_mac ),
2680 &sign_mac_length ),
2681 PSA_ERROR_BAD_STATE );
2682 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002683
Gilles Peskine76b29a72019-05-28 14:08:50 +02002684 PSA_ASSERT( psa_destroy_key( handle ) );
2685
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002686exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002687 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002688}
2689/* END_CASE */
2690
2691/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002692void mac_sign( int key_type_arg,
2693 data_t *key,
2694 int alg_arg,
2695 data_t *input,
2696 data_t *expected_mac )
2697{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002698 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002699 psa_key_type_t key_type = key_type_arg;
2700 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002701 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002702 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002703 /* Leave a little extra room in the output buffer. At the end of the
2704 * test, we'll check that the implementation didn't overwrite onto
2705 * this extra room. */
2706 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2707 size_t mac_buffer_size =
2708 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2709 size_t mac_length = 0;
2710
2711 memset( actual_mac, '+', sizeof( actual_mac ) );
2712 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2713 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2714
Gilles Peskine8817f612018-12-18 00:18:46 +01002715 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002716
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002717 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2718 psa_set_key_algorithm( &attributes, alg );
2719 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002720
Gilles Peskine73676cb2019-05-15 20:15:10 +02002721 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002722
2723 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002724 PSA_ASSERT( psa_mac_sign_setup( &operation,
2725 handle, alg ) );
2726 PSA_ASSERT( psa_mac_update( &operation,
2727 input->x, input->len ) );
2728 PSA_ASSERT( psa_mac_sign_finish( &operation,
2729 actual_mac, mac_buffer_size,
2730 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002731
2732 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002733 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2734 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002735
2736 /* Verify that the end of the buffer is untouched. */
2737 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2738 sizeof( actual_mac ) - mac_length ) );
2739
2740exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002741 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002742 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002743}
2744/* END_CASE */
2745
2746/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002747void mac_verify( int key_type_arg,
2748 data_t *key,
2749 int alg_arg,
2750 data_t *input,
2751 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002752{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002753 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002754 psa_key_type_t key_type = key_type_arg;
2755 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002756 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002757 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002758
Gilles Peskine69c12672018-06-28 00:07:19 +02002759 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2760
Gilles Peskine8817f612018-12-18 00:18:46 +01002761 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002762
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002763 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2764 psa_set_key_algorithm( &attributes, alg );
2765 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002766
Gilles Peskine73676cb2019-05-15 20:15:10 +02002767 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002768
Gilles Peskine8817f612018-12-18 00:18:46 +01002769 PSA_ASSERT( psa_mac_verify_setup( &operation,
2770 handle, alg ) );
2771 PSA_ASSERT( psa_destroy_key( handle ) );
2772 PSA_ASSERT( psa_mac_update( &operation,
2773 input->x, input->len ) );
2774 PSA_ASSERT( psa_mac_verify_finish( &operation,
2775 expected_mac->x,
2776 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002777
2778exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002779 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002780 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002781}
2782/* END_CASE */
2783
2784/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002785void cipher_operation_init( )
2786{
Jaeden Ameroab439972019-02-15 14:12:05 +00002787 const uint8_t input[1] = { 0 };
2788 unsigned char output[1] = { 0 };
2789 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002790 /* Test each valid way of initializing the object, except for `= {0}`, as
2791 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2792 * though it's OK by the C standard. We could test for this, but we'd need
2793 * to supress the Clang warning for the test. */
2794 psa_cipher_operation_t func = psa_cipher_operation_init( );
2795 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2796 psa_cipher_operation_t zero;
2797
2798 memset( &zero, 0, sizeof( zero ) );
2799
Jaeden Ameroab439972019-02-15 14:12:05 +00002800 /* A freshly-initialized cipher operation should not be usable. */
2801 TEST_EQUAL( psa_cipher_update( &func,
2802 input, sizeof( input ),
2803 output, sizeof( output ),
2804 &output_length ),
2805 PSA_ERROR_BAD_STATE );
2806 TEST_EQUAL( psa_cipher_update( &init,
2807 input, sizeof( input ),
2808 output, sizeof( output ),
2809 &output_length ),
2810 PSA_ERROR_BAD_STATE );
2811 TEST_EQUAL( psa_cipher_update( &zero,
2812 input, sizeof( input ),
2813 output, sizeof( output ),
2814 &output_length ),
2815 PSA_ERROR_BAD_STATE );
2816
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002817 /* A default cipher operation should be abortable without error. */
2818 PSA_ASSERT( psa_cipher_abort( &func ) );
2819 PSA_ASSERT( psa_cipher_abort( &init ) );
2820 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002821}
2822/* END_CASE */
2823
2824/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002825void cipher_setup( int key_type_arg,
2826 data_t *key,
2827 int alg_arg,
2828 int expected_status_arg )
2829{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002830 psa_key_type_t key_type = key_type_arg;
2831 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002832 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002833 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002834 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002835#if defined(KNOWN_SUPPORTED_MAC_ALG)
2836 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2837#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002838
Gilles Peskine8817f612018-12-18 00:18:46 +01002839 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002840
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002841 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2842 &operation, &status ) )
2843 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002844 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002845
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002846 /* The operation object should be reusable. */
2847#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2848 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2849 smoke_test_key_data,
2850 sizeof( smoke_test_key_data ),
2851 KNOWN_SUPPORTED_CIPHER_ALG,
2852 &operation, &status ) )
2853 goto exit;
2854 TEST_EQUAL( status, PSA_SUCCESS );
2855#endif
2856
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002857exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002858 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002859}
2860/* END_CASE */
2861
2862/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002863void cipher_bad_order( )
2864{
2865 psa_key_handle_t handle = 0;
2866 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2867 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002868 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002869 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2870 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2871 const uint8_t key[] = {
2872 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2873 0xaa, 0xaa, 0xaa, 0xaa };
2874 const uint8_t text[] = {
2875 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2876 0xbb, 0xbb, 0xbb, 0xbb };
2877 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2878 size_t length = 0;
2879
2880 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002881 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2882 psa_set_key_algorithm( &attributes, alg );
2883 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002884 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002885
2886
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002887 /* Call encrypt setup twice in a row. */
2888 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2889 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2890 PSA_ERROR_BAD_STATE );
2891 PSA_ASSERT( psa_cipher_abort( &operation ) );
2892
2893 /* Call decrypt setup twice in a row. */
2894 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2895 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2896 PSA_ERROR_BAD_STATE );
2897 PSA_ASSERT( psa_cipher_abort( &operation ) );
2898
Jaeden Ameroab439972019-02-15 14:12:05 +00002899 /* Generate an IV without calling setup beforehand. */
2900 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2901 buffer, sizeof( buffer ),
2902 &length ),
2903 PSA_ERROR_BAD_STATE );
2904 PSA_ASSERT( psa_cipher_abort( &operation ) );
2905
2906 /* Generate an IV twice in a row. */
2907 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2908 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2909 buffer, sizeof( buffer ),
2910 &length ) );
2911 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2912 buffer, sizeof( buffer ),
2913 &length ),
2914 PSA_ERROR_BAD_STATE );
2915 PSA_ASSERT( psa_cipher_abort( &operation ) );
2916
2917 /* Generate an IV after it's already set. */
2918 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2919 PSA_ASSERT( psa_cipher_set_iv( &operation,
2920 iv, sizeof( iv ) ) );
2921 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2922 buffer, sizeof( buffer ),
2923 &length ),
2924 PSA_ERROR_BAD_STATE );
2925 PSA_ASSERT( psa_cipher_abort( &operation ) );
2926
2927 /* Set an IV without calling setup beforehand. */
2928 TEST_EQUAL( psa_cipher_set_iv( &operation,
2929 iv, sizeof( iv ) ),
2930 PSA_ERROR_BAD_STATE );
2931 PSA_ASSERT( psa_cipher_abort( &operation ) );
2932
2933 /* Set an IV after it's already set. */
2934 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2935 PSA_ASSERT( psa_cipher_set_iv( &operation,
2936 iv, sizeof( iv ) ) );
2937 TEST_EQUAL( psa_cipher_set_iv( &operation,
2938 iv, sizeof( iv ) ),
2939 PSA_ERROR_BAD_STATE );
2940 PSA_ASSERT( psa_cipher_abort( &operation ) );
2941
2942 /* Set an IV after it's already generated. */
2943 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2944 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2945 buffer, sizeof( buffer ),
2946 &length ) );
2947 TEST_EQUAL( psa_cipher_set_iv( &operation,
2948 iv, sizeof( iv ) ),
2949 PSA_ERROR_BAD_STATE );
2950 PSA_ASSERT( psa_cipher_abort( &operation ) );
2951
2952 /* Call update without calling setup beforehand. */
2953 TEST_EQUAL( psa_cipher_update( &operation,
2954 text, sizeof( text ),
2955 buffer, sizeof( buffer ),
2956 &length ),
2957 PSA_ERROR_BAD_STATE );
2958 PSA_ASSERT( psa_cipher_abort( &operation ) );
2959
2960 /* Call update without an IV where an IV is required. */
2961 TEST_EQUAL( psa_cipher_update( &operation,
2962 text, sizeof( text ),
2963 buffer, sizeof( buffer ),
2964 &length ),
2965 PSA_ERROR_BAD_STATE );
2966 PSA_ASSERT( psa_cipher_abort( &operation ) );
2967
2968 /* Call update after finish. */
2969 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2970 PSA_ASSERT( psa_cipher_set_iv( &operation,
2971 iv, sizeof( iv ) ) );
2972 PSA_ASSERT( psa_cipher_finish( &operation,
2973 buffer, sizeof( buffer ), &length ) );
2974 TEST_EQUAL( psa_cipher_update( &operation,
2975 text, sizeof( text ),
2976 buffer, sizeof( buffer ),
2977 &length ),
2978 PSA_ERROR_BAD_STATE );
2979 PSA_ASSERT( psa_cipher_abort( &operation ) );
2980
2981 /* Call finish without calling setup beforehand. */
2982 TEST_EQUAL( psa_cipher_finish( &operation,
2983 buffer, sizeof( buffer ), &length ),
2984 PSA_ERROR_BAD_STATE );
2985 PSA_ASSERT( psa_cipher_abort( &operation ) );
2986
2987 /* Call finish without an IV where an IV is required. */
2988 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2989 /* Not calling update means we are encrypting an empty buffer, which is OK
2990 * for cipher modes with padding. */
2991 TEST_EQUAL( psa_cipher_finish( &operation,
2992 buffer, sizeof( buffer ), &length ),
2993 PSA_ERROR_BAD_STATE );
2994 PSA_ASSERT( psa_cipher_abort( &operation ) );
2995
2996 /* Call finish twice in a row. */
2997 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2998 PSA_ASSERT( psa_cipher_set_iv( &operation,
2999 iv, sizeof( iv ) ) );
3000 PSA_ASSERT( psa_cipher_finish( &operation,
3001 buffer, sizeof( buffer ), &length ) );
3002 TEST_EQUAL( psa_cipher_finish( &operation,
3003 buffer, sizeof( buffer ), &length ),
3004 PSA_ERROR_BAD_STATE );
3005 PSA_ASSERT( psa_cipher_abort( &operation ) );
3006
Gilles Peskine76b29a72019-05-28 14:08:50 +02003007 PSA_ASSERT( psa_destroy_key( handle ) );
3008
Jaeden Ameroab439972019-02-15 14:12:05 +00003009exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003010 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003011}
3012/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003013
Gilles Peskine50e586b2018-06-08 14:28:46 +02003014/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003015void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003016 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003017 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003018 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003019{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003020 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003021 psa_status_t status;
3022 psa_key_type_t key_type = key_type_arg;
3023 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003024 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003025 unsigned char *output = NULL;
3026 size_t output_buffer_size = 0;
3027 size_t function_output_length = 0;
3028 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003029 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003030 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003031
Gilles Peskine8817f612018-12-18 00:18:46 +01003032 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003033
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003034 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3035 psa_set_key_algorithm( &attributes, alg );
3036 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003037
Gilles Peskine73676cb2019-05-15 20:15:10 +02003038 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003039
Gilles Peskine8817f612018-12-18 00:18:46 +01003040 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3041 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003042
Gilles Peskine423005e2019-05-06 15:22:57 +02003043 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003044 output_buffer_size = ( (size_t) input->len +
3045 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003046 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003047
Gilles Peskine8817f612018-12-18 00:18:46 +01003048 PSA_ASSERT( psa_cipher_update( &operation,
3049 input->x, input->len,
3050 output, output_buffer_size,
3051 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003052 total_output_length += function_output_length;
3053 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003054 output + total_output_length,
3055 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003056 &function_output_length );
3057 total_output_length += function_output_length;
3058
Gilles Peskinefe11b722018-12-18 00:24:04 +01003059 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003060 if( expected_status == PSA_SUCCESS )
3061 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003062 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003063 ASSERT_COMPARE( expected_output->x, expected_output->len,
3064 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065 }
3066
3067exit:
3068 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003069 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003070 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003071}
3072/* END_CASE */
3073
3074/* BEGIN_CASE */
3075void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003076 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003077 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003078 int first_part_size_arg,
3079 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003080 data_t *expected_output )
3081{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003082 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003083 psa_key_type_t key_type = key_type_arg;
3084 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003085 size_t first_part_size = first_part_size_arg;
3086 size_t output1_length = output1_length_arg;
3087 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003088 unsigned char *output = NULL;
3089 size_t output_buffer_size = 0;
3090 size_t function_output_length = 0;
3091 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003092 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003093 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003094
Gilles Peskine8817f612018-12-18 00:18:46 +01003095 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003096
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003097 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3098 psa_set_key_algorithm( &attributes, alg );
3099 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003100
Gilles Peskine73676cb2019-05-15 20:15:10 +02003101 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003102
Gilles Peskine8817f612018-12-18 00:18:46 +01003103 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3104 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003105
Gilles Peskine423005e2019-05-06 15:22:57 +02003106 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003107 output_buffer_size = ( (size_t) input->len +
3108 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003109 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003110
Gilles Peskinee0866522019-02-19 19:44:00 +01003111 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003112 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3113 output, output_buffer_size,
3114 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003115 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003116 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003117 PSA_ASSERT( psa_cipher_update( &operation,
3118 input->x + first_part_size,
3119 input->len - first_part_size,
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 Peskinee0866522019-02-19 19:44:00 +01003123 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003124 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003125 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003126 output + total_output_length,
3127 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003128 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003129 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003130 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003131
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003132 ASSERT_COMPARE( expected_output->x, expected_output->len,
3133 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003134
3135exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003136 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003137 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003138 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003139}
3140/* END_CASE */
3141
3142/* BEGIN_CASE */
3143void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003144 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003145 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003146 int first_part_size_arg,
3147 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003148 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003149{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003150 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003151
3152 psa_key_type_t key_type = key_type_arg;
3153 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003154 size_t first_part_size = first_part_size_arg;
3155 size_t output1_length = output1_length_arg;
3156 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003157 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003158 size_t output_buffer_size = 0;
3159 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003160 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003161 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003163
Gilles Peskine8817f612018-12-18 00:18:46 +01003164 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003165
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003166 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3167 psa_set_key_algorithm( &attributes, alg );
3168 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003169
Gilles Peskine73676cb2019-05-15 20:15:10 +02003170 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003171
Gilles Peskine8817f612018-12-18 00:18:46 +01003172 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3173 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003174
Gilles Peskine423005e2019-05-06 15:22:57 +02003175 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003176
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003177 output_buffer_size = ( (size_t) input->len +
3178 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003179 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003180
Gilles Peskinee0866522019-02-19 19:44:00 +01003181 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003182 PSA_ASSERT( psa_cipher_update( &operation,
3183 input->x, first_part_size,
3184 output, output_buffer_size,
3185 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003186 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003187 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003188 PSA_ASSERT( psa_cipher_update( &operation,
3189 input->x + first_part_size,
3190 input->len - first_part_size,
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 Peskinee0866522019-02-19 19:44:00 +01003194 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003195 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003196 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003197 output + total_output_length,
3198 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003199 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003200 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003201 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003202
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003203 ASSERT_COMPARE( expected_output->x, expected_output->len,
3204 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003205
3206exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003207 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003208 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003209 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003210}
3211/* END_CASE */
3212
Gilles Peskine50e586b2018-06-08 14:28:46 +02003213/* BEGIN_CASE */
3214void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003215 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003216 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003217 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003218{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003219 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003220 psa_status_t status;
3221 psa_key_type_t key_type = key_type_arg;
3222 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003223 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003224 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003225 size_t output_buffer_size = 0;
3226 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003227 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003228 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003229 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003230
Gilles Peskine8817f612018-12-18 00:18:46 +01003231 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003232
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003233 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3234 psa_set_key_algorithm( &attributes, alg );
3235 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003236
Gilles Peskine73676cb2019-05-15 20:15:10 +02003237 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003238
Gilles Peskine8817f612018-12-18 00:18:46 +01003239 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3240 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003241
Gilles Peskine423005e2019-05-06 15:22:57 +02003242 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003243
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003244 output_buffer_size = ( (size_t) input->len +
3245 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003246 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003247
Gilles Peskine8817f612018-12-18 00:18:46 +01003248 PSA_ASSERT( psa_cipher_update( &operation,
3249 input->x, input->len,
3250 output, output_buffer_size,
3251 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003252 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003253 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003254 output + total_output_length,
3255 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003256 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003257 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003258 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003259
3260 if( expected_status == PSA_SUCCESS )
3261 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003262 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003263 ASSERT_COMPARE( expected_output->x, expected_output->len,
3264 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003265 }
3266
Gilles Peskine50e586b2018-06-08 14:28:46 +02003267exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003268 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003269 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003270 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003271}
3272/* END_CASE */
3273
Gilles Peskine50e586b2018-06-08 14:28:46 +02003274/* BEGIN_CASE */
3275void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003276 data_t *key,
3277 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003278{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003279 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003280 psa_key_type_t key_type = key_type_arg;
3281 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003282 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003283 size_t iv_size = 16;
3284 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003285 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003286 size_t output1_size = 0;
3287 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003288 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003289 size_t output2_size = 0;
3290 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003291 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003292 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3293 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003294 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003295
Gilles Peskine8817f612018-12-18 00:18:46 +01003296 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003297
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003298 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3299 psa_set_key_algorithm( &attributes, alg );
3300 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003301
Gilles Peskine73676cb2019-05-15 20:15:10 +02003302 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003303
Gilles Peskine8817f612018-12-18 00:18:46 +01003304 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3305 handle, alg ) );
3306 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3307 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003308
Gilles Peskine8817f612018-12-18 00:18:46 +01003309 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3310 iv, iv_size,
3311 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003312 output1_size = ( (size_t) input->len +
3313 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003314 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003315
Gilles Peskine8817f612018-12-18 00:18:46 +01003316 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3317 output1, output1_size,
3318 &output1_length ) );
3319 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003320 output1 + output1_length,
3321 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003322 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003323
Gilles Peskine048b7f02018-06-08 14:20:49 +02003324 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003325
Gilles Peskine8817f612018-12-18 00:18:46 +01003326 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003327
3328 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003329 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003330
Gilles Peskine8817f612018-12-18 00:18:46 +01003331 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3332 iv, iv_length ) );
3333 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3334 output2, output2_size,
3335 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003336 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003337 PSA_ASSERT( psa_cipher_finish( &operation2,
3338 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003339 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003340 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003341
Gilles Peskine048b7f02018-06-08 14:20:49 +02003342 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003343
Gilles Peskine8817f612018-12-18 00:18:46 +01003344 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003345
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003346 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003347
3348exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003349 mbedtls_free( output1 );
3350 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003351 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003352 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003353}
3354/* END_CASE */
3355
3356/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003357void cipher_verify_output_multipart( int alg_arg,
3358 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003359 data_t *key,
3360 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003361 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003362{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003363 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003364 psa_key_type_t key_type = key_type_arg;
3365 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003366 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003367 unsigned char iv[16] = {0};
3368 size_t iv_size = 16;
3369 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003370 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003371 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003372 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003373 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003374 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003375 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003376 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003377 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3378 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003379 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003380
Gilles Peskine8817f612018-12-18 00:18:46 +01003381 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003382
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003383 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3384 psa_set_key_algorithm( &attributes, alg );
3385 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003386
Gilles Peskine73676cb2019-05-15 20:15:10 +02003387 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003388
Gilles Peskine8817f612018-12-18 00:18:46 +01003389 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3390 handle, alg ) );
3391 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3392 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003393
Gilles Peskine8817f612018-12-18 00:18:46 +01003394 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3395 iv, iv_size,
3396 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003397 output1_buffer_size = ( (size_t) input->len +
3398 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003399 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003400
Gilles Peskinee0866522019-02-19 19:44:00 +01003401 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003402
Gilles Peskine8817f612018-12-18 00:18:46 +01003403 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3404 output1, output1_buffer_size,
3405 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003406 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003407
Gilles Peskine8817f612018-12-18 00:18:46 +01003408 PSA_ASSERT( psa_cipher_update( &operation1,
3409 input->x + first_part_size,
3410 input->len - first_part_size,
3411 output1, output1_buffer_size,
3412 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003413 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003414
Gilles Peskine8817f612018-12-18 00:18:46 +01003415 PSA_ASSERT( psa_cipher_finish( &operation1,
3416 output1 + output1_length,
3417 output1_buffer_size - output1_length,
3418 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003419 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003420
Gilles Peskine8817f612018-12-18 00:18:46 +01003421 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003422
Gilles Peskine048b7f02018-06-08 14:20:49 +02003423 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003424 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003425
Gilles Peskine8817f612018-12-18 00:18:46 +01003426 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3427 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003428
Gilles Peskine8817f612018-12-18 00:18:46 +01003429 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3430 output2, output2_buffer_size,
3431 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003432 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003433
Gilles Peskine8817f612018-12-18 00:18:46 +01003434 PSA_ASSERT( psa_cipher_update( &operation2,
3435 output1 + first_part_size,
3436 output1_length - first_part_size,
3437 output2, output2_buffer_size,
3438 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003439 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003440
Gilles Peskine8817f612018-12-18 00:18:46 +01003441 PSA_ASSERT( psa_cipher_finish( &operation2,
3442 output2 + output2_length,
3443 output2_buffer_size - output2_length,
3444 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003445 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003446
Gilles Peskine8817f612018-12-18 00:18:46 +01003447 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003448
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003449 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003450
3451exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003452 mbedtls_free( output1 );
3453 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003454 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003455 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003456}
3457/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003458
Gilles Peskine20035e32018-02-03 22:44:14 +01003459/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003460void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003461 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003462 data_t *nonce,
3463 data_t *additional_data,
3464 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003465 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003466{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003467 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003468 psa_key_type_t key_type = key_type_arg;
3469 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003470 unsigned char *output_data = NULL;
3471 size_t output_size = 0;
3472 size_t output_length = 0;
3473 unsigned char *output_data2 = NULL;
3474 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003475 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003476 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003477 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003478
Gilles Peskine4abf7412018-06-18 16:35:34 +02003479 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003480 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3481 * should be exact. */
3482 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3483 TEST_EQUAL( output_size,
3484 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003485 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003486
Gilles Peskine8817f612018-12-18 00:18:46 +01003487 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003489 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3490 psa_set_key_algorithm( &attributes, alg );
3491 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003492
Gilles Peskine049c7532019-05-15 20:22:09 +02003493 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3494 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003495
Gilles Peskinefe11b722018-12-18 00:24:04 +01003496 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3497 nonce->x, nonce->len,
3498 additional_data->x,
3499 additional_data->len,
3500 input_data->x, input_data->len,
3501 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003502 &output_length ),
3503 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003504
3505 if( PSA_SUCCESS == expected_result )
3506 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003507 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003508
Gilles Peskine003a4a92019-05-14 16:09:40 +02003509 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3510 * should be exact. */
3511 TEST_EQUAL( input_data->len,
3512 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3513
Gilles Peskinefe11b722018-12-18 00:24:04 +01003514 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3515 nonce->x, nonce->len,
3516 additional_data->x,
3517 additional_data->len,
3518 output_data, output_length,
3519 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003520 &output_length2 ),
3521 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003522
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003523 ASSERT_COMPARE( input_data->x, input_data->len,
3524 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003525 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003526
Gilles Peskinea1cac842018-06-11 19:33:02 +02003527exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003528 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003529 mbedtls_free( output_data );
3530 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003531 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003532}
3533/* END_CASE */
3534
3535/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003536void aead_encrypt( int key_type_arg, data_t *key_data,
3537 int alg_arg,
3538 data_t *nonce,
3539 data_t *additional_data,
3540 data_t *input_data,
3541 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003542{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003543 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003544 psa_key_type_t key_type = key_type_arg;
3545 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003546 unsigned char *output_data = NULL;
3547 size_t output_size = 0;
3548 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003549 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003550 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003551
Gilles Peskine4abf7412018-06-18 16:35:34 +02003552 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003553 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3554 * should be exact. */
3555 TEST_EQUAL( output_size,
3556 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003557 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003558
Gilles Peskine8817f612018-12-18 00:18:46 +01003559 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003560
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003561 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3562 psa_set_key_algorithm( &attributes, alg );
3563 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003564
Gilles Peskine049c7532019-05-15 20:22:09 +02003565 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3566 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003567
Gilles Peskine8817f612018-12-18 00:18:46 +01003568 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3569 nonce->x, nonce->len,
3570 additional_data->x, additional_data->len,
3571 input_data->x, input_data->len,
3572 output_data, output_size,
3573 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003574
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003575 ASSERT_COMPARE( expected_result->x, expected_result->len,
3576 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003577
Gilles Peskinea1cac842018-06-11 19:33:02 +02003578exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003579 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003580 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003581 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003582}
3583/* END_CASE */
3584
3585/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003586void aead_decrypt( int key_type_arg, data_t *key_data,
3587 int alg_arg,
3588 data_t *nonce,
3589 data_t *additional_data,
3590 data_t *input_data,
3591 data_t *expected_data,
3592 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003593{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003594 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003595 psa_key_type_t key_type = key_type_arg;
3596 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003597 unsigned char *output_data = NULL;
3598 size_t output_size = 0;
3599 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003600 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003601 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003602 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003603
Gilles Peskine003a4a92019-05-14 16:09:40 +02003604 output_size = input_data->len - tag_length;
3605 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3606 * should be exact. */
3607 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3608 TEST_EQUAL( output_size,
3609 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003610 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003611
Gilles Peskine8817f612018-12-18 00:18:46 +01003612 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003613
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003614 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3615 psa_set_key_algorithm( &attributes, alg );
3616 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003617
Gilles Peskine049c7532019-05-15 20:22:09 +02003618 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3619 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003620
Gilles Peskinefe11b722018-12-18 00:24:04 +01003621 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3622 nonce->x, nonce->len,
3623 additional_data->x,
3624 additional_data->len,
3625 input_data->x, input_data->len,
3626 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003627 &output_length ),
3628 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003629
Gilles Peskine2d277862018-06-18 15:41:12 +02003630 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003631 ASSERT_COMPARE( expected_data->x, expected_data->len,
3632 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003633
Gilles Peskinea1cac842018-06-11 19:33:02 +02003634exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003635 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003636 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003637 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003638}
3639/* END_CASE */
3640
3641/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003642void signature_size( int type_arg,
3643 int bits,
3644 int alg_arg,
3645 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003646{
3647 psa_key_type_t type = type_arg;
3648 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003649 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003650 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003651exit:
3652 ;
3653}
3654/* END_CASE */
3655
3656/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003657void sign_deterministic( int key_type_arg, data_t *key_data,
3658 int alg_arg, data_t *input_data,
3659 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003660{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003661 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003662 psa_key_type_t key_type = key_type_arg;
3663 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003664 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003665 unsigned char *signature = NULL;
3666 size_t signature_size;
3667 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003668 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003669
Gilles Peskine8817f612018-12-18 00:18:46 +01003670 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003671
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003672 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3673 psa_set_key_algorithm( &attributes, alg );
3674 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003675
Gilles Peskine049c7532019-05-15 20:22:09 +02003676 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3677 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003678 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3679 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003680
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003681 /* Allocate a buffer which has the size advertized by the
3682 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003683 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3684 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003685 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003686 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003687 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003688
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003689 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003690 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3691 input_data->x, input_data->len,
3692 signature, signature_size,
3693 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003694 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003695 ASSERT_COMPARE( output_data->x, output_data->len,
3696 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003697
3698exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003699 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003700 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003701 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003702 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003703}
3704/* END_CASE */
3705
3706/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003707void sign_fail( int key_type_arg, data_t *key_data,
3708 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003709 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003710{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003711 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003712 psa_key_type_t key_type = key_type_arg;
3713 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003714 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003715 psa_status_t actual_status;
3716 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003717 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003718 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003719 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003720
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003721 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003722
Gilles Peskine8817f612018-12-18 00:18:46 +01003723 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003724
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003725 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3726 psa_set_key_algorithm( &attributes, alg );
3727 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003728
Gilles Peskine049c7532019-05-15 20:22:09 +02003729 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3730 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003731
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003732 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003733 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003734 signature, signature_size,
3735 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003736 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003737 /* The value of *signature_length is unspecified on error, but
3738 * whatever it is, it should be less than signature_size, so that
3739 * if the caller tries to read *signature_length bytes without
3740 * checking the error code then they don't overflow a buffer. */
3741 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003742
3743exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003744 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003745 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003746 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003747 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003748}
3749/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003750
3751/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003752void sign_verify( int key_type_arg, data_t *key_data,
3753 int alg_arg, data_t *input_data )
3754{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003755 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003756 psa_key_type_t key_type = key_type_arg;
3757 psa_algorithm_t alg = alg_arg;
3758 size_t key_bits;
3759 unsigned char *signature = NULL;
3760 size_t signature_size;
3761 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003762 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003763
Gilles Peskine8817f612018-12-18 00:18:46 +01003764 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003765
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003766 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3767 psa_set_key_algorithm( &attributes, alg );
3768 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003769
Gilles Peskine049c7532019-05-15 20:22:09 +02003770 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3771 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003772 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3773 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003774
3775 /* Allocate a buffer which has the size advertized by the
3776 * library. */
3777 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3778 key_bits, alg );
3779 TEST_ASSERT( signature_size != 0 );
3780 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003781 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003782
3783 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003784 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3785 input_data->x, input_data->len,
3786 signature, signature_size,
3787 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003788 /* Check that the signature length looks sensible. */
3789 TEST_ASSERT( signature_length <= signature_size );
3790 TEST_ASSERT( signature_length > 0 );
3791
3792 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003793 PSA_ASSERT( psa_asymmetric_verify(
3794 handle, alg,
3795 input_data->x, input_data->len,
3796 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003797
3798 if( input_data->len != 0 )
3799 {
3800 /* Flip a bit in the input and verify that the signature is now
3801 * detected as invalid. Flip a bit at the beginning, not at the end,
3802 * because ECDSA may ignore the last few bits of the input. */
3803 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003804 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3805 input_data->x, input_data->len,
3806 signature, signature_length ),
3807 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003808 }
3809
3810exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003811 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003812 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003813 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003814 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003815}
3816/* END_CASE */
3817
3818/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003819void asymmetric_verify( int key_type_arg, data_t *key_data,
3820 int alg_arg, data_t *hash_data,
3821 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003822{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003823 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003824 psa_key_type_t key_type = key_type_arg;
3825 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003826 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003827
Gilles Peskine69c12672018-06-28 00:07:19 +02003828 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3829
Gilles Peskine8817f612018-12-18 00:18:46 +01003830 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003831
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003832 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3833 psa_set_key_algorithm( &attributes, alg );
3834 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003835
Gilles Peskine049c7532019-05-15 20:22:09 +02003836 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3837 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003838
Gilles Peskine8817f612018-12-18 00:18:46 +01003839 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3840 hash_data->x, hash_data->len,
3841 signature_data->x,
3842 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003843exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003844 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003845 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003846 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003847}
3848/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003849
3850/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003851void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3852 int alg_arg, data_t *hash_data,
3853 data_t *signature_data,
3854 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003855{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003856 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003857 psa_key_type_t key_type = key_type_arg;
3858 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003859 psa_status_t actual_status;
3860 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003861 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003862
Gilles Peskine8817f612018-12-18 00:18:46 +01003863 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003864
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003865 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3866 psa_set_key_algorithm( &attributes, alg );
3867 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003868
Gilles Peskine049c7532019-05-15 20:22:09 +02003869 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3870 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003872 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003873 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003874 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003875 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876
Gilles Peskinefe11b722018-12-18 00:24:04 +01003877 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003878
3879exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003880 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003881 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003882 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883}
3884/* END_CASE */
3885
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003886/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003887void asymmetric_encrypt( int key_type_arg,
3888 data_t *key_data,
3889 int alg_arg,
3890 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003891 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003892 int expected_output_length_arg,
3893 int expected_status_arg )
3894{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003895 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003896 psa_key_type_t key_type = key_type_arg;
3897 psa_algorithm_t alg = alg_arg;
3898 size_t expected_output_length = expected_output_length_arg;
3899 size_t key_bits;
3900 unsigned char *output = NULL;
3901 size_t output_size;
3902 size_t output_length = ~0;
3903 psa_status_t actual_status;
3904 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003905 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003906
Gilles Peskine8817f612018-12-18 00:18:46 +01003907 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003908
Gilles Peskine656896e2018-06-29 19:12:28 +02003909 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003910 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3911 psa_set_key_algorithm( &attributes, alg );
3912 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003913 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3914 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003915
3916 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003917 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3918 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003919 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003920 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003921
3922 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003923 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003924 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003925 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003926 output, output_size,
3927 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003928 TEST_EQUAL( actual_status, expected_status );
3929 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003930
Gilles Peskine68428122018-06-30 18:42:41 +02003931 /* If the label is empty, the test framework puts a non-null pointer
3932 * in label->x. Test that a null pointer works as well. */
3933 if( label->len == 0 )
3934 {
3935 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003936 if( output_size != 0 )
3937 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003938 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003939 input_data->x, input_data->len,
3940 NULL, label->len,
3941 output, output_size,
3942 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003943 TEST_EQUAL( actual_status, expected_status );
3944 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003945 }
3946
Gilles Peskine656896e2018-06-29 19:12:28 +02003947exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003948 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003949 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003950 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003951 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02003952}
3953/* END_CASE */
3954
3955/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003956void asymmetric_encrypt_decrypt( int key_type_arg,
3957 data_t *key_data,
3958 int alg_arg,
3959 data_t *input_data,
3960 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003961{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003962 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003963 psa_key_type_t key_type = key_type_arg;
3964 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003965 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003966 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003967 size_t output_size;
3968 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003969 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003970 size_t output2_size;
3971 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003972 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003973
Gilles Peskine8817f612018-12-18 00:18:46 +01003974 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003975
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003976 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3977 psa_set_key_algorithm( &attributes, alg );
3978 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003979
Gilles Peskine049c7532019-05-15 20:22:09 +02003980 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3981 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003982
3983 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003984 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3985 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003986 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003987 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003988 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003989 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003990
Gilles Peskineeebd7382018-06-08 18:11:54 +02003991 /* We test encryption by checking that encrypt-then-decrypt gives back
3992 * the original plaintext because of the non-optional random
3993 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003994 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3995 input_data->x, input_data->len,
3996 label->x, label->len,
3997 output, output_size,
3998 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003999 /* We don't know what ciphertext length to expect, but check that
4000 * it looks sensible. */
4001 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03004002
Gilles Peskine8817f612018-12-18 00:18:46 +01004003 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4004 output, output_length,
4005 label->x, label->len,
4006 output2, output2_size,
4007 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004008 ASSERT_COMPARE( input_data->x, input_data->len,
4009 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004010
4011exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004012 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004013 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004014 mbedtls_free( output );
4015 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004016 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004017}
4018/* END_CASE */
4019
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004020/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004021void asymmetric_decrypt( int key_type_arg,
4022 data_t *key_data,
4023 int alg_arg,
4024 data_t *input_data,
4025 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02004026 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004027{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004028 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004029 psa_key_type_t key_type = key_type_arg;
4030 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004031 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03004032 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004033 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004034 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004035
Jaeden Amero412654a2019-02-06 12:57:46 +00004036 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004037 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004038
Gilles Peskine8817f612018-12-18 00:18:46 +01004039 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004040
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004041 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4042 psa_set_key_algorithm( &attributes, alg );
4043 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004044
Gilles Peskine049c7532019-05-15 20:22:09 +02004045 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4046 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004047
Gilles Peskine8817f612018-12-18 00:18:46 +01004048 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4049 input_data->x, input_data->len,
4050 label->x, label->len,
4051 output,
4052 output_size,
4053 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004054 ASSERT_COMPARE( expected_data->x, expected_data->len,
4055 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004056
Gilles Peskine68428122018-06-30 18:42:41 +02004057 /* If the label is empty, the test framework puts a non-null pointer
4058 * in label->x. Test that a null pointer works as well. */
4059 if( label->len == 0 )
4060 {
4061 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004062 if( output_size != 0 )
4063 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004064 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4065 input_data->x, input_data->len,
4066 NULL, label->len,
4067 output,
4068 output_size,
4069 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004070 ASSERT_COMPARE( expected_data->x, expected_data->len,
4071 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004072 }
4073
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004074exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004075 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004076 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004077 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004078 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004079}
4080/* END_CASE */
4081
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004082/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004083void asymmetric_decrypt_fail( int key_type_arg,
4084 data_t *key_data,
4085 int alg_arg,
4086 data_t *input_data,
4087 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00004088 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02004089 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004090{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004091 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004092 psa_key_type_t key_type = key_type_arg;
4093 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004094 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004095 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004096 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004097 psa_status_t actual_status;
4098 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004099 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004100
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004101 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004102
Gilles Peskine8817f612018-12-18 00:18:46 +01004103 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004104
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004105 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4106 psa_set_key_algorithm( &attributes, alg );
4107 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004108
Gilles Peskine049c7532019-05-15 20:22:09 +02004109 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4110 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004111
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004112 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004113 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004114 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004115 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004116 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004117 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004118 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004119
Gilles Peskine68428122018-06-30 18:42:41 +02004120 /* If the label is empty, the test framework puts a non-null pointer
4121 * in label->x. Test that a null pointer works as well. */
4122 if( label->len == 0 )
4123 {
4124 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004125 if( output_size != 0 )
4126 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004127 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004128 input_data->x, input_data->len,
4129 NULL, label->len,
4130 output, output_size,
4131 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004132 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004133 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004134 }
4135
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004136exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004137 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004138 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004139 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004140 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004141}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004142/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004143
4144/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004145void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004146{
4147 /* Test each valid way of initializing the object, except for `= {0}`, as
4148 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4149 * though it's OK by the C standard. We could test for this, but we'd need
4150 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004151 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004152 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4153 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4154 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004155
4156 memset( &zero, 0, sizeof( zero ) );
4157
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004158 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004159 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004160 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004161 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004162 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004163 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004164 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004165
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004166 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004167 PSA_ASSERT( psa_key_derivation_abort(&func) );
4168 PSA_ASSERT( psa_key_derivation_abort(&init) );
4169 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004170}
4171/* END_CASE */
4172
Janos Follath16de4a42019-06-13 16:32:24 +01004173/* BEGIN_CASE */
4174void derive_setup( int alg_arg, int expected_status_arg )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004175{
Gilles Peskineea0fb492018-07-12 17:17:20 +02004176 psa_algorithm_t alg = alg_arg;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004177 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004178 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004179
Gilles Peskine8817f612018-12-18 00:18:46 +01004180 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004181
Janos Follath16de4a42019-06-13 16:32:24 +01004182 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004183 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004184
4185exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004186 psa_key_derivation_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004187 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004188}
4189/* END_CASE */
4190
Janos Follathaf3c2a02019-06-12 12:34:34 +01004191/* BEGIN_CASE */
Janos Follatha27c9272019-06-14 09:59:36 +01004192void derive_set_capacity( int alg_arg, int capacity_arg,
4193 int expected_status_arg )
4194{
4195 psa_algorithm_t alg = alg_arg;
4196 size_t capacity = capacity_arg;
4197 psa_status_t expected_status = expected_status_arg;
4198 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4199
4200 PSA_ASSERT( psa_crypto_init( ) );
4201
4202 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4203
4204 TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
4205 expected_status );
4206
4207exit:
4208 psa_key_derivation_abort( &operation );
4209 PSA_DONE( );
4210}
4211/* END_CASE */
4212
4213/* BEGIN_CASE */
Janos Follathaf3c2a02019-06-12 12:34:34 +01004214void derive_input( int alg_arg,
4215 int key_type_arg,
4216 int step1_arg, data_t *input1,
4217 int step2_arg, data_t *input2,
4218 int step3_arg, data_t *input3,
4219 int expected_status_arg1,
4220 int expected_status_arg2,
4221 int expected_status_arg3 )
4222{
4223 psa_algorithm_t alg = alg_arg;
4224 size_t key_type = key_type_arg;
4225 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4226 psa_status_t expected_statuses[] = {expected_status_arg1,
4227 expected_status_arg2,
4228 expected_status_arg3};
4229 data_t *inputs[] = {input1, input2, input3};
4230 psa_key_handle_t handles[] = {0, 0, 0};
4231 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4232 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4233 size_t i;
4234
4235 PSA_ASSERT( psa_crypto_init( ) );
4236
4237 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4238 psa_set_key_algorithm( &attributes, alg );
4239 psa_set_key_type( &attributes, key_type );
4240
4241 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4242
4243 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
4244 {
4245 switch( steps[i] )
4246 {
4247 case PSA_KEY_DERIVATION_INPUT_SECRET:
4248 PSA_ASSERT( psa_import_key( &attributes,
4249 inputs[i]->x, inputs[i]->len,
4250 &handles[i] ) );
4251 TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
4252 handles[i] ),
4253 expected_statuses[i] );
4254 break;
4255 default:
4256 TEST_EQUAL( psa_key_derivation_input_bytes(
4257 &operation, steps[i],
4258 inputs[i]->x, inputs[i]->len ),
4259 expected_statuses[i] );
4260 break;
4261 }
4262 }
4263
4264exit:
4265 psa_key_derivation_abort( &operation );
4266 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4267 psa_destroy_key( handles[i] );
4268 PSA_DONE( );
4269}
4270/* END_CASE */
4271
Janos Follathd958bb72019-07-03 15:02:16 +01004272/* BEGIN_CASE */
4273void test_derive_invalid_key_derivation_state( int alg_arg )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004274{
Janos Follathd958bb72019-07-03 15:02:16 +01004275 psa_algorithm_t alg = alg_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004276 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004277 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004278 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathd958bb72019-07-03 15:02:16 +01004279 unsigned char input1[] = "Input 1";
4280 size_t input1_length = sizeof( input1 );
4281 unsigned char input2[] = "Input 2";
4282 size_t input2_length = sizeof( input2 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004283 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004284 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004285 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4286 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4287 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004288 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004289
Gilles Peskine8817f612018-12-18 00:18:46 +01004290 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004291
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004292 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4293 psa_set_key_algorithm( &attributes, alg );
4294 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004295
Gilles Peskine73676cb2019-05-15 20:15:10 +02004296 PSA_ASSERT( psa_import_key( &attributes,
4297 key_data, sizeof( key_data ),
4298 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004299
4300 /* valid key derivation */
Janos Follathd958bb72019-07-03 15:02:16 +01004301 if( !setup_key_derivation_wrap( &operation, handle, alg,
4302 input1, input1_length,
4303 input2, input2_length,
4304 capacity ) )
4305 goto exit;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004306
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004307 /* state of operation shouldn't allow additional generation */
Janos Follathd958bb72019-07-03 15:02:16 +01004308 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004309 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004310
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004311 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004312
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004313 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004314 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004315
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004316exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004317 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004318 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004319 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004320}
4321/* END_CASE */
4322
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004323/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004324void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004325{
4326 uint8_t output_buffer[16];
4327 size_t buffer_size = 16;
4328 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004329 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004330
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004331 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4332 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004333 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004334
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004335 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
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 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004339
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004340 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4341 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004342 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004343
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004344 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004345 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004346
4347exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004348 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004349}
4350/* END_CASE */
4351
4352/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004353void derive_output( int alg_arg,
Gilles Peskine1468da72019-05-29 17:35:49 +02004354 int step1_arg, data_t *input1,
4355 int step2_arg, data_t *input2,
4356 int step3_arg, data_t *input3,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004357 int requested_capacity_arg,
4358 data_t *expected_output1,
4359 data_t *expected_output2 )
4360{
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004361 psa_algorithm_t alg = alg_arg;
Gilles Peskine1468da72019-05-29 17:35:49 +02004362 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4363 data_t *inputs[] = {input1, input2, input3};
4364 psa_key_handle_t handles[] = {0, 0, 0};
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004365 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004366 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004367 uint8_t *expected_outputs[2] =
4368 {expected_output1->x, expected_output2->x};
4369 size_t output_sizes[2] =
4370 {expected_output1->len, expected_output2->len};
4371 size_t output_buffer_size = 0;
4372 uint8_t *output_buffer = NULL;
4373 size_t expected_capacity;
4374 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004375 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004376 psa_status_t status;
Gilles Peskine1468da72019-05-29 17:35:49 +02004377 size_t i;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004378
4379 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4380 {
4381 if( output_sizes[i] > output_buffer_size )
4382 output_buffer_size = output_sizes[i];
4383 if( output_sizes[i] == 0 )
4384 expected_outputs[i] = NULL;
4385 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004386 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004387 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004388
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004389 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4390 psa_set_key_algorithm( &attributes, alg );
4391 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004392
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004393 /* Extraction phase. */
Gilles Peskine1468da72019-05-29 17:35:49 +02004394 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4395 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4396 requested_capacity ) );
4397 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004398 {
Gilles Peskine1468da72019-05-29 17:35:49 +02004399 switch( steps[i] )
4400 {
4401 case 0:
4402 break;
4403 case PSA_KEY_DERIVATION_INPUT_SECRET:
4404 PSA_ASSERT( psa_import_key( &attributes,
4405 inputs[i]->x, inputs[i]->len,
4406 &handles[i] ) );
4407 PSA_ASSERT( psa_key_derivation_input_key(
4408 &operation, steps[i],
4409 handles[i] ) );
4410 break;
4411 default:
4412 PSA_ASSERT( psa_key_derivation_input_bytes(
4413 &operation, steps[i],
4414 inputs[i]->x, inputs[i]->len ) );
4415 break;
4416 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004417 }
Gilles Peskine1468da72019-05-29 17:35:49 +02004418
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004419 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004420 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004421 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004422 expected_capacity = requested_capacity;
4423
4424 /* Expansion phase. */
4425 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4426 {
4427 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004428 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004429 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004430 if( expected_capacity == 0 && output_sizes[i] == 0 )
4431 {
4432 /* Reading 0 bytes when 0 bytes are available can go either way. */
4433 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004434 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004435 continue;
4436 }
4437 else if( expected_capacity == 0 ||
4438 output_sizes[i] > expected_capacity )
4439 {
4440 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004441 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004442 expected_capacity = 0;
4443 continue;
4444 }
4445 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004446 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004447 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004448 ASSERT_COMPARE( output_buffer, output_sizes[i],
4449 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004450 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004451 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004452 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004453 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004454 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004455 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004456 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004457
4458exit:
4459 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004460 psa_key_derivation_abort( &operation );
Gilles Peskine1468da72019-05-29 17:35:49 +02004461 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4462 psa_destroy_key( handles[i] );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004463 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004464}
4465/* END_CASE */
4466
4467/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004468void derive_full( int alg_arg,
4469 data_t *key_data,
Janos Follath47f27ed2019-06-25 13:24:52 +01004470 data_t *input1,
4471 data_t *input2,
Gilles Peskined54931c2018-07-17 21:06:59 +02004472 int requested_capacity_arg )
4473{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004474 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004475 psa_algorithm_t alg = alg_arg;
4476 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004477 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004478 unsigned char output_buffer[16];
4479 size_t expected_capacity = requested_capacity;
4480 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004481 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004482
Gilles Peskine8817f612018-12-18 00:18:46 +01004483 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004484
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004485 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4486 psa_set_key_algorithm( &attributes, alg );
4487 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004488
Gilles Peskine049c7532019-05-15 20:22:09 +02004489 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4490 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004491
Janos Follathf2815ea2019-07-03 12:41:36 +01004492 if( !setup_key_derivation_wrap( &operation, handle, alg,
4493 input1->x, input1->len,
4494 input2->x, input2->len,
4495 requested_capacity ) )
4496 goto exit;
Janos Follath47f27ed2019-06-25 13:24:52 +01004497
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004498 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004499 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004500 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004501
4502 /* Expansion phase. */
4503 while( current_capacity > 0 )
4504 {
4505 size_t read_size = sizeof( output_buffer );
4506 if( read_size > current_capacity )
4507 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004508 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004509 output_buffer,
4510 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004511 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004512 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004513 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004514 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004515 }
4516
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004517 /* Check that the operation refuses to go over capacity. */
4518 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004519 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004520
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004521 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004522
4523exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004524 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004525 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004526 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004527}
4528/* END_CASE */
4529
Janos Follathe60c9052019-07-03 13:51:30 +01004530/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004531void derive_key_exercise( int alg_arg,
4532 data_t *key_data,
Janos Follathe60c9052019-07-03 13:51:30 +01004533 data_t *input1,
4534 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004535 int derived_type_arg,
4536 int derived_bits_arg,
4537 int derived_usage_arg,
4538 int derived_alg_arg )
4539{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004540 psa_key_handle_t base_handle = 0;
4541 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004542 psa_algorithm_t alg = alg_arg;
4543 psa_key_type_t derived_type = derived_type_arg;
4544 size_t derived_bits = derived_bits_arg;
4545 psa_key_usage_t derived_usage = derived_usage_arg;
4546 psa_algorithm_t derived_alg = derived_alg_arg;
4547 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004548 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004549 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004550 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004551
Gilles Peskine8817f612018-12-18 00:18:46 +01004552 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004553
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004554 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4555 psa_set_key_algorithm( &attributes, alg );
4556 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004557 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4558 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004559
4560 /* Derive a key. */
Janos Follathe60c9052019-07-03 13:51:30 +01004561 if ( setup_key_derivation_wrap( &operation, base_handle, alg,
4562 input1->x, input1->len,
4563 input2->x, input2->len, capacity ) )
4564 goto exit;
4565
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004566 psa_set_key_usage_flags( &attributes, derived_usage );
4567 psa_set_key_algorithm( &attributes, derived_alg );
4568 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004569 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004570 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004571 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004572
4573 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004574 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4575 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4576 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004577
4578 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004579 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004580 goto exit;
4581
4582exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004583 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004584 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004585 psa_destroy_key( base_handle );
4586 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004587 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004588}
4589/* END_CASE */
4590
Janos Follath42fd8882019-07-03 14:17:09 +01004591/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004592void derive_key_export( int alg_arg,
4593 data_t *key_data,
Janos Follath42fd8882019-07-03 14:17:09 +01004594 data_t *input1,
4595 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004596 int bytes1_arg,
4597 int bytes2_arg )
4598{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004599 psa_key_handle_t base_handle = 0;
4600 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004601 psa_algorithm_t alg = alg_arg;
4602 size_t bytes1 = bytes1_arg;
4603 size_t bytes2 = bytes2_arg;
4604 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004605 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004606 uint8_t *output_buffer = NULL;
4607 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004608 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4609 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004610 size_t length;
4611
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004612 ASSERT_ALLOC( output_buffer, capacity );
4613 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004614 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004615
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004616 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4617 psa_set_key_algorithm( &base_attributes, alg );
4618 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004619 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4620 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004621
4622 /* Derive some material and output it. */
Janos Follath42fd8882019-07-03 14:17:09 +01004623 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4624 input1->x, input1->len,
4625 input2->x, input2->len, capacity ) )
4626 goto exit;
4627
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004628 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004629 output_buffer,
4630 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004631 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004632
4633 /* Derive the same output again, but this time store it in key objects. */
Janos Follath42fd8882019-07-03 14:17:09 +01004634 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4635 input1->x, input1->len,
4636 input2->x, input2->len, capacity ) )
4637 goto exit;
4638
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004639 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4640 psa_set_key_algorithm( &derived_attributes, 0 );
4641 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004642 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004643 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004644 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004645 PSA_ASSERT( psa_export_key( derived_handle,
4646 export_buffer, bytes1,
4647 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004648 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004649 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004650 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004651 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004652 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004653 PSA_ASSERT( psa_export_key( derived_handle,
4654 export_buffer + bytes1, bytes2,
4655 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004656 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004657
4658 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004659 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4660 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004661
4662exit:
4663 mbedtls_free( output_buffer );
4664 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004665 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004666 psa_destroy_key( base_handle );
4667 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004668 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004669}
4670/* END_CASE */
4671
4672/* BEGIN_CASE */
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004673void derive_key( int alg_arg,
4674 data_t *key_data, data_t *input1, data_t *input2,
4675 int type_arg, int bits_arg,
4676 int expected_status_arg )
Gilles Peskinec744d992019-07-30 17:26:54 +02004677{
4678 psa_key_handle_t base_handle = 0;
4679 psa_key_handle_t derived_handle = 0;
4680 psa_algorithm_t alg = alg_arg;
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004681 psa_key_type_t type = type_arg;
Gilles Peskinec744d992019-07-30 17:26:54 +02004682 size_t bits = bits_arg;
4683 psa_status_t expected_status = expected_status_arg;
4684 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4685 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4686 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
4687
4688 PSA_ASSERT( psa_crypto_init( ) );
4689
4690 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4691 psa_set_key_algorithm( &base_attributes, alg );
4692 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4693 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4694 &base_handle ) );
4695
4696 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4697 input1->x, input1->len,
4698 input2->x, input2->len, SIZE_MAX ) )
4699 goto exit;
4700
4701 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4702 psa_set_key_algorithm( &derived_attributes, 0 );
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004703 psa_set_key_type( &derived_attributes, type );
Gilles Peskinec744d992019-07-30 17:26:54 +02004704 psa_set_key_bits( &derived_attributes, bits );
4705 TEST_EQUAL( psa_key_derivation_output_key( &derived_attributes, &operation,
4706 &derived_handle ),
4707 expected_status );
4708
4709exit:
4710 psa_key_derivation_abort( &operation );
4711 psa_destroy_key( base_handle );
4712 psa_destroy_key( derived_handle );
4713 PSA_DONE( );
4714}
4715/* END_CASE */
4716
4717/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004718void key_agreement_setup( int alg_arg,
4719 int our_key_type_arg, data_t *our_key_data,
4720 data_t *peer_key_data,
4721 int expected_status_arg )
4722{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004723 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004724 psa_algorithm_t alg = alg_arg;
4725 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004726 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004727 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004728 psa_status_t expected_status = expected_status_arg;
4729 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004730
Gilles Peskine8817f612018-12-18 00:18:46 +01004731 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004732
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004733 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4734 psa_set_key_algorithm( &attributes, alg );
4735 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004736 PSA_ASSERT( psa_import_key( &attributes,
4737 our_key_data->x, our_key_data->len,
4738 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004739
Gilles Peskine77f40d82019-04-11 21:27:06 +02004740 /* The tests currently include inputs that should fail at either step.
4741 * Test cases that fail at the setup step should be changed to call
4742 * key_derivation_setup instead, and this function should be renamed
4743 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004744 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004745 if( status == PSA_SUCCESS )
4746 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004747 TEST_EQUAL( psa_key_derivation_key_agreement(
4748 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4749 our_key,
4750 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004751 expected_status );
4752 }
4753 else
4754 {
4755 TEST_ASSERT( status == expected_status );
4756 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004757
4758exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004759 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004760 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004761 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004762}
4763/* END_CASE */
4764
4765/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004766void raw_key_agreement( int alg_arg,
4767 int our_key_type_arg, data_t *our_key_data,
4768 data_t *peer_key_data,
4769 data_t *expected_output )
4770{
4771 psa_key_handle_t our_key = 0;
4772 psa_algorithm_t alg = alg_arg;
4773 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004774 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004775 unsigned char *output = NULL;
4776 size_t output_length = ~0;
4777
4778 ASSERT_ALLOC( output, expected_output->len );
4779 PSA_ASSERT( psa_crypto_init( ) );
4780
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004781 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4782 psa_set_key_algorithm( &attributes, alg );
4783 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004784 PSA_ASSERT( psa_import_key( &attributes,
4785 our_key_data->x, our_key_data->len,
4786 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004787
Gilles Peskinebe697d82019-05-16 18:00:41 +02004788 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4789 peer_key_data->x, peer_key_data->len,
4790 output, expected_output->len,
4791 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004792 ASSERT_COMPARE( output, output_length,
4793 expected_output->x, expected_output->len );
4794
4795exit:
4796 mbedtls_free( output );
4797 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004798 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004799}
4800/* END_CASE */
4801
4802/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004803void key_agreement_capacity( int alg_arg,
4804 int our_key_type_arg, data_t *our_key_data,
4805 data_t *peer_key_data,
4806 int expected_capacity_arg )
4807{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004808 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004809 psa_algorithm_t alg = alg_arg;
4810 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004811 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004812 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004813 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004814 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004815
Gilles Peskine8817f612018-12-18 00:18:46 +01004816 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004817
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004818 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4819 psa_set_key_algorithm( &attributes, alg );
4820 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004821 PSA_ASSERT( psa_import_key( &attributes,
4822 our_key_data->x, our_key_data->len,
4823 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004824
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004825 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004826 PSA_ASSERT( psa_key_derivation_key_agreement(
4827 &operation,
4828 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4829 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004830 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4831 {
4832 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004833 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004834 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004835 NULL, 0 ) );
4836 }
Gilles Peskine59685592018-09-18 12:11:34 +02004837
Gilles Peskinebf491972018-10-25 22:36:12 +02004838 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004839 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004840 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004841 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004842
Gilles Peskinebf491972018-10-25 22:36:12 +02004843 /* Test the actual capacity by reading the output. */
4844 while( actual_capacity > sizeof( output ) )
4845 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004846 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004847 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004848 actual_capacity -= sizeof( output );
4849 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004850 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004851 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004852 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004853 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004854
Gilles Peskine59685592018-09-18 12:11:34 +02004855exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004856 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004857 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004858 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004859}
4860/* END_CASE */
4861
4862/* BEGIN_CASE */
4863void key_agreement_output( int alg_arg,
4864 int our_key_type_arg, data_t *our_key_data,
4865 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004866 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004867{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004868 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004869 psa_algorithm_t alg = alg_arg;
4870 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004871 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004872 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004873 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004874
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004875 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4876 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004877
Gilles Peskine8817f612018-12-18 00:18:46 +01004878 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004879
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004880 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4881 psa_set_key_algorithm( &attributes, alg );
4882 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004883 PSA_ASSERT( psa_import_key( &attributes,
4884 our_key_data->x, our_key_data->len,
4885 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004886
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004887 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004888 PSA_ASSERT( psa_key_derivation_key_agreement(
4889 &operation,
4890 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4891 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004892 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4893 {
4894 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004895 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004896 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004897 NULL, 0 ) );
4898 }
Gilles Peskine59685592018-09-18 12:11:34 +02004899
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004900 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004901 actual_output,
4902 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004903 ASSERT_COMPARE( actual_output, expected_output1->len,
4904 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004905 if( expected_output2->len != 0 )
4906 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004907 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004908 actual_output,
4909 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004910 ASSERT_COMPARE( actual_output, expected_output2->len,
4911 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004912 }
Gilles Peskine59685592018-09-18 12:11:34 +02004913
4914exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004915 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004916 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004917 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004918 mbedtls_free( actual_output );
4919}
4920/* END_CASE */
4921
4922/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004923void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004924{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004925 size_t bytes = bytes_arg;
4926 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004927 unsigned char *output = NULL;
4928 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004929 size_t i;
4930 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004931
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004932 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4933 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004934 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004935
Gilles Peskine8817f612018-12-18 00:18:46 +01004936 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004937
Gilles Peskinea50d7392018-06-21 10:22:13 +02004938 /* Run several times, to ensure that every output byte will be
4939 * nonzero at least once with overwhelming probability
4940 * (2^(-8*number_of_runs)). */
4941 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004942 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004943 if( bytes != 0 )
4944 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004945 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004946
4947 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004948 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4949 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004950
4951 for( i = 0; i < bytes; i++ )
4952 {
4953 if( output[i] != 0 )
4954 ++changed[i];
4955 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004956 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004957
4958 /* Check that every byte was changed to nonzero at least once. This
4959 * validates that psa_generate_random is overwriting every byte of
4960 * the output buffer. */
4961 for( i = 0; i < bytes; i++ )
4962 {
4963 TEST_ASSERT( changed[i] != 0 );
4964 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004965
4966exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004967 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004968 mbedtls_free( output );
4969 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004970}
4971/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004972
4973/* BEGIN_CASE */
4974void generate_key( int type_arg,
4975 int bits_arg,
4976 int usage_arg,
4977 int alg_arg,
4978 int expected_status_arg )
4979{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004980 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004981 psa_key_type_t type = type_arg;
4982 psa_key_usage_t usage = usage_arg;
4983 size_t bits = bits_arg;
4984 psa_algorithm_t alg = alg_arg;
4985 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004986 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004987 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004988
Gilles Peskine8817f612018-12-18 00:18:46 +01004989 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004990
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004991 psa_set_key_usage_flags( &attributes, usage );
4992 psa_set_key_algorithm( &attributes, alg );
4993 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004994 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004995
4996 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004997 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004998 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004999 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005000
5001 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005002 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
5003 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
5004 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005005
Gilles Peskine818ca122018-06-20 18:16:48 +02005006 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005007 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02005008 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005009
5010exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005011 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005012 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005013 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005014}
5015/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03005016
Gilles Peskinee56e8782019-04-26 17:34:02 +02005017/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
5018void generate_key_rsa( int bits_arg,
5019 data_t *e_arg,
5020 int expected_status_arg )
5021{
5022 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02005023 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02005024 size_t bits = bits_arg;
5025 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
5026 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
5027 psa_status_t expected_status = expected_status_arg;
5028 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5029 uint8_t *exported = NULL;
5030 size_t exported_size =
5031 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
5032 size_t exported_length = SIZE_MAX;
5033 uint8_t *e_read_buffer = NULL;
5034 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02005035 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005036 size_t e_read_length = SIZE_MAX;
5037
5038 if( e_arg->len == 0 ||
5039 ( e_arg->len == 3 &&
5040 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
5041 {
5042 is_default_public_exponent = 1;
5043 e_read_size = 0;
5044 }
5045 ASSERT_ALLOC( e_read_buffer, e_read_size );
5046 ASSERT_ALLOC( exported, exported_size );
5047
5048 PSA_ASSERT( psa_crypto_init( ) );
5049
5050 psa_set_key_usage_flags( &attributes, usage );
5051 psa_set_key_algorithm( &attributes, alg );
5052 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
5053 e_arg->x, e_arg->len ) );
5054 psa_set_key_bits( &attributes, bits );
5055
5056 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005057 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005058 if( expected_status != PSA_SUCCESS )
5059 goto exit;
5060
5061 /* Test the key information */
5062 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5063 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5064 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5065 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
5066 e_read_buffer, e_read_size,
5067 &e_read_length ) );
5068 if( is_default_public_exponent )
5069 TEST_EQUAL( e_read_length, 0 );
5070 else
5071 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
5072
5073 /* Do something with the key according to its type and permitted usage. */
5074 if( ! exercise_key( handle, usage, alg ) )
5075 goto exit;
5076
5077 /* Export the key and check the public exponent. */
5078 PSA_ASSERT( psa_export_public_key( handle,
5079 exported, exported_size,
5080 &exported_length ) );
5081 {
5082 uint8_t *p = exported;
5083 uint8_t *end = exported + exported_length;
5084 size_t len;
5085 /* RSAPublicKey ::= SEQUENCE {
5086 * modulus INTEGER, -- n
5087 * publicExponent INTEGER } -- e
5088 */
5089 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005090 MBEDTLS_ASN1_SEQUENCE |
5091 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005092 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
5093 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
5094 MBEDTLS_ASN1_INTEGER ) );
5095 if( len >= 1 && p[0] == 0 )
5096 {
5097 ++p;
5098 --len;
5099 }
5100 if( e_arg->len == 0 )
5101 {
5102 TEST_EQUAL( len, 3 );
5103 TEST_EQUAL( p[0], 1 );
5104 TEST_EQUAL( p[1], 0 );
5105 TEST_EQUAL( p[2], 1 );
5106 }
5107 else
5108 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
5109 }
5110
5111exit:
5112 psa_reset_key_attributes( &attributes );
5113 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005114 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005115 mbedtls_free( e_read_buffer );
5116 mbedtls_free( exported );
5117}
5118/* END_CASE */
5119
Darryl Greend49a4992018-06-18 17:27:26 +01005120/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005121void persistent_key_load_key_from_storage( data_t *data,
5122 int type_arg, int bits_arg,
5123 int usage_flags_arg, int alg_arg,
5124 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01005125{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005126 psa_key_id_t key_id = 1;
5127 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005128 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005129 psa_key_handle_t base_key = 0;
5130 psa_key_type_t type = type_arg;
5131 size_t bits = bits_arg;
5132 psa_key_usage_t usage_flags = usage_flags_arg;
5133 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005134 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01005135 unsigned char *first_export = NULL;
5136 unsigned char *second_export = NULL;
5137 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
5138 size_t first_exported_length;
5139 size_t second_exported_length;
5140
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005141 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5142 {
5143 ASSERT_ALLOC( first_export, export_size );
5144 ASSERT_ALLOC( second_export, export_size );
5145 }
Darryl Greend49a4992018-06-18 17:27:26 +01005146
Gilles Peskine8817f612018-12-18 00:18:46 +01005147 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005148
Gilles Peskinec87af662019-05-15 16:12:22 +02005149 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005150 psa_set_key_usage_flags( &attributes, usage_flags );
5151 psa_set_key_algorithm( &attributes, alg );
5152 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005153 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01005154
Darryl Green0c6575a2018-11-07 16:05:30 +00005155 switch( generation_method )
5156 {
5157 case IMPORT_KEY:
5158 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02005159 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
5160 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005161 break;
Darryl Greend49a4992018-06-18 17:27:26 +01005162
Darryl Green0c6575a2018-11-07 16:05:30 +00005163 case GENERATE_KEY:
5164 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005165 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005166 break;
5167
5168 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005169 {
5170 /* Create base key */
5171 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
5172 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5173 psa_set_key_usage_flags( &base_attributes,
5174 PSA_KEY_USAGE_DERIVE );
5175 psa_set_key_algorithm( &base_attributes, derive_alg );
5176 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005177 PSA_ASSERT( psa_import_key( &base_attributes,
5178 data->x, data->len,
5179 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005180 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005181 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005182 PSA_ASSERT( psa_key_derivation_input_key(
5183 &operation,
5184 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005185 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005186 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005187 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005188 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5189 &operation,
5190 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005191 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005192 PSA_ASSERT( psa_destroy_key( base_key ) );
5193 base_key = 0;
5194 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005195 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005196 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005197 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005198
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005199 /* Export the key if permitted by the key policy. */
5200 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5201 {
5202 PSA_ASSERT( psa_export_key( handle,
5203 first_export, export_size,
5204 &first_exported_length ) );
5205 if( generation_method == IMPORT_KEY )
5206 ASSERT_COMPARE( data->x, data->len,
5207 first_export, first_exported_length );
5208 }
Darryl Greend49a4992018-06-18 17:27:26 +01005209
5210 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005211 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005212 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005213 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005214
Darryl Greend49a4992018-06-18 17:27:26 +01005215 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005216 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005217 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5218 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5219 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5220 PSA_KEY_LIFETIME_PERSISTENT );
5221 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5222 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5223 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5224 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005225
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005226 /* Export the key again if permitted by the key policy. */
5227 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005228 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005229 PSA_ASSERT( psa_export_key( handle,
5230 second_export, export_size,
5231 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005232 ASSERT_COMPARE( first_export, first_exported_length,
5233 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005234 }
5235
5236 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005237 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005238 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005239
5240exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005241 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005242 mbedtls_free( first_export );
5243 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005244 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005245 psa_destroy_key( base_key );
5246 if( handle == 0 )
5247 {
5248 /* In case there was a test failure after creating the persistent key
5249 * but while it was not open, try to re-open the persistent key
5250 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005251 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005252 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005253 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005254 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005255}
5256/* END_CASE */