blob: 8cf30c8cb95b5f28576cee88ccf29901ebb9c716 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/* BEGIN_HEADER */
itayzafrir3e02b3b2018-06-12 17:06:52 +03002#include <stdint.h>
mohammad160327010052018-07-03 13:16:15 +03003
4#if defined(MBEDTLS_PSA_CRYPTO_SPM)
5#include "spm/psa_defs.h"
6#endif
7
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02008#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02009#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +020010#include "mbedtls/oid.h"
11
Gilles Peskinee59236f2018-01-27 23:32:46 +010012#include "psa/crypto.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +030013
Jaeden Amerof24c7f82018-06-27 17:20:43 +010014/** An invalid export length that will never be set by psa_export_key(). */
15static const size_t INVALID_EXPORT_LENGTH = ~0U;
16
Gilles Peskinef426e0f2019-02-25 17:42:03 +010017/* A hash algorithm that is known to be supported.
18 *
19 * This is used in some smoke tests.
20 */
21#if defined(MBEDTLS_MD2_C)
22#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
23#elif defined(MBEDTLS_MD4_C)
24#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
25#elif defined(MBEDTLS_MD5_C)
26#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
27/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
28 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
29 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
30 * implausible anyway. */
31#elif defined(MBEDTLS_SHA1_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
33#elif defined(MBEDTLS_SHA256_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
35#elif defined(MBEDTLS_SHA512_C)
36#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
37#elif defined(MBEDTLS_SHA3_C)
38#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
39#else
40#undef KNOWN_SUPPORTED_HASH_ALG
41#endif
42
43/* A block cipher that is known to be supported.
44 *
45 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
46 */
47#if defined(MBEDTLS_AES_C)
48#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
49#elif defined(MBEDTLS_ARIA_C)
50#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
51#elif defined(MBEDTLS_CAMELLIA_C)
52#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
53#undef KNOWN_SUPPORTED_BLOCK_CIPHER
54#endif
55
56/* A MAC mode that is known to be supported.
57 *
58 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
59 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
60 *
61 * This is used in some smoke tests.
62 */
63#if defined(KNOWN_SUPPORTED_HASH_ALG)
64#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
65#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
66#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
67#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
68#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
69#else
70#undef KNOWN_SUPPORTED_MAC_ALG
71#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
72#endif
73
74/* A cipher algorithm and key type that are known to be supported.
75 *
76 * This is used in some smoke tests.
77 */
78#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
79#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
80#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
81#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
82#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
83#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
84#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
85#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
86#else
87#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
88#endif
89#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
90#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
91#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
92#elif defined(MBEDTLS_RC4_C)
93#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
94#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
95#else
96#undef KNOWN_SUPPORTED_CIPHER_ALG
97#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
98#endif
99
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200100/** Test if a buffer contains a constant byte value.
101 *
102 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200103 *
104 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200105 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 * \param size Size of the buffer in bytes.
107 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200108 * \return 1 if the buffer is all-bits-zero.
109 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200110 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200111static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200112{
113 size_t i;
114 for( i = 0; i < size; i++ )
115 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200116 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200117 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200118 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200119 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200120}
Gilles Peskine818ca122018-06-20 18:16:48 +0200121
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200122/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
123static int asn1_write_10x( unsigned char **p,
124 unsigned char *start,
125 size_t bits,
126 unsigned char x )
127{
128 int ret;
129 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200130 if( bits == 0 )
131 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
132 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200133 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300134 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200135 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
136 *p -= len;
137 ( *p )[len-1] = x;
138 if( bits % 8 == 0 )
139 ( *p )[1] |= 1;
140 else
141 ( *p )[0] |= 1 << ( bits % 8 );
142 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
143 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
144 MBEDTLS_ASN1_INTEGER ) );
145 return( len );
146}
147
148static int construct_fake_rsa_key( unsigned char *buffer,
149 size_t buffer_size,
150 unsigned char **p,
151 size_t bits,
152 int keypair )
153{
154 size_t half_bits = ( bits + 1 ) / 2;
155 int ret;
156 int len = 0;
157 /* Construct something that looks like a DER encoding of
158 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
159 * RSAPrivateKey ::= SEQUENCE {
160 * version Version,
161 * modulus INTEGER, -- n
162 * publicExponent INTEGER, -- e
163 * privateExponent INTEGER, -- d
164 * prime1 INTEGER, -- p
165 * prime2 INTEGER, -- q
166 * exponent1 INTEGER, -- d mod (p-1)
167 * exponent2 INTEGER, -- d mod (q-1)
168 * coefficient INTEGER, -- (inverse of q) mod p
169 * otherPrimeInfos OtherPrimeInfos OPTIONAL
170 * }
171 * Or, for a public key, the same structure with only
172 * version, modulus and publicExponent.
173 */
174 *p = buffer + buffer_size;
175 if( keypair )
176 {
177 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
178 asn1_write_10x( p, buffer, half_bits, 1 ) );
179 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
180 asn1_write_10x( p, buffer, half_bits, 1 ) );
181 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
182 asn1_write_10x( p, buffer, half_bits, 1 ) );
183 MBEDTLS_ASN1_CHK_ADD( len, /* q */
184 asn1_write_10x( p, buffer, half_bits, 1 ) );
185 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
186 asn1_write_10x( p, buffer, half_bits, 3 ) );
187 MBEDTLS_ASN1_CHK_ADD( len, /* d */
188 asn1_write_10x( p, buffer, bits, 1 ) );
189 }
190 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
191 asn1_write_10x( p, buffer, 17, 1 ) );
192 MBEDTLS_ASN1_CHK_ADD( len, /* n */
193 asn1_write_10x( p, buffer, bits, 1 ) );
194 if( keypair )
195 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
196 mbedtls_asn1_write_int( p, buffer, 0 ) );
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
198 {
199 const unsigned char tag =
200 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
201 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
202 }
203 return( len );
204}
205
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100206int exercise_mac_setup( psa_key_type_t key_type,
207 const unsigned char *key_bytes,
208 size_t key_length,
209 psa_algorithm_t alg,
210 psa_mac_operation_t *operation,
211 psa_status_t *status )
212{
213 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100215
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200216 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
217 psa_set_key_algorithm( &attributes, alg );
218 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200219 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
220 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100221
222 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100223 /* Whether setup succeeded or failed, abort must succeed. */
224 PSA_ASSERT( psa_mac_abort( operation ) );
225 /* If setup failed, reproduce the failure, so that the caller can
226 * test the resulting state of the operation object. */
227 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100228 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100229 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
230 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100231 }
232
233 psa_destroy_key( handle );
234 return( 1 );
235
236exit:
237 psa_destroy_key( handle );
238 return( 0 );
239}
240
241int exercise_cipher_setup( psa_key_type_t key_type,
242 const unsigned char *key_bytes,
243 size_t key_length,
244 psa_algorithm_t alg,
245 psa_cipher_operation_t *operation,
246 psa_status_t *status )
247{
248 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200249 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100250
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200251 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
252 psa_set_key_algorithm( &attributes, alg );
253 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200254 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
255 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100256
257 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100258 /* Whether setup succeeded or failed, abort must succeed. */
259 PSA_ASSERT( psa_cipher_abort( operation ) );
260 /* If setup failed, reproduce the failure, so that the caller can
261 * test the resulting state of the operation object. */
262 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100263 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100264 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
265 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100266 }
267
268 psa_destroy_key( handle );
269 return( 1 );
270
271exit:
272 psa_destroy_key( handle );
273 return( 0 );
274}
275
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100276static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200277 psa_key_usage_t usage,
278 psa_algorithm_t alg )
279{
Jaeden Amero769ce272019-01-04 11:48:03 +0000280 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200281 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200282 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200283 size_t mac_length = sizeof( mac );
284
285 if( usage & PSA_KEY_USAGE_SIGN )
286 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100287 PSA_ASSERT( psa_mac_sign_setup( &operation,
288 handle, alg ) );
289 PSA_ASSERT( psa_mac_update( &operation,
290 input, sizeof( input ) ) );
291 PSA_ASSERT( psa_mac_sign_finish( &operation,
292 mac, sizeof( mac ),
293 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200294 }
295
296 if( usage & PSA_KEY_USAGE_VERIFY )
297 {
298 psa_status_t verify_status =
299 ( usage & PSA_KEY_USAGE_SIGN ?
300 PSA_SUCCESS :
301 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100302 PSA_ASSERT( psa_mac_verify_setup( &operation,
303 handle, alg ) );
304 PSA_ASSERT( psa_mac_update( &operation,
305 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100306 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
307 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200308 }
309
310 return( 1 );
311
312exit:
313 psa_mac_abort( &operation );
314 return( 0 );
315}
316
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100317static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200318 psa_key_usage_t usage,
319 psa_algorithm_t alg )
320{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000321 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200322 unsigned char iv[16] = {0};
323 size_t iv_length = sizeof( iv );
324 const unsigned char plaintext[16] = "Hello, world...";
325 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
326 size_t ciphertext_length = sizeof( ciphertext );
327 unsigned char decrypted[sizeof( ciphertext )];
328 size_t part_length;
329
330 if( usage & PSA_KEY_USAGE_ENCRYPT )
331 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100332 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
333 handle, alg ) );
334 PSA_ASSERT( psa_cipher_generate_iv( &operation,
335 iv, sizeof( iv ),
336 &iv_length ) );
337 PSA_ASSERT( psa_cipher_update( &operation,
338 plaintext, sizeof( plaintext ),
339 ciphertext, sizeof( ciphertext ),
340 &ciphertext_length ) );
341 PSA_ASSERT( psa_cipher_finish( &operation,
342 ciphertext + ciphertext_length,
343 sizeof( ciphertext ) - ciphertext_length,
344 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200345 ciphertext_length += part_length;
346 }
347
348 if( usage & PSA_KEY_USAGE_DECRYPT )
349 {
350 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200351 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200352 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
353 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200354 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
355 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
356 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
357 * have this macro yet. */
358 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
359 psa_get_key_type( &attributes ) );
360 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200361 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100362 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
363 handle, alg ) );
364 PSA_ASSERT( psa_cipher_set_iv( &operation,
365 iv, iv_length ) );
366 PSA_ASSERT( psa_cipher_update( &operation,
367 ciphertext, ciphertext_length,
368 decrypted, sizeof( decrypted ),
369 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200370 status = psa_cipher_finish( &operation,
371 decrypted + part_length,
372 sizeof( decrypted ) - part_length,
373 &part_length );
374 /* For a stream cipher, all inputs are valid. For a block cipher,
375 * if the input is some aribtrary data rather than an actual
376 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200377 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200378 TEST_ASSERT( status == PSA_SUCCESS ||
379 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200380 else
381 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200382 }
383
384 return( 1 );
385
386exit:
387 psa_cipher_abort( &operation );
388 return( 0 );
389}
390
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100391static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200392 psa_key_usage_t usage,
393 psa_algorithm_t alg )
394{
395 unsigned char nonce[16] = {0};
396 size_t nonce_length = sizeof( nonce );
397 unsigned char plaintext[16] = "Hello, world...";
398 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
399 size_t ciphertext_length = sizeof( ciphertext );
400 size_t plaintext_length = sizeof( ciphertext );
401
402 if( usage & PSA_KEY_USAGE_ENCRYPT )
403 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100404 PSA_ASSERT( psa_aead_encrypt( handle, alg,
405 nonce, nonce_length,
406 NULL, 0,
407 plaintext, sizeof( plaintext ),
408 ciphertext, sizeof( ciphertext ),
409 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200410 }
411
412 if( usage & PSA_KEY_USAGE_DECRYPT )
413 {
414 psa_status_t verify_status =
415 ( usage & PSA_KEY_USAGE_ENCRYPT ?
416 PSA_SUCCESS :
417 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100418 TEST_EQUAL( psa_aead_decrypt( handle, alg,
419 nonce, nonce_length,
420 NULL, 0,
421 ciphertext, ciphertext_length,
422 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100423 &plaintext_length ),
424 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200425 }
426
427 return( 1 );
428
429exit:
430 return( 0 );
431}
432
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100433static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200434 psa_key_usage_t usage,
435 psa_algorithm_t alg )
436{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200437 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
438 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200439 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200440 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100441 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
442
443 /* If the policy allows signing with any hash, just pick one. */
444 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
445 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100446#if defined(KNOWN_SUPPORTED_HASH_ALG)
447 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
448 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100449#else
450 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100451 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100452#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100453 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200454
455 if( usage & PSA_KEY_USAGE_SIGN )
456 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200457 /* Some algorithms require the payload to have the size of
458 * the hash encoded in the algorithm. Use this input size
459 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200460 if( hash_alg != 0 )
461 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100462 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
463 payload, payload_length,
464 signature, sizeof( signature ),
465 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200466 }
467
468 if( usage & PSA_KEY_USAGE_VERIFY )
469 {
470 psa_status_t verify_status =
471 ( usage & PSA_KEY_USAGE_SIGN ?
472 PSA_SUCCESS :
473 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100474 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
475 payload, payload_length,
476 signature, signature_length ),
477 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200478 }
479
480 return( 1 );
481
482exit:
483 return( 0 );
484}
485
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100486static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200487 psa_key_usage_t usage,
488 psa_algorithm_t alg )
489{
490 unsigned char plaintext[256] = "Hello, world...";
491 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
492 size_t ciphertext_length = sizeof( ciphertext );
493 size_t plaintext_length = 16;
494
495 if( usage & PSA_KEY_USAGE_ENCRYPT )
496 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100497 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
498 plaintext, plaintext_length,
499 NULL, 0,
500 ciphertext, sizeof( ciphertext ),
501 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200502 }
503
504 if( usage & PSA_KEY_USAGE_DECRYPT )
505 {
506 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100507 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200508 ciphertext, ciphertext_length,
509 NULL, 0,
510 plaintext, sizeof( plaintext ),
511 &plaintext_length );
512 TEST_ASSERT( status == PSA_SUCCESS ||
513 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
514 ( status == PSA_ERROR_INVALID_ARGUMENT ||
515 status == PSA_ERROR_INVALID_PADDING ) ) );
516 }
517
518 return( 1 );
519
520exit:
521 return( 0 );
522}
Gilles Peskine02b75072018-07-01 22:31:34 +0200523
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100524static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200525 psa_key_usage_t usage,
526 psa_algorithm_t alg )
527{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200528 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +0200529 unsigned char label[16] = "This is a label.";
530 size_t label_length = sizeof( label );
531 unsigned char seed[16] = "abcdefghijklmnop";
532 size_t seed_length = sizeof( seed );
533 unsigned char output[1];
534
535 if( usage & PSA_KEY_USAGE_DERIVE )
536 {
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100537 if( PSA_ALG_IS_HKDF( alg ) )
538 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200539 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
540 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200541 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100542 label,
543 label_length ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200544 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200545 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100546 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200547 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200548 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100549 seed,
550 seed_length ) );
551 }
552 else
553 {
554 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200555 PSA_ASSERT( psa_key_derivation( &operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100556 handle, alg,
557 label, label_length,
558 seed, seed_length,
559 sizeof( output ) ) );
560 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200561 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200562 output,
563 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200564 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200565 }
566
567 return( 1 );
568
569exit:
570 return( 0 );
571}
572
Gilles Peskinec7998b72018-11-07 18:45:02 +0100573/* We need two keys to exercise key agreement. Exercise the
574 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200575static psa_status_t key_agreement_with_self(
576 psa_key_derivation_operation_t *operation,
577 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100578{
579 psa_key_type_t private_key_type;
580 psa_key_type_t public_key_type;
581 size_t key_bits;
582 uint8_t *public_key = NULL;
583 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200584 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200585 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
586 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200587 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200588 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100589
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200590 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
591 private_key_type = psa_get_key_type( &attributes );
592 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200593 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100594 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
595 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100596 PSA_ASSERT( psa_export_public_key( handle,
597 public_key, public_key_length,
598 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100599
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200600 status = psa_key_derivation_key_agreement(
601 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
602 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100603exit:
604 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200605 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100606 return( status );
607}
608
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200609/* We need two keys to exercise key agreement. Exercise the
610 * private key against its own public key. */
611static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
612 psa_key_handle_t handle )
613{
614 psa_key_type_t private_key_type;
615 psa_key_type_t public_key_type;
616 size_t key_bits;
617 uint8_t *public_key = NULL;
618 size_t public_key_length;
619 uint8_t output[1024];
620 size_t output_length;
621 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200622 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
623 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200624 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200625 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200626
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200627 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
628 private_key_type = psa_get_key_type( &attributes );
629 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200630 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200631 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
632 ASSERT_ALLOC( public_key, public_key_length );
633 PSA_ASSERT( psa_export_public_key( handle,
634 public_key, public_key_length,
635 &public_key_length ) );
636
Gilles Peskinebe697d82019-05-16 18:00:41 +0200637 status = psa_raw_key_agreement( alg, handle,
638 public_key, public_key_length,
639 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200640exit:
641 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200642 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200643 return( status );
644}
645
646static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
647 psa_key_usage_t usage,
648 psa_algorithm_t alg )
649{
650 int ok = 0;
651
652 if( usage & PSA_KEY_USAGE_DERIVE )
653 {
654 /* We need two keys to exercise key agreement. Exercise the
655 * private key against its own public key. */
656 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
657 }
658 ok = 1;
659
660exit:
661 return( ok );
662}
663
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100664static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200665 psa_key_usage_t usage,
666 psa_algorithm_t alg )
667{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200668 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200669 unsigned char output[1];
670 int ok = 0;
671
672 if( usage & PSA_KEY_USAGE_DERIVE )
673 {
674 /* We need two keys to exercise key agreement. Exercise the
675 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200676 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
677 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
678 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200679 output,
680 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200681 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200682 }
683 ok = 1;
684
685exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200686 return( ok );
687}
688
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200689static int is_oid_of_key_type( psa_key_type_t type,
690 const uint8_t *oid, size_t oid_length )
691{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200692 const uint8_t *expected_oid = NULL;
693 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200694#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200695 if( PSA_KEY_TYPE_IS_RSA( type ) )
696 {
697 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
698 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
699 }
700 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200701#endif /* MBEDTLS_RSA_C */
702#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200703 if( PSA_KEY_TYPE_IS_ECC( type ) )
704 {
705 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
706 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
707 }
708 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200709#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200710 {
711 char message[40];
712 mbedtls_snprintf( message, sizeof( message ),
713 "OID not known for key type=0x%08lx",
714 (unsigned long) type );
715 test_fail( message, __LINE__, __FILE__ );
716 return( 0 );
717 }
718
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200719 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200720 return( 1 );
721
722exit:
723 return( 0 );
724}
725
726static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
727 size_t min_bits, size_t max_bits,
728 int must_be_odd )
729{
730 size_t len;
731 size_t actual_bits;
732 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100733 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100734 MBEDTLS_ASN1_INTEGER ),
735 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200736 /* Tolerate a slight departure from DER encoding:
737 * - 0 may be represented by an empty string or a 1-byte string.
738 * - The sign bit may be used as a value bit. */
739 if( ( len == 1 && ( *p )[0] == 0 ) ||
740 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
741 {
742 ++( *p );
743 --len;
744 }
745 if( min_bits == 0 && len == 0 )
746 return( 1 );
747 msb = ( *p )[0];
748 TEST_ASSERT( msb != 0 );
749 actual_bits = 8 * ( len - 1 );
750 while( msb != 0 )
751 {
752 msb >>= 1;
753 ++actual_bits;
754 }
755 TEST_ASSERT( actual_bits >= min_bits );
756 TEST_ASSERT( actual_bits <= max_bits );
757 if( must_be_odd )
758 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
759 *p += len;
760 return( 1 );
761exit:
762 return( 0 );
763}
764
765static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
766 size_t *len,
767 unsigned char n, unsigned char tag )
768{
769 int ret;
770 ret = mbedtls_asn1_get_tag( p, end, len,
771 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
772 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
773 if( ret != 0 )
774 return( ret );
775 end = *p + *len;
776 ret = mbedtls_asn1_get_tag( p, end, len, tag );
777 if( ret != 0 )
778 return( ret );
779 if( *p + *len != end )
780 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
781 return( 0 );
782}
783
784static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
785 uint8_t *exported, size_t exported_length )
786{
787 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100788 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200789 else
790 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200791
792#if defined(MBEDTLS_DES_C)
793 if( type == PSA_KEY_TYPE_DES )
794 {
795 /* Check the parity bits. */
796 unsigned i;
797 for( i = 0; i < bits / 8; i++ )
798 {
799 unsigned bit_count = 0;
800 unsigned m;
801 for( m = 1; m <= 0x100; m <<= 1 )
802 {
803 if( exported[i] & m )
804 ++bit_count;
805 }
806 TEST_ASSERT( bit_count % 2 != 0 );
807 }
808 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200809 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200810#endif
811
812#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200813 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200814 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200815 uint8_t *p = exported;
816 uint8_t *end = exported + exported_length;
817 size_t len;
818 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200819 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200820 * modulus INTEGER, -- n
821 * publicExponent INTEGER, -- e
822 * privateExponent INTEGER, -- d
823 * prime1 INTEGER, -- p
824 * prime2 INTEGER, -- q
825 * exponent1 INTEGER, -- d mod (p-1)
826 * exponent2 INTEGER, -- d mod (q-1)
827 * coefficient INTEGER, -- (inverse of q) mod p
828 * }
829 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100830 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
831 MBEDTLS_ASN1_SEQUENCE |
832 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
833 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200834 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
835 goto exit;
836 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
837 goto exit;
838 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
839 goto exit;
840 /* Require d to be at least half the size of n. */
841 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
842 goto exit;
843 /* Require p and q to be at most half the size of n, rounded up. */
844 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
845 goto exit;
846 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
847 goto exit;
848 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
849 goto exit;
850 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
851 goto exit;
852 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
853 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100854 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100855 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200856 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200857#endif /* MBEDTLS_RSA_C */
858
859#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200860 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200861 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100862 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100863 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100864 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200865 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200866#endif /* MBEDTLS_ECP_C */
867
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200868 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
869 {
870 uint8_t *p = exported;
871 uint8_t *end = exported + exported_length;
872 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200873#if defined(MBEDTLS_RSA_C)
874 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
875 {
876 /* RSAPublicKey ::= SEQUENCE {
877 * modulus INTEGER, -- n
878 * publicExponent INTEGER } -- e
879 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100880 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
881 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100882 MBEDTLS_ASN1_CONSTRUCTED ),
883 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100884 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200885 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
886 goto exit;
887 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
888 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100889 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200890 }
891 else
892#endif /* MBEDTLS_RSA_C */
893#if defined(MBEDTLS_ECP_C)
894 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
895 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000896 /* The representation of an ECC public key is:
897 * - The byte 0x04;
898 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
899 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
900 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000901 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100902 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
903 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200904 }
905 else
906#endif /* MBEDTLS_ECP_C */
907 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100908 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200909 mbedtls_snprintf( message, sizeof( message ),
910 "No sanity check for public key type=0x%08lx",
911 (unsigned long) type );
912 test_fail( message, __LINE__, __FILE__ );
913 return( 0 );
914 }
915 }
916 else
917
918 {
919 /* No sanity checks for other types */
920 }
921
922 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200923
924exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200925 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200926}
927
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100928static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200929 psa_key_usage_t usage )
930{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200931 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200932 uint8_t *exported = NULL;
933 size_t exported_size = 0;
934 size_t exported_length = 0;
935 int ok = 0;
936
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200937 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200938
939 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200940 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200941 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100942 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
943 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200944 ok = 1;
945 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200946 }
947
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200948 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
949 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200950 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200951
Gilles Peskine8817f612018-12-18 00:18:46 +0100952 PSA_ASSERT( psa_export_key( handle,
953 exported, exported_size,
954 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200955 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
956 psa_get_key_bits( &attributes ),
957 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200958
959exit:
960 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200961 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200962 return( ok );
963}
964
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100965static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200966{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200968 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200969 uint8_t *exported = NULL;
970 size_t exported_size = 0;
971 size_t exported_length = 0;
972 int ok = 0;
973
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200974 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
975 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200976 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100977 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100978 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200979 return( 1 );
980 }
981
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200982 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200983 psa_get_key_type( &attributes ) );
984 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
985 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200986 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200987
Gilles Peskine8817f612018-12-18 00:18:46 +0100988 PSA_ASSERT( psa_export_public_key( handle,
989 exported, exported_size,
990 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200991 ok = exported_key_sanity_check( public_type,
992 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200993 exported, exported_length );
994
995exit:
996 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200997 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200998 return( ok );
999}
1000
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001001/** Do smoke tests on a key.
1002 *
1003 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1004 * sign/verify, or derivation) that is permitted according to \p usage.
1005 * \p usage and \p alg should correspond to the expected policy on the
1006 * key.
1007 *
1008 * Export the key if permitted by \p usage, and check that the output
1009 * looks sensible. If \p usage forbids export, check that
1010 * \p psa_export_key correctly rejects the attempt. If the key is
1011 * asymmetric, also check \p psa_export_public_key.
1012 *
1013 * If the key fails the tests, this function calls the test framework's
1014 * `test_fail` function and returns false. Otherwise this function returns
1015 * true. Therefore it should be used as follows:
1016 * ```
1017 * if( ! exercise_key( ... ) ) goto exit;
1018 * ```
1019 *
1020 * \param handle The key to exercise. It should be capable of performing
1021 * \p alg.
1022 * \param usage The usage flags to assume.
1023 * \param alg The algorithm to exercise.
1024 *
1025 * \retval 0 The key failed the smoke tests.
1026 * \retval 1 The key passed the smoke tests.
1027 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001029 psa_key_usage_t usage,
1030 psa_algorithm_t alg )
1031{
1032 int ok;
1033 if( alg == 0 )
1034 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1035 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001036 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001037 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001038 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001039 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001040 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001041 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001042 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001043 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001044 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001045 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001046 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001047 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1048 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001049 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001050 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001051 else
1052 {
1053 char message[40];
1054 mbedtls_snprintf( message, sizeof( message ),
1055 "No code to exercise alg=0x%08lx",
1056 (unsigned long) alg );
1057 test_fail( message, __LINE__, __FILE__ );
1058 ok = 0;
1059 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001060
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001061 ok = ok && exercise_export_key( handle, usage );
1062 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001063
Gilles Peskine02b75072018-07-01 22:31:34 +02001064 return( ok );
1065}
1066
Gilles Peskine10df3412018-10-25 22:35:43 +02001067static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1068 psa_algorithm_t alg )
1069{
1070 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1071 {
1072 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1073 PSA_KEY_USAGE_VERIFY :
1074 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1075 }
1076 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1077 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1078 {
1079 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1080 PSA_KEY_USAGE_ENCRYPT :
1081 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1082 }
1083 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1084 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1085 {
1086 return( PSA_KEY_USAGE_DERIVE );
1087 }
1088 else
1089 {
1090 return( 0 );
1091 }
1092
1093}
Darryl Green0c6575a2018-11-07 16:05:30 +00001094
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001095static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1096{
1097 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1098 uint8_t buffer[1];
1099 size_t length;
1100 int ok = 0;
1101
Gilles Peskinec87af662019-05-15 16:12:22 +02001102 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001103 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1104 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1105 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1106 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1107 PSA_ERROR_INVALID_HANDLE );
1108 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001109 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001110 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1111 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1112 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1113 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1114
1115 TEST_EQUAL( psa_export_key( handle,
1116 buffer, sizeof( buffer ), &length ),
1117 PSA_ERROR_INVALID_HANDLE );
1118 TEST_EQUAL( psa_export_public_key( handle,
1119 buffer, sizeof( buffer ), &length ),
1120 PSA_ERROR_INVALID_HANDLE );
1121
1122 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1123 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1124
1125 ok = 1;
1126
1127exit:
1128 psa_reset_key_attributes( &attributes );
1129 return( ok );
1130}
1131
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001132/* An overapproximation of the amount of storage needed for a key of the
1133 * given type and with the given content. The API doesn't make it easy
1134 * to find a good value for the size. The current implementation doesn't
1135 * care about the value anyway. */
1136#define KEY_BITS_FROM_DATA( type, data ) \
1137 ( data )->len
1138
Darryl Green0c6575a2018-11-07 16:05:30 +00001139typedef enum {
1140 IMPORT_KEY = 0,
1141 GENERATE_KEY = 1,
1142 DERIVE_KEY = 2
1143} generate_method;
1144
Gilles Peskinee59236f2018-01-27 23:32:46 +01001145/* END_HEADER */
1146
1147/* BEGIN_DEPENDENCIES
1148 * depends_on:MBEDTLS_PSA_CRYPTO_C
1149 * END_DEPENDENCIES
1150 */
1151
1152/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001153void static_checks( )
1154{
1155 size_t max_truncated_mac_size =
1156 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1157
1158 /* Check that the length for a truncated MAC always fits in the algorithm
1159 * encoding. The shifted mask is the maximum truncated value. The
1160 * untruncated algorithm may be one byte larger. */
1161 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1162}
1163/* END_CASE */
1164
1165/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001166void attributes_set_get( int id_arg, int lifetime_arg,
1167 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001168 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001169{
Gilles Peskine4747d192019-04-17 15:05:45 +02001170 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001171 psa_key_id_t id = id_arg;
1172 psa_key_lifetime_t lifetime = lifetime_arg;
1173 psa_key_usage_t usage_flags = usage_flags_arg;
1174 psa_algorithm_t alg = alg_arg;
1175 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001176 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001177
1178 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1179 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1182 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001183 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001184
Gilles Peskinec87af662019-05-15 16:12:22 +02001185 psa_set_key_id( &attributes, id );
1186 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001187 psa_set_key_usage_flags( &attributes, usage_flags );
1188 psa_set_key_algorithm( &attributes, alg );
1189 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001190 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001191
1192 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1193 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1194 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1195 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1196 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001197 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001198
1199 psa_reset_key_attributes( &attributes );
1200
1201 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1202 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1203 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1204 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1205 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001206 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001207}
1208/* END_CASE */
1209
1210/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001211void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1212 int expected_id_arg, int expected_lifetime_arg )
1213{
1214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1215 psa_key_id_t id1 = id1_arg;
1216 psa_key_lifetime_t lifetime = lifetime_arg;
1217 psa_key_id_t id2 = id2_arg;
1218 psa_key_id_t expected_id = expected_id_arg;
1219 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1220
1221 if( id1_arg != -1 )
1222 psa_set_key_id( &attributes, id1 );
1223 if( lifetime_arg != -1 )
1224 psa_set_key_lifetime( &attributes, lifetime );
1225 if( id2_arg != -1 )
1226 psa_set_key_id( &attributes, id2 );
1227
1228 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1229 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1230}
1231/* END_CASE */
1232
1233/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001234void import( data_t *data, int type_arg,
1235 int attr_bits_arg,
1236 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001237{
1238 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1239 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001240 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001241 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001242 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001243 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001244 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001245
Gilles Peskine8817f612018-12-18 00:18:46 +01001246 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001247
Gilles Peskine4747d192019-04-17 15:05:45 +02001248 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001249 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001250 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001251 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001252 if( status != PSA_SUCCESS )
1253 goto exit;
1254
1255 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1256 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001257 if( attr_bits != 0 )
1258 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001259
1260 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001261 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001262
1263exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001264 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001265 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001266 mbedtls_psa_crypto_free( );
1267}
1268/* END_CASE */
1269
1270/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001271void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1272{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001273 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001274 size_t bits = bits_arg;
1275 psa_status_t expected_status = expected_status_arg;
1276 psa_status_t status;
1277 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001278 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001279 size_t buffer_size = /* Slight overapproximations */
1280 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001281 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001282 unsigned char *p;
1283 int ret;
1284 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001285 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001286
Gilles Peskine8817f612018-12-18 00:18:46 +01001287 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001288 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001289
1290 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1291 bits, keypair ) ) >= 0 );
1292 length = ret;
1293
1294 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001295 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001296 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001297 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001298 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001299 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001300
1301exit:
1302 mbedtls_free( buffer );
1303 mbedtls_psa_crypto_free( );
1304}
1305/* END_CASE */
1306
1307/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001308void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001309 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001310 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001311 int expected_bits,
1312 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001313 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001314 int canonical_input )
1315{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001316 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001318 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001319 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001320 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001321 unsigned char *exported = NULL;
1322 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001323 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001324 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001325 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001326 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001327 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001328
Moran Pekercb088e72018-07-17 17:36:59 +03001329 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001330 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001331 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001332 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001333 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001334
Gilles Peskine4747d192019-04-17 15:05:45 +02001335 psa_set_key_usage_flags( &attributes, usage_arg );
1336 psa_set_key_algorithm( &attributes, alg );
1337 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001338
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001339 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001340 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001341
1342 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001343 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1344 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1345 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001346
1347 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001348 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001349 exported, export_size,
1350 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001351 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001352
1353 /* The exported length must be set by psa_export_key() to a value between 0
1354 * and export_size. On errors, the exported length must be 0. */
1355 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1356 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1357 TEST_ASSERT( exported_length <= export_size );
1358
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001359 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001360 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001361 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001362 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001363 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001364 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001365 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001366
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001367 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001368 goto exit;
1369
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001370 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001371 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001372 else
1373 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001374 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001375 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1376 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001377 PSA_ASSERT( psa_export_key( handle2,
1378 reexported,
1379 export_size,
1380 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001381 ASSERT_COMPARE( exported, exported_length,
1382 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001383 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001384 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001385 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001386
1387destroy:
1388 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001389 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001390 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001391
1392exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001393 mbedtls_free( exported );
1394 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001395 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001396 mbedtls_psa_crypto_free( );
1397}
1398/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001399
Moran Pekerf709f4a2018-06-06 17:26:04 +03001400/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001401void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001402{
Gilles Peskine8817f612018-12-18 00:18:46 +01001403 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001404 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001405
1406exit:
1407 mbedtls_psa_crypto_free( );
1408}
1409/* END_CASE */
1410
1411/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001412void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001413 int type_arg,
1414 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001415 int export_size_delta,
1416 int expected_export_status_arg,
1417 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001418{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001419 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001420 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001421 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001422 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001423 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001424 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001425 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001426 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001427 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001428
Gilles Peskine8817f612018-12-18 00:18:46 +01001429 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001430
Gilles Peskine4747d192019-04-17 15:05:45 +02001431 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1432 psa_set_key_algorithm( &attributes, alg );
1433 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001434
1435 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001436 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001437
Gilles Peskine49c25912018-10-29 15:15:31 +01001438 /* Export the public key */
1439 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001440 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001441 exported, export_size,
1442 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001443 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001444 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001445 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001446 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001447 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001448 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1449 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001450 TEST_ASSERT( expected_public_key->len <=
1451 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001452 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1453 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001454 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001455
1456exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001457 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001458 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001459 psa_reset_key_attributes( &attributes );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001460 mbedtls_psa_crypto_free( );
1461}
1462/* END_CASE */
1463
Gilles Peskine20035e32018-02-03 22:44:14 +01001464/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001465void import_and_exercise_key( data_t *data,
1466 int type_arg,
1467 int bits_arg,
1468 int alg_arg )
1469{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001470 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001471 psa_key_type_t type = type_arg;
1472 size_t bits = bits_arg;
1473 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001474 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001475 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001476 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001477
Gilles Peskine8817f612018-12-18 00:18:46 +01001478 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001479
Gilles Peskine4747d192019-04-17 15:05:45 +02001480 psa_set_key_usage_flags( &attributes, usage );
1481 psa_set_key_algorithm( &attributes, alg );
1482 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001483
1484 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001485 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001486
1487 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001488 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1489 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1490 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001491
1492 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001493 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001494 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001495
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001496 PSA_ASSERT( psa_destroy_key( handle ) );
1497 test_operations_on_invalid_handle( handle );
1498
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001499exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001500 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001501 psa_reset_key_attributes( &got_attributes );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001502 mbedtls_psa_crypto_free( );
1503}
1504/* END_CASE */
1505
1506/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001507void key_policy( int usage_arg, int alg_arg )
1508{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001509 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001510 psa_algorithm_t alg = alg_arg;
1511 psa_key_usage_t usage = usage_arg;
1512 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1513 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001514 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001515
1516 memset( key, 0x2a, sizeof( key ) );
1517
Gilles Peskine8817f612018-12-18 00:18:46 +01001518 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001519
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001520 psa_set_key_usage_flags( &attributes, usage );
1521 psa_set_key_algorithm( &attributes, alg );
1522 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001523
Gilles Peskine73676cb2019-05-15 20:15:10 +02001524 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001525
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001526 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1527 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1528 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1529 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001530
1531exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001532 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001533 psa_reset_key_attributes( &attributes );
Gilles Peskined5b33222018-06-18 22:20:03 +02001534 mbedtls_psa_crypto_free( );
1535}
1536/* END_CASE */
1537
1538/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001539void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001540{
1541 /* Test each valid way of initializing the object, except for `= {0}`, as
1542 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1543 * though it's OK by the C standard. We could test for this, but we'd need
1544 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001545 psa_key_attributes_t func = psa_key_attributes_init( );
1546 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1547 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001548
1549 memset( &zero, 0, sizeof( zero ) );
1550
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001551 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1552 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1553 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001554
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001555 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1556 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1557 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1558
1559 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1560 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1561 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1562
1563 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1564 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1565 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1566
1567 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1568 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1569 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001570}
1571/* END_CASE */
1572
1573/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001574void mac_key_policy( int policy_usage,
1575 int policy_alg,
1576 int key_type,
1577 data_t *key_data,
1578 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001579{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001580 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001581 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001582 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001583 psa_status_t status;
1584 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001585
Gilles Peskine8817f612018-12-18 00:18:46 +01001586 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001587
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001588 psa_set_key_usage_flags( &attributes, policy_usage );
1589 psa_set_key_algorithm( &attributes, policy_alg );
1590 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001591
Gilles Peskine049c7532019-05-15 20:22:09 +02001592 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1593 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001594
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001595 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001596 if( policy_alg == exercise_alg &&
1597 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001598 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001599 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001600 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001601 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001602
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001603 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001604 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001605 if( policy_alg == exercise_alg &&
1606 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001607 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001608 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001609 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001610
1611exit:
1612 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001613 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001614 mbedtls_psa_crypto_free( );
1615}
1616/* END_CASE */
1617
1618/* BEGIN_CASE */
1619void cipher_key_policy( int policy_usage,
1620 int policy_alg,
1621 int key_type,
1622 data_t *key_data,
1623 int exercise_alg )
1624{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001625 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001626 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001627 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001628 psa_status_t status;
1629
Gilles Peskine8817f612018-12-18 00:18:46 +01001630 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001631
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001632 psa_set_key_usage_flags( &attributes, policy_usage );
1633 psa_set_key_algorithm( &attributes, policy_alg );
1634 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001635
Gilles Peskine049c7532019-05-15 20:22:09 +02001636 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1637 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001638
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001639 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001640 if( policy_alg == exercise_alg &&
1641 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001642 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001643 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001644 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001645 psa_cipher_abort( &operation );
1646
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001647 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001648 if( policy_alg == exercise_alg &&
1649 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001650 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001651 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001652 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001653
1654exit:
1655 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001656 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001657 mbedtls_psa_crypto_free( );
1658}
1659/* END_CASE */
1660
1661/* BEGIN_CASE */
1662void aead_key_policy( int policy_usage,
1663 int policy_alg,
1664 int key_type,
1665 data_t *key_data,
1666 int nonce_length_arg,
1667 int tag_length_arg,
1668 int exercise_alg )
1669{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001670 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001671 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001672 psa_status_t status;
1673 unsigned char nonce[16] = {0};
1674 size_t nonce_length = nonce_length_arg;
1675 unsigned char tag[16];
1676 size_t tag_length = tag_length_arg;
1677 size_t output_length;
1678
1679 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1680 TEST_ASSERT( tag_length <= sizeof( tag ) );
1681
Gilles Peskine8817f612018-12-18 00:18:46 +01001682 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001683
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001684 psa_set_key_usage_flags( &attributes, policy_usage );
1685 psa_set_key_algorithm( &attributes, policy_alg );
1686 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001687
Gilles Peskine049c7532019-05-15 20:22:09 +02001688 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1689 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001690
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001691 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692 nonce, nonce_length,
1693 NULL, 0,
1694 NULL, 0,
1695 tag, tag_length,
1696 &output_length );
1697 if( policy_alg == exercise_alg &&
1698 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001699 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001700 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001701 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001702
1703 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001704 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705 nonce, nonce_length,
1706 NULL, 0,
1707 tag, tag_length,
1708 NULL, 0,
1709 &output_length );
1710 if( policy_alg == exercise_alg &&
1711 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001712 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001713 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001714 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001715
1716exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001717 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001718 mbedtls_psa_crypto_free( );
1719}
1720/* END_CASE */
1721
1722/* BEGIN_CASE */
1723void asymmetric_encryption_key_policy( int policy_usage,
1724 int policy_alg,
1725 int key_type,
1726 data_t *key_data,
1727 int exercise_alg )
1728{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001729 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001730 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001731 psa_status_t status;
1732 size_t key_bits;
1733 size_t buffer_length;
1734 unsigned char *buffer = NULL;
1735 size_t output_length;
1736
Gilles Peskine8817f612018-12-18 00:18:46 +01001737 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001738
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001739 psa_set_key_usage_flags( &attributes, policy_usage );
1740 psa_set_key_algorithm( &attributes, policy_alg );
1741 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001742
Gilles Peskine049c7532019-05-15 20:22:09 +02001743 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1744 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001745
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001746 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1747 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1749 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001750 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001752 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001753 NULL, 0,
1754 NULL, 0,
1755 buffer, buffer_length,
1756 &output_length );
1757 if( policy_alg == exercise_alg &&
1758 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001759 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001760 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001761 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001763 if( buffer_length != 0 )
1764 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001765 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001766 buffer, buffer_length,
1767 NULL, 0,
1768 buffer, buffer_length,
1769 &output_length );
1770 if( policy_alg == exercise_alg &&
1771 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001772 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001773 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001774 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001775
1776exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001777 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001778 psa_reset_key_attributes( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001779 mbedtls_psa_crypto_free( );
1780 mbedtls_free( buffer );
1781}
1782/* END_CASE */
1783
1784/* BEGIN_CASE */
1785void asymmetric_signature_key_policy( int policy_usage,
1786 int policy_alg,
1787 int key_type,
1788 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001789 int exercise_alg,
1790 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001791{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001792 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001793 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001794 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001795 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1796 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1797 * compatible with the policy and `payload_length_arg` is supposed to be
1798 * a valid input length to sign. If `payload_length_arg <= 0`,
1799 * `exercise_alg` is supposed to be forbidden by the policy. */
1800 int compatible_alg = payload_length_arg > 0;
1801 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001802 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1803 size_t signature_length;
1804
Gilles Peskine8817f612018-12-18 00:18:46 +01001805 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001806
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001807 psa_set_key_usage_flags( &attributes, policy_usage );
1808 psa_set_key_algorithm( &attributes, policy_alg );
1809 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001810
Gilles Peskine049c7532019-05-15 20:22:09 +02001811 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1812 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001813
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001814 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001815 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001816 signature, sizeof( signature ),
1817 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001818 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001819 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001820 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001821 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822
1823 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001824 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001825 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001826 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001827 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001828 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001829 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001830 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001831
1832exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001833 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001834 mbedtls_psa_crypto_free( );
1835}
1836/* END_CASE */
1837
1838/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001839void derive_key_policy( int policy_usage,
1840 int policy_alg,
1841 int key_type,
1842 data_t *key_data,
1843 int exercise_alg )
1844{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001845 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001846 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001847 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001848 psa_status_t status;
1849
Gilles Peskine8817f612018-12-18 00:18:46 +01001850 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001851
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001852 psa_set_key_usage_flags( &attributes, policy_usage );
1853 psa_set_key_algorithm( &attributes, policy_alg );
1854 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001855
Gilles Peskine049c7532019-05-15 20:22:09 +02001856 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1857 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001858
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001859 status = psa_key_derivation( &operation, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001860 exercise_alg,
1861 NULL, 0,
1862 NULL, 0,
1863 1 );
1864 if( policy_alg == exercise_alg &&
1865 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001866 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001867 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001868 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001869
1870exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001871 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001872 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001873 mbedtls_psa_crypto_free( );
1874}
1875/* END_CASE */
1876
1877/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001878void agreement_key_policy( int policy_usage,
1879 int policy_alg,
1880 int key_type_arg,
1881 data_t *key_data,
1882 int exercise_alg )
1883{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001884 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001885 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001886 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001887 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001888 psa_status_t status;
1889
Gilles Peskine8817f612018-12-18 00:18:46 +01001890 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001891
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001892 psa_set_key_usage_flags( &attributes, policy_usage );
1893 psa_set_key_algorithm( &attributes, policy_alg );
1894 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001895
Gilles Peskine049c7532019-05-15 20:22:09 +02001896 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1897 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001898
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001899 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1900 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001901
Gilles Peskine01d718c2018-09-18 12:01:02 +02001902 if( policy_alg == exercise_alg &&
1903 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001904 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001905 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001906 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001907
1908exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001909 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001910 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001911 mbedtls_psa_crypto_free( );
1912}
1913/* END_CASE */
1914
1915/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001916void key_policy_alg2( int key_type_arg, data_t *key_data,
1917 int usage_arg, int alg_arg, int alg2_arg )
1918{
1919 psa_key_handle_t handle = 0;
1920 psa_key_type_t key_type = key_type_arg;
1921 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1922 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1923 psa_key_usage_t usage = usage_arg;
1924 psa_algorithm_t alg = alg_arg;
1925 psa_algorithm_t alg2 = alg2_arg;
1926
1927 PSA_ASSERT( psa_crypto_init( ) );
1928
1929 psa_set_key_usage_flags( &attributes, usage );
1930 psa_set_key_algorithm( &attributes, alg );
1931 psa_set_key_enrollment_algorithm( &attributes, alg2 );
1932 psa_set_key_type( &attributes, key_type );
1933 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1934 &handle ) );
1935
1936 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1937 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1938 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1939 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
1940
1941 if( ! exercise_key( handle, usage, alg ) )
1942 goto exit;
1943 if( ! exercise_key( handle, usage, alg2 ) )
1944 goto exit;
1945
1946exit:
1947 psa_destroy_key( handle );
1948 mbedtls_psa_crypto_free( );
1949}
1950/* END_CASE */
1951
1952/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001953void raw_agreement_key_policy( int policy_usage,
1954 int policy_alg,
1955 int key_type_arg,
1956 data_t *key_data,
1957 int exercise_alg )
1958{
1959 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001960 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001961 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001962 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001963 psa_status_t status;
1964
1965 PSA_ASSERT( psa_crypto_init( ) );
1966
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001967 psa_set_key_usage_flags( &attributes, policy_usage );
1968 psa_set_key_algorithm( &attributes, policy_alg );
1969 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001970
Gilles Peskine049c7532019-05-15 20:22:09 +02001971 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1972 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001973
1974 status = raw_key_agreement_with_self( exercise_alg, handle );
1975
1976 if( policy_alg == exercise_alg &&
1977 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1978 PSA_ASSERT( status );
1979 else
1980 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1981
1982exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001983 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001984 psa_destroy_key( handle );
1985 mbedtls_psa_crypto_free( );
1986}
1987/* END_CASE */
1988
1989/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02001990void copy_success( int source_usage_arg, int source_alg_arg,
1991 int type_arg, data_t *material,
1992 int copy_attributes,
1993 int target_usage_arg, int target_alg_arg,
1994 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001995{
Gilles Peskineca25db92019-04-19 11:43:08 +02001996 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1997 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001998 psa_key_usage_t expected_usage = expected_usage_arg;
1999 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002000 psa_key_handle_t source_handle = 0;
2001 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002002 uint8_t *export_buffer = NULL;
2003
Gilles Peskine57ab7212019-01-28 13:03:09 +01002004 PSA_ASSERT( psa_crypto_init( ) );
2005
Gilles Peskineca25db92019-04-19 11:43:08 +02002006 /* Prepare the source key. */
2007 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2008 psa_set_key_algorithm( &source_attributes, source_alg_arg );
2009 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002010 PSA_ASSERT( psa_import_key( &source_attributes,
2011 material->x, material->len,
2012 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002013 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002014
Gilles Peskineca25db92019-04-19 11:43:08 +02002015 /* Prepare the target attributes. */
2016 if( copy_attributes )
2017 target_attributes = source_attributes;
2018 if( target_usage_arg != -1 )
2019 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2020 if( target_alg_arg != -1 )
2021 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002022
2023 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002024 PSA_ASSERT( psa_copy_key( source_handle,
2025 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002026
2027 /* Destroy the source to ensure that this doesn't affect the target. */
2028 PSA_ASSERT( psa_destroy_key( source_handle ) );
2029
2030 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002031 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2032 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2033 psa_get_key_type( &target_attributes ) );
2034 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2035 psa_get_key_bits( &target_attributes ) );
2036 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2037 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002038 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2039 {
2040 size_t length;
2041 ASSERT_ALLOC( export_buffer, material->len );
2042 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2043 material->len, &length ) );
2044 ASSERT_COMPARE( material->x, material->len,
2045 export_buffer, length );
2046 }
2047 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2048 goto exit;
2049
2050 PSA_ASSERT( psa_close_key( target_handle ) );
2051
2052exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002053 psa_reset_key_attributes( &source_attributes );
2054 psa_reset_key_attributes( &target_attributes );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002055 mbedtls_psa_crypto_free( );
2056 mbedtls_free( export_buffer );
2057}
2058/* END_CASE */
2059
2060/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02002061void copy_fail( int source_usage_arg, int source_alg_arg,
2062 int type_arg, data_t *material,
2063 int target_type_arg, int target_bits_arg,
2064 int target_usage_arg, int target_alg_arg,
2065 int expected_status_arg )
2066{
2067 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2068 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2069 psa_key_handle_t source_handle = 0;
2070 psa_key_handle_t target_handle = 0;
2071
2072 PSA_ASSERT( psa_crypto_init( ) );
2073
2074 /* Prepare the source key. */
2075 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2076 psa_set_key_algorithm( &source_attributes, source_alg_arg );
2077 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002078 PSA_ASSERT( psa_import_key( &source_attributes,
2079 material->x, material->len,
2080 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002081
2082 /* Prepare the target attributes. */
2083 psa_set_key_type( &target_attributes, target_type_arg );
2084 psa_set_key_bits( &target_attributes, target_bits_arg );
2085 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2086 psa_set_key_algorithm( &target_attributes, target_alg_arg );
2087
2088 /* Try to copy the key. */
2089 TEST_EQUAL( psa_copy_key( source_handle,
2090 &target_attributes, &target_handle ),
2091 expected_status_arg );
2092exit:
2093 psa_reset_key_attributes( &source_attributes );
2094 psa_reset_key_attributes( &target_attributes );
2095 mbedtls_psa_crypto_free( );
2096}
2097/* END_CASE */
2098
2099/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002100void hash_operation_init( )
2101{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002102 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002103 /* Test each valid way of initializing the object, except for `= {0}`, as
2104 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2105 * though it's OK by the C standard. We could test for this, but we'd need
2106 * to supress the Clang warning for the test. */
2107 psa_hash_operation_t func = psa_hash_operation_init( );
2108 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2109 psa_hash_operation_t zero;
2110
2111 memset( &zero, 0, sizeof( zero ) );
2112
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002113 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002114 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2115 PSA_ERROR_BAD_STATE );
2116 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2117 PSA_ERROR_BAD_STATE );
2118 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2119 PSA_ERROR_BAD_STATE );
2120
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002121 /* A default hash operation should be abortable without error. */
2122 PSA_ASSERT( psa_hash_abort( &func ) );
2123 PSA_ASSERT( psa_hash_abort( &init ) );
2124 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002125}
2126/* END_CASE */
2127
2128/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002129void hash_setup( int alg_arg,
2130 int expected_status_arg )
2131{
2132 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002133 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002134 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002135 psa_status_t status;
2136
Gilles Peskine8817f612018-12-18 00:18:46 +01002137 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002138
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002139 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002140 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002141
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002142 /* Whether setup succeeded or failed, abort must succeed. */
2143 PSA_ASSERT( psa_hash_abort( &operation ) );
2144
2145 /* If setup failed, reproduce the failure, so as to
2146 * test the resulting state of the operation object. */
2147 if( status != PSA_SUCCESS )
2148 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2149
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002150 /* Now the operation object should be reusable. */
2151#if defined(KNOWN_SUPPORTED_HASH_ALG)
2152 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2153 PSA_ASSERT( psa_hash_abort( &operation ) );
2154#endif
2155
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002156exit:
2157 mbedtls_psa_crypto_free( );
2158}
2159/* END_CASE */
2160
2161/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002162void hash_bad_order( )
2163{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002164 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002165 unsigned char input[] = "";
2166 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002167 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002168 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2169 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2170 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002171 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002172 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002173 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002174
Gilles Peskine8817f612018-12-18 00:18:46 +01002175 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002176
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002177 /* Call setup twice in a row. */
2178 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2179 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2180 PSA_ERROR_BAD_STATE );
2181 PSA_ASSERT( psa_hash_abort( &operation ) );
2182
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002183 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002184 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002185 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002186 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002187
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002188 /* Call update after finish. */
2189 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2190 PSA_ASSERT( psa_hash_finish( &operation,
2191 hash, sizeof( hash ), &hash_len ) );
2192 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002193 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002194 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002195
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002196 /* Call verify without calling setup beforehand. */
2197 TEST_EQUAL( psa_hash_verify( &operation,
2198 valid_hash, sizeof( valid_hash ) ),
2199 PSA_ERROR_BAD_STATE );
2200 PSA_ASSERT( psa_hash_abort( &operation ) );
2201
2202 /* Call verify after finish. */
2203 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2204 PSA_ASSERT( psa_hash_finish( &operation,
2205 hash, sizeof( hash ), &hash_len ) );
2206 TEST_EQUAL( psa_hash_verify( &operation,
2207 valid_hash, sizeof( valid_hash ) ),
2208 PSA_ERROR_BAD_STATE );
2209 PSA_ASSERT( psa_hash_abort( &operation ) );
2210
2211 /* Call verify twice in a row. */
2212 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2213 PSA_ASSERT( psa_hash_verify( &operation,
2214 valid_hash, sizeof( valid_hash ) ) );
2215 TEST_EQUAL( psa_hash_verify( &operation,
2216 valid_hash, sizeof( valid_hash ) ),
2217 PSA_ERROR_BAD_STATE );
2218 PSA_ASSERT( psa_hash_abort( &operation ) );
2219
2220 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002221 TEST_EQUAL( psa_hash_finish( &operation,
2222 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002223 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002224 PSA_ASSERT( psa_hash_abort( &operation ) );
2225
2226 /* Call finish twice in a row. */
2227 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2228 PSA_ASSERT( psa_hash_finish( &operation,
2229 hash, sizeof( hash ), &hash_len ) );
2230 TEST_EQUAL( psa_hash_finish( &operation,
2231 hash, sizeof( hash ), &hash_len ),
2232 PSA_ERROR_BAD_STATE );
2233 PSA_ASSERT( psa_hash_abort( &operation ) );
2234
2235 /* Call finish after calling verify. */
2236 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2237 PSA_ASSERT( psa_hash_verify( &operation,
2238 valid_hash, sizeof( valid_hash ) ) );
2239 TEST_EQUAL( psa_hash_finish( &operation,
2240 hash, sizeof( hash ), &hash_len ),
2241 PSA_ERROR_BAD_STATE );
2242 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002243
2244exit:
2245 mbedtls_psa_crypto_free( );
2246}
2247/* END_CASE */
2248
itayzafrir27e69452018-11-01 14:26:34 +02002249/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2250void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002251{
2252 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002253 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2254 * appended to it */
2255 unsigned char hash[] = {
2256 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2257 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2258 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002259 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002260 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002261
Gilles Peskine8817f612018-12-18 00:18:46 +01002262 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002263
itayzafrir27e69452018-11-01 14:26:34 +02002264 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002265 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002266 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002267 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002268
itayzafrir27e69452018-11-01 14:26:34 +02002269 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002270 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002271 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002272 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002273
itayzafrir27e69452018-11-01 14:26:34 +02002274 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002275 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002276 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002277 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002278
itayzafrirec93d302018-10-18 18:01:10 +03002279exit:
2280 mbedtls_psa_crypto_free( );
2281}
2282/* END_CASE */
2283
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002284/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2285void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002286{
2287 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002288 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002289 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002290 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002291 size_t hash_len;
2292
Gilles Peskine8817f612018-12-18 00:18:46 +01002293 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002294
itayzafrir58028322018-10-25 10:22:01 +03002295 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002296 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002297 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002298 hash, expected_size - 1, &hash_len ),
2299 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002300
2301exit:
2302 mbedtls_psa_crypto_free( );
2303}
2304/* END_CASE */
2305
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002306/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2307void hash_clone_source_state( )
2308{
2309 psa_algorithm_t alg = PSA_ALG_SHA_256;
2310 unsigned char hash[PSA_HASH_MAX_SIZE];
2311 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2312 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2313 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2314 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2315 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2316 size_t hash_len;
2317
2318 PSA_ASSERT( psa_crypto_init( ) );
2319 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2320
2321 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2322 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2323 PSA_ASSERT( psa_hash_finish( &op_finished,
2324 hash, sizeof( hash ), &hash_len ) );
2325 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2326 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2327
2328 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2329 PSA_ERROR_BAD_STATE );
2330
2331 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2332 PSA_ASSERT( psa_hash_finish( &op_init,
2333 hash, sizeof( hash ), &hash_len ) );
2334 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2335 PSA_ASSERT( psa_hash_finish( &op_finished,
2336 hash, sizeof( hash ), &hash_len ) );
2337 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2338 PSA_ASSERT( psa_hash_finish( &op_aborted,
2339 hash, sizeof( hash ), &hash_len ) );
2340
2341exit:
2342 psa_hash_abort( &op_source );
2343 psa_hash_abort( &op_init );
2344 psa_hash_abort( &op_setup );
2345 psa_hash_abort( &op_finished );
2346 psa_hash_abort( &op_aborted );
2347 mbedtls_psa_crypto_free( );
2348}
2349/* END_CASE */
2350
2351/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2352void hash_clone_target_state( )
2353{
2354 psa_algorithm_t alg = PSA_ALG_SHA_256;
2355 unsigned char hash[PSA_HASH_MAX_SIZE];
2356 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2357 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2358 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2359 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2360 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2361 size_t hash_len;
2362
2363 PSA_ASSERT( psa_crypto_init( ) );
2364
2365 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2366 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2367 PSA_ASSERT( psa_hash_finish( &op_finished,
2368 hash, sizeof( hash ), &hash_len ) );
2369 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2370 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2371
2372 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2373 PSA_ASSERT( psa_hash_finish( &op_target,
2374 hash, sizeof( hash ), &hash_len ) );
2375
2376 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2377 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2378 PSA_ERROR_BAD_STATE );
2379 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2380 PSA_ERROR_BAD_STATE );
2381
2382exit:
2383 psa_hash_abort( &op_target );
2384 psa_hash_abort( &op_init );
2385 psa_hash_abort( &op_setup );
2386 psa_hash_abort( &op_finished );
2387 psa_hash_abort( &op_aborted );
2388 mbedtls_psa_crypto_free( );
2389}
2390/* END_CASE */
2391
itayzafrir58028322018-10-25 10:22:01 +03002392/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002393void mac_operation_init( )
2394{
Jaeden Amero252ef282019-02-15 14:05:35 +00002395 const uint8_t input[1] = { 0 };
2396
Jaeden Amero769ce272019-01-04 11:48:03 +00002397 /* Test each valid way of initializing the object, except for `= {0}`, as
2398 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2399 * though it's OK by the C standard. We could test for this, but we'd need
2400 * to supress the Clang warning for the test. */
2401 psa_mac_operation_t func = psa_mac_operation_init( );
2402 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2403 psa_mac_operation_t zero;
2404
2405 memset( &zero, 0, sizeof( zero ) );
2406
Jaeden Amero252ef282019-02-15 14:05:35 +00002407 /* A freshly-initialized MAC operation should not be usable. */
2408 TEST_EQUAL( psa_mac_update( &func,
2409 input, sizeof( input ) ),
2410 PSA_ERROR_BAD_STATE );
2411 TEST_EQUAL( psa_mac_update( &init,
2412 input, sizeof( input ) ),
2413 PSA_ERROR_BAD_STATE );
2414 TEST_EQUAL( psa_mac_update( &zero,
2415 input, sizeof( input ) ),
2416 PSA_ERROR_BAD_STATE );
2417
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002418 /* A default MAC operation should be abortable without error. */
2419 PSA_ASSERT( psa_mac_abort( &func ) );
2420 PSA_ASSERT( psa_mac_abort( &init ) );
2421 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002422}
2423/* END_CASE */
2424
2425/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002426void mac_setup( int key_type_arg,
2427 data_t *key,
2428 int alg_arg,
2429 int expected_status_arg )
2430{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002431 psa_key_type_t key_type = key_type_arg;
2432 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002433 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002434 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002435 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2436#if defined(KNOWN_SUPPORTED_MAC_ALG)
2437 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2438#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002439
Gilles Peskine8817f612018-12-18 00:18:46 +01002440 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002441
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002442 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2443 &operation, &status ) )
2444 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002445 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002446
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002447 /* The operation object should be reusable. */
2448#if defined(KNOWN_SUPPORTED_MAC_ALG)
2449 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2450 smoke_test_key_data,
2451 sizeof( smoke_test_key_data ),
2452 KNOWN_SUPPORTED_MAC_ALG,
2453 &operation, &status ) )
2454 goto exit;
2455 TEST_EQUAL( status, PSA_SUCCESS );
2456#endif
2457
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002458exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002459 mbedtls_psa_crypto_free( );
2460}
2461/* END_CASE */
2462
2463/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002464void mac_bad_order( )
2465{
2466 psa_key_handle_t handle = 0;
2467 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2468 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2469 const uint8_t key[] = {
2470 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2471 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2472 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002473 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002474 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2475 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2476 size_t sign_mac_length = 0;
2477 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2478 const uint8_t verify_mac[] = {
2479 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2480 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2481 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2482
2483 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002484 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2485 psa_set_key_algorithm( &attributes, alg );
2486 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002487
Gilles Peskine73676cb2019-05-15 20:15:10 +02002488 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002489
Jaeden Amero252ef282019-02-15 14:05:35 +00002490 /* Call update without calling setup beforehand. */
2491 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2492 PSA_ERROR_BAD_STATE );
2493 PSA_ASSERT( psa_mac_abort( &operation ) );
2494
2495 /* Call sign finish without calling setup beforehand. */
2496 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2497 &sign_mac_length),
2498 PSA_ERROR_BAD_STATE );
2499 PSA_ASSERT( psa_mac_abort( &operation ) );
2500
2501 /* Call verify finish without calling setup beforehand. */
2502 TEST_EQUAL( psa_mac_verify_finish( &operation,
2503 verify_mac, sizeof( verify_mac ) ),
2504 PSA_ERROR_BAD_STATE );
2505 PSA_ASSERT( psa_mac_abort( &operation ) );
2506
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002507 /* Call setup twice in a row. */
2508 PSA_ASSERT( psa_mac_sign_setup( &operation,
2509 handle, alg ) );
2510 TEST_EQUAL( psa_mac_sign_setup( &operation,
2511 handle, alg ),
2512 PSA_ERROR_BAD_STATE );
2513 PSA_ASSERT( psa_mac_abort( &operation ) );
2514
Jaeden Amero252ef282019-02-15 14:05:35 +00002515 /* Call update after sign finish. */
2516 PSA_ASSERT( psa_mac_sign_setup( &operation,
2517 handle, alg ) );
2518 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2519 PSA_ASSERT( psa_mac_sign_finish( &operation,
2520 sign_mac, sizeof( sign_mac ),
2521 &sign_mac_length ) );
2522 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2523 PSA_ERROR_BAD_STATE );
2524 PSA_ASSERT( psa_mac_abort( &operation ) );
2525
2526 /* Call update after verify finish. */
2527 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002528 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002529 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2530 PSA_ASSERT( psa_mac_verify_finish( &operation,
2531 verify_mac, sizeof( verify_mac ) ) );
2532 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2533 PSA_ERROR_BAD_STATE );
2534 PSA_ASSERT( psa_mac_abort( &operation ) );
2535
2536 /* Call sign finish twice in a row. */
2537 PSA_ASSERT( psa_mac_sign_setup( &operation,
2538 handle, alg ) );
2539 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2540 PSA_ASSERT( psa_mac_sign_finish( &operation,
2541 sign_mac, sizeof( sign_mac ),
2542 &sign_mac_length ) );
2543 TEST_EQUAL( psa_mac_sign_finish( &operation,
2544 sign_mac, sizeof( sign_mac ),
2545 &sign_mac_length ),
2546 PSA_ERROR_BAD_STATE );
2547 PSA_ASSERT( psa_mac_abort( &operation ) );
2548
2549 /* Call verify finish twice in a row. */
2550 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002551 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002552 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2553 PSA_ASSERT( psa_mac_verify_finish( &operation,
2554 verify_mac, sizeof( verify_mac ) ) );
2555 TEST_EQUAL( psa_mac_verify_finish( &operation,
2556 verify_mac, sizeof( verify_mac ) ),
2557 PSA_ERROR_BAD_STATE );
2558 PSA_ASSERT( psa_mac_abort( &operation ) );
2559
2560 /* Setup sign but try verify. */
2561 PSA_ASSERT( psa_mac_sign_setup( &operation,
2562 handle, alg ) );
2563 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2564 TEST_EQUAL( psa_mac_verify_finish( &operation,
2565 verify_mac, sizeof( verify_mac ) ),
2566 PSA_ERROR_BAD_STATE );
2567 PSA_ASSERT( psa_mac_abort( &operation ) );
2568
2569 /* Setup verify but try sign. */
2570 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002571 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002572 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2573 TEST_EQUAL( psa_mac_sign_finish( &operation,
2574 sign_mac, sizeof( sign_mac ),
2575 &sign_mac_length ),
2576 PSA_ERROR_BAD_STATE );
2577 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002578
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002579exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002580 mbedtls_psa_crypto_free( );
2581}
2582/* END_CASE */
2583
2584/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002585void mac_sign( int key_type_arg,
2586 data_t *key,
2587 int alg_arg,
2588 data_t *input,
2589 data_t *expected_mac )
2590{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002591 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002592 psa_key_type_t key_type = key_type_arg;
2593 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002594 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002595 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002596 /* Leave a little extra room in the output buffer. At the end of the
2597 * test, we'll check that the implementation didn't overwrite onto
2598 * this extra room. */
2599 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2600 size_t mac_buffer_size =
2601 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2602 size_t mac_length = 0;
2603
2604 memset( actual_mac, '+', sizeof( actual_mac ) );
2605 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2606 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2607
Gilles Peskine8817f612018-12-18 00:18:46 +01002608 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002609
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002610 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2611 psa_set_key_algorithm( &attributes, alg );
2612 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002613
Gilles Peskine73676cb2019-05-15 20:15:10 +02002614 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002615
2616 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002617 PSA_ASSERT( psa_mac_sign_setup( &operation,
2618 handle, alg ) );
2619 PSA_ASSERT( psa_mac_update( &operation,
2620 input->x, input->len ) );
2621 PSA_ASSERT( psa_mac_sign_finish( &operation,
2622 actual_mac, mac_buffer_size,
2623 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002624
2625 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002626 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2627 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002628
2629 /* Verify that the end of the buffer is untouched. */
2630 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2631 sizeof( actual_mac ) - mac_length ) );
2632
2633exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002634 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002635 mbedtls_psa_crypto_free( );
2636}
2637/* END_CASE */
2638
2639/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002640void mac_verify( int key_type_arg,
2641 data_t *key,
2642 int alg_arg,
2643 data_t *input,
2644 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002645{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002646 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002647 psa_key_type_t key_type = key_type_arg;
2648 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002649 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002650 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002651
Gilles Peskine69c12672018-06-28 00:07:19 +02002652 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2653
Gilles Peskine8817f612018-12-18 00:18:46 +01002654 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002655
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002656 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2657 psa_set_key_algorithm( &attributes, alg );
2658 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002659
Gilles Peskine73676cb2019-05-15 20:15:10 +02002660 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002661
Gilles Peskine8817f612018-12-18 00:18:46 +01002662 PSA_ASSERT( psa_mac_verify_setup( &operation,
2663 handle, alg ) );
2664 PSA_ASSERT( psa_destroy_key( handle ) );
2665 PSA_ASSERT( psa_mac_update( &operation,
2666 input->x, input->len ) );
2667 PSA_ASSERT( psa_mac_verify_finish( &operation,
2668 expected_mac->x,
2669 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002670
2671exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002672 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002673 mbedtls_psa_crypto_free( );
2674}
2675/* END_CASE */
2676
2677/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002678void cipher_operation_init( )
2679{
Jaeden Ameroab439972019-02-15 14:12:05 +00002680 const uint8_t input[1] = { 0 };
2681 unsigned char output[1] = { 0 };
2682 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002683 /* Test each valid way of initializing the object, except for `= {0}`, as
2684 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2685 * though it's OK by the C standard. We could test for this, but we'd need
2686 * to supress the Clang warning for the test. */
2687 psa_cipher_operation_t func = psa_cipher_operation_init( );
2688 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2689 psa_cipher_operation_t zero;
2690
2691 memset( &zero, 0, sizeof( zero ) );
2692
Jaeden Ameroab439972019-02-15 14:12:05 +00002693 /* A freshly-initialized cipher operation should not be usable. */
2694 TEST_EQUAL( psa_cipher_update( &func,
2695 input, sizeof( input ),
2696 output, sizeof( output ),
2697 &output_length ),
2698 PSA_ERROR_BAD_STATE );
2699 TEST_EQUAL( psa_cipher_update( &init,
2700 input, sizeof( input ),
2701 output, sizeof( output ),
2702 &output_length ),
2703 PSA_ERROR_BAD_STATE );
2704 TEST_EQUAL( psa_cipher_update( &zero,
2705 input, sizeof( input ),
2706 output, sizeof( output ),
2707 &output_length ),
2708 PSA_ERROR_BAD_STATE );
2709
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002710 /* A default cipher operation should be abortable without error. */
2711 PSA_ASSERT( psa_cipher_abort( &func ) );
2712 PSA_ASSERT( psa_cipher_abort( &init ) );
2713 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002714}
2715/* END_CASE */
2716
2717/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002718void cipher_setup( int key_type_arg,
2719 data_t *key,
2720 int alg_arg,
2721 int expected_status_arg )
2722{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002723 psa_key_type_t key_type = key_type_arg;
2724 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002725 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002726 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002727 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002728#if defined(KNOWN_SUPPORTED_MAC_ALG)
2729 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2730#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002731
Gilles Peskine8817f612018-12-18 00:18:46 +01002732 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002733
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002734 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2735 &operation, &status ) )
2736 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002737 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002738
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002739 /* The operation object should be reusable. */
2740#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2741 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2742 smoke_test_key_data,
2743 sizeof( smoke_test_key_data ),
2744 KNOWN_SUPPORTED_CIPHER_ALG,
2745 &operation, &status ) )
2746 goto exit;
2747 TEST_EQUAL( status, PSA_SUCCESS );
2748#endif
2749
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002750exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002751 mbedtls_psa_crypto_free( );
2752}
2753/* END_CASE */
2754
2755/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002756void cipher_bad_order( )
2757{
2758 psa_key_handle_t handle = 0;
2759 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2760 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002761 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002762 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2763 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2764 const uint8_t key[] = {
2765 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2766 0xaa, 0xaa, 0xaa, 0xaa };
2767 const uint8_t text[] = {
2768 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2769 0xbb, 0xbb, 0xbb, 0xbb };
2770 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2771 size_t length = 0;
2772
2773 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002774 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2775 psa_set_key_algorithm( &attributes, alg );
2776 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002777 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002778
2779
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002780 /* Call encrypt setup twice in a row. */
2781 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2782 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2783 PSA_ERROR_BAD_STATE );
2784 PSA_ASSERT( psa_cipher_abort( &operation ) );
2785
2786 /* Call decrypt setup twice in a row. */
2787 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2788 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2789 PSA_ERROR_BAD_STATE );
2790 PSA_ASSERT( psa_cipher_abort( &operation ) );
2791
Jaeden Ameroab439972019-02-15 14:12:05 +00002792 /* Generate an IV without calling setup beforehand. */
2793 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2794 buffer, sizeof( buffer ),
2795 &length ),
2796 PSA_ERROR_BAD_STATE );
2797 PSA_ASSERT( psa_cipher_abort( &operation ) );
2798
2799 /* Generate an IV twice in a row. */
2800 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2801 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2802 buffer, sizeof( buffer ),
2803 &length ) );
2804 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2805 buffer, sizeof( buffer ),
2806 &length ),
2807 PSA_ERROR_BAD_STATE );
2808 PSA_ASSERT( psa_cipher_abort( &operation ) );
2809
2810 /* Generate an IV after it's already set. */
2811 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2812 PSA_ASSERT( psa_cipher_set_iv( &operation,
2813 iv, sizeof( iv ) ) );
2814 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2815 buffer, sizeof( buffer ),
2816 &length ),
2817 PSA_ERROR_BAD_STATE );
2818 PSA_ASSERT( psa_cipher_abort( &operation ) );
2819
2820 /* Set an IV without calling setup beforehand. */
2821 TEST_EQUAL( psa_cipher_set_iv( &operation,
2822 iv, sizeof( iv ) ),
2823 PSA_ERROR_BAD_STATE );
2824 PSA_ASSERT( psa_cipher_abort( &operation ) );
2825
2826 /* Set an IV after it's already set. */
2827 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2828 PSA_ASSERT( psa_cipher_set_iv( &operation,
2829 iv, sizeof( iv ) ) );
2830 TEST_EQUAL( psa_cipher_set_iv( &operation,
2831 iv, sizeof( iv ) ),
2832 PSA_ERROR_BAD_STATE );
2833 PSA_ASSERT( psa_cipher_abort( &operation ) );
2834
2835 /* Set an IV after it's already generated. */
2836 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2837 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2838 buffer, sizeof( buffer ),
2839 &length ) );
2840 TEST_EQUAL( psa_cipher_set_iv( &operation,
2841 iv, sizeof( iv ) ),
2842 PSA_ERROR_BAD_STATE );
2843 PSA_ASSERT( psa_cipher_abort( &operation ) );
2844
2845 /* Call update without calling setup beforehand. */
2846 TEST_EQUAL( psa_cipher_update( &operation,
2847 text, sizeof( text ),
2848 buffer, sizeof( buffer ),
2849 &length ),
2850 PSA_ERROR_BAD_STATE );
2851 PSA_ASSERT( psa_cipher_abort( &operation ) );
2852
2853 /* Call update without an IV where an IV is required. */
2854 TEST_EQUAL( psa_cipher_update( &operation,
2855 text, sizeof( text ),
2856 buffer, sizeof( buffer ),
2857 &length ),
2858 PSA_ERROR_BAD_STATE );
2859 PSA_ASSERT( psa_cipher_abort( &operation ) );
2860
2861 /* Call update after finish. */
2862 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2863 PSA_ASSERT( psa_cipher_set_iv( &operation,
2864 iv, sizeof( iv ) ) );
2865 PSA_ASSERT( psa_cipher_finish( &operation,
2866 buffer, sizeof( buffer ), &length ) );
2867 TEST_EQUAL( psa_cipher_update( &operation,
2868 text, sizeof( text ),
2869 buffer, sizeof( buffer ),
2870 &length ),
2871 PSA_ERROR_BAD_STATE );
2872 PSA_ASSERT( psa_cipher_abort( &operation ) );
2873
2874 /* Call finish without calling setup beforehand. */
2875 TEST_EQUAL( psa_cipher_finish( &operation,
2876 buffer, sizeof( buffer ), &length ),
2877 PSA_ERROR_BAD_STATE );
2878 PSA_ASSERT( psa_cipher_abort( &operation ) );
2879
2880 /* Call finish without an IV where an IV is required. */
2881 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2882 /* Not calling update means we are encrypting an empty buffer, which is OK
2883 * for cipher modes with padding. */
2884 TEST_EQUAL( psa_cipher_finish( &operation,
2885 buffer, sizeof( buffer ), &length ),
2886 PSA_ERROR_BAD_STATE );
2887 PSA_ASSERT( psa_cipher_abort( &operation ) );
2888
2889 /* Call finish twice in a row. */
2890 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2891 PSA_ASSERT( psa_cipher_set_iv( &operation,
2892 iv, sizeof( iv ) ) );
2893 PSA_ASSERT( psa_cipher_finish( &operation,
2894 buffer, sizeof( buffer ), &length ) );
2895 TEST_EQUAL( psa_cipher_finish( &operation,
2896 buffer, sizeof( buffer ), &length ),
2897 PSA_ERROR_BAD_STATE );
2898 PSA_ASSERT( psa_cipher_abort( &operation ) );
2899
2900exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002901 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002902}
2903/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002904
Gilles Peskine50e586b2018-06-08 14:28:46 +02002905/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002906void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002907 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002908 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002909 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002910{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002911 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002912 psa_status_t status;
2913 psa_key_type_t key_type = key_type_arg;
2914 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002915 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002916 unsigned char *output = NULL;
2917 size_t output_buffer_size = 0;
2918 size_t function_output_length = 0;
2919 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002920 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002921 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002922
Gilles Peskine8817f612018-12-18 00:18:46 +01002923 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002925 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2926 psa_set_key_algorithm( &attributes, alg );
2927 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002928
Gilles Peskine73676cb2019-05-15 20:15:10 +02002929 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002930
Gilles Peskine8817f612018-12-18 00:18:46 +01002931 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2932 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933
Gilles Peskine423005e2019-05-06 15:22:57 +02002934 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002935 output_buffer_size = ( (size_t) input->len +
2936 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002937 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002938
Gilles Peskine8817f612018-12-18 00:18:46 +01002939 PSA_ASSERT( psa_cipher_update( &operation,
2940 input->x, input->len,
2941 output, output_buffer_size,
2942 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002943 total_output_length += function_output_length;
2944 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002945 output + total_output_length,
2946 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002947 &function_output_length );
2948 total_output_length += function_output_length;
2949
Gilles Peskinefe11b722018-12-18 00:24:04 +01002950 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002951 if( expected_status == PSA_SUCCESS )
2952 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002953 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002954 ASSERT_COMPARE( expected_output->x, expected_output->len,
2955 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002956 }
2957
2958exit:
2959 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002960 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002961 mbedtls_psa_crypto_free( );
2962}
2963/* END_CASE */
2964
2965/* BEGIN_CASE */
2966void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002967 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002968 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002969 int first_part_size_arg,
2970 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002971 data_t *expected_output )
2972{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002973 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002974 psa_key_type_t key_type = key_type_arg;
2975 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002976 size_t first_part_size = first_part_size_arg;
2977 size_t output1_length = output1_length_arg;
2978 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002979 unsigned char *output = NULL;
2980 size_t output_buffer_size = 0;
2981 size_t function_output_length = 0;
2982 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002983 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002984 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002985
Gilles Peskine8817f612018-12-18 00:18:46 +01002986 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002987
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002988 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2989 psa_set_key_algorithm( &attributes, alg );
2990 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002991
Gilles Peskine73676cb2019-05-15 20:15:10 +02002992 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002993
Gilles Peskine8817f612018-12-18 00:18:46 +01002994 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2995 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002996
Gilles Peskine423005e2019-05-06 15:22:57 +02002997 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002998 output_buffer_size = ( (size_t) input->len +
2999 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003000 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003001
Gilles Peskinee0866522019-02-19 19:44:00 +01003002 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003003 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3004 output, output_buffer_size,
3005 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003006 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003007 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003008 PSA_ASSERT( psa_cipher_update( &operation,
3009 input->x + first_part_size,
3010 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003011 output + total_output_length,
3012 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003013 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003014 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003015 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003016 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003017 output + total_output_length,
3018 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003019 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003020 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003021 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003022
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003023 ASSERT_COMPARE( expected_output->x, expected_output->len,
3024 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003025
3026exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003027 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003028 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003029 mbedtls_psa_crypto_free( );
3030}
3031/* END_CASE */
3032
3033/* BEGIN_CASE */
3034void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003035 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003036 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003037 int first_part_size_arg,
3038 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003039 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003040{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003041 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003042
3043 psa_key_type_t key_type = key_type_arg;
3044 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003045 size_t first_part_size = first_part_size_arg;
3046 size_t output1_length = output1_length_arg;
3047 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003048 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003049 size_t output_buffer_size = 0;
3050 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003051 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003052 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003053 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003054
Gilles Peskine8817f612018-12-18 00:18:46 +01003055 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003056
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003057 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3058 psa_set_key_algorithm( &attributes, alg );
3059 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003060
Gilles Peskine73676cb2019-05-15 20:15:10 +02003061 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003062
Gilles Peskine8817f612018-12-18 00:18:46 +01003063 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3064 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065
Gilles Peskine423005e2019-05-06 15:22:57 +02003066 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003067
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003068 output_buffer_size = ( (size_t) input->len +
3069 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003070 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003071
Gilles Peskinee0866522019-02-19 19:44:00 +01003072 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003073 PSA_ASSERT( psa_cipher_update( &operation,
3074 input->x, first_part_size,
3075 output, output_buffer_size,
3076 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003077 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003078 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003079 PSA_ASSERT( psa_cipher_update( &operation,
3080 input->x + first_part_size,
3081 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003082 output + total_output_length,
3083 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003084 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003085 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003086 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003087 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003088 output + total_output_length,
3089 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003090 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003091 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003092 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003093
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003094 ASSERT_COMPARE( expected_output->x, expected_output->len,
3095 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003096
3097exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003098 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003099 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003100 mbedtls_psa_crypto_free( );
3101}
3102/* END_CASE */
3103
Gilles Peskine50e586b2018-06-08 14:28:46 +02003104/* BEGIN_CASE */
3105void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003106 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003107 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003108 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003109{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003110 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003111 psa_status_t status;
3112 psa_key_type_t key_type = key_type_arg;
3113 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003114 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003115 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003116 size_t output_buffer_size = 0;
3117 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003118 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003119 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003120 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003121
Gilles Peskine8817f612018-12-18 00:18:46 +01003122 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003123
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003124 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3125 psa_set_key_algorithm( &attributes, alg );
3126 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003127
Gilles Peskine73676cb2019-05-15 20:15:10 +02003128 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003129
Gilles Peskine8817f612018-12-18 00:18:46 +01003130 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3131 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003132
Gilles Peskine423005e2019-05-06 15:22:57 +02003133 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003134
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003135 output_buffer_size = ( (size_t) input->len +
3136 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003137 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003138
Gilles Peskine8817f612018-12-18 00:18:46 +01003139 PSA_ASSERT( psa_cipher_update( &operation,
3140 input->x, input->len,
3141 output, output_buffer_size,
3142 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003143 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003144 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003145 output + total_output_length,
3146 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003147 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003148 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003149 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003150
3151 if( expected_status == PSA_SUCCESS )
3152 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003153 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003154 ASSERT_COMPARE( expected_output->x, expected_output->len,
3155 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003156 }
3157
Gilles Peskine50e586b2018-06-08 14:28:46 +02003158exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003159 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003160 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003161 mbedtls_psa_crypto_free( );
3162}
3163/* END_CASE */
3164
Gilles Peskine50e586b2018-06-08 14:28:46 +02003165/* BEGIN_CASE */
3166void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003167 data_t *key,
3168 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003169{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003170 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003171 psa_key_type_t key_type = key_type_arg;
3172 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003173 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003174 size_t iv_size = 16;
3175 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003176 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003177 size_t output1_size = 0;
3178 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003179 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003180 size_t output2_size = 0;
3181 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003182 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003183 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3184 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003185 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003186
Gilles Peskine8817f612018-12-18 00:18:46 +01003187 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003188
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003189 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3190 psa_set_key_algorithm( &attributes, alg );
3191 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003192
Gilles Peskine73676cb2019-05-15 20:15:10 +02003193 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003194
Gilles Peskine8817f612018-12-18 00:18:46 +01003195 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3196 handle, alg ) );
3197 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3198 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003199
Gilles Peskine8817f612018-12-18 00:18:46 +01003200 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3201 iv, iv_size,
3202 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003203 output1_size = ( (size_t) input->len +
3204 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003205 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003206
Gilles Peskine8817f612018-12-18 00:18:46 +01003207 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3208 output1, output1_size,
3209 &output1_length ) );
3210 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003211 output1 + output1_length,
3212 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003213 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003214
Gilles Peskine048b7f02018-06-08 14:20:49 +02003215 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003216
Gilles Peskine8817f612018-12-18 00:18:46 +01003217 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003218
3219 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003220 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003221
Gilles Peskine8817f612018-12-18 00:18:46 +01003222 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3223 iv, iv_length ) );
3224 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3225 output2, output2_size,
3226 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003227 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003228 PSA_ASSERT( psa_cipher_finish( &operation2,
3229 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003230 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003231 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003232
Gilles Peskine048b7f02018-06-08 14:20:49 +02003233 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003234
Gilles Peskine8817f612018-12-18 00:18:46 +01003235 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003236
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003237 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003238
3239exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003240 mbedtls_free( output1 );
3241 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003242 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003243 mbedtls_psa_crypto_free( );
3244}
3245/* END_CASE */
3246
3247/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003248void cipher_verify_output_multipart( int alg_arg,
3249 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003250 data_t *key,
3251 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003252 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003253{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003254 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003255 psa_key_type_t key_type = key_type_arg;
3256 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003257 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003258 unsigned char iv[16] = {0};
3259 size_t iv_size = 16;
3260 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003261 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003262 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003263 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003264 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003265 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003266 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003267 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003268 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3269 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003270 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003271
Gilles Peskine8817f612018-12-18 00:18:46 +01003272 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003273
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003274 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3275 psa_set_key_algorithm( &attributes, alg );
3276 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003277
Gilles Peskine73676cb2019-05-15 20:15:10 +02003278 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003279
Gilles Peskine8817f612018-12-18 00:18:46 +01003280 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3281 handle, alg ) );
3282 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3283 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003284
Gilles Peskine8817f612018-12-18 00:18:46 +01003285 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3286 iv, iv_size,
3287 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003288 output1_buffer_size = ( (size_t) input->len +
3289 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003290 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003291
Gilles Peskinee0866522019-02-19 19:44:00 +01003292 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003293
Gilles Peskine8817f612018-12-18 00:18:46 +01003294 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3295 output1, output1_buffer_size,
3296 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003297 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003298
Gilles Peskine8817f612018-12-18 00:18:46 +01003299 PSA_ASSERT( psa_cipher_update( &operation1,
3300 input->x + first_part_size,
3301 input->len - first_part_size,
3302 output1, output1_buffer_size,
3303 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003304 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003305
Gilles Peskine8817f612018-12-18 00:18:46 +01003306 PSA_ASSERT( psa_cipher_finish( &operation1,
3307 output1 + output1_length,
3308 output1_buffer_size - output1_length,
3309 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003310 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003311
Gilles Peskine8817f612018-12-18 00:18:46 +01003312 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003313
Gilles Peskine048b7f02018-06-08 14:20:49 +02003314 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003315 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003316
Gilles Peskine8817f612018-12-18 00:18:46 +01003317 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3318 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003319
Gilles Peskine8817f612018-12-18 00:18:46 +01003320 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3321 output2, output2_buffer_size,
3322 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003323 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003324
Gilles Peskine8817f612018-12-18 00:18:46 +01003325 PSA_ASSERT( psa_cipher_update( &operation2,
3326 output1 + first_part_size,
3327 output1_length - first_part_size,
3328 output2, output2_buffer_size,
3329 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003330 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003331
Gilles Peskine8817f612018-12-18 00:18:46 +01003332 PSA_ASSERT( psa_cipher_finish( &operation2,
3333 output2 + output2_length,
3334 output2_buffer_size - output2_length,
3335 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003336 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003337
Gilles Peskine8817f612018-12-18 00:18:46 +01003338 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003339
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003340 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003341
3342exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003343 mbedtls_free( output1 );
3344 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003345 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003346 mbedtls_psa_crypto_free( );
3347}
3348/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003349
Gilles Peskine20035e32018-02-03 22:44:14 +01003350/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003351void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003352 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003353 data_t *nonce,
3354 data_t *additional_data,
3355 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003356 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003357{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003358 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003359 psa_key_type_t key_type = key_type_arg;
3360 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003361 unsigned char *output_data = NULL;
3362 size_t output_size = 0;
3363 size_t output_length = 0;
3364 unsigned char *output_data2 = NULL;
3365 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003366 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003367 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003368 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003369
Gilles Peskine4abf7412018-06-18 16:35:34 +02003370 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003371 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3372 * should be exact. */
3373 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3374 TEST_EQUAL( output_size,
3375 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003376 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003377
Gilles Peskine8817f612018-12-18 00:18:46 +01003378 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003379
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003380 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3381 psa_set_key_algorithm( &attributes, alg );
3382 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003383
Gilles Peskine049c7532019-05-15 20:22:09 +02003384 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3385 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003386
Gilles Peskinefe11b722018-12-18 00:24:04 +01003387 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3388 nonce->x, nonce->len,
3389 additional_data->x,
3390 additional_data->len,
3391 input_data->x, input_data->len,
3392 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003393 &output_length ),
3394 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003395
3396 if( PSA_SUCCESS == expected_result )
3397 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003398 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003399
Gilles Peskine003a4a92019-05-14 16:09:40 +02003400 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3401 * should be exact. */
3402 TEST_EQUAL( input_data->len,
3403 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3404
Gilles Peskinefe11b722018-12-18 00:24:04 +01003405 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3406 nonce->x, nonce->len,
3407 additional_data->x,
3408 additional_data->len,
3409 output_data, output_length,
3410 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003411 &output_length2 ),
3412 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003413
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003414 ASSERT_COMPARE( input_data->x, input_data->len,
3415 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003416 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003417
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003419 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003420 mbedtls_free( output_data );
3421 mbedtls_free( output_data2 );
3422 mbedtls_psa_crypto_free( );
3423}
3424/* END_CASE */
3425
3426/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003427void aead_encrypt( int key_type_arg, data_t *key_data,
3428 int alg_arg,
3429 data_t *nonce,
3430 data_t *additional_data,
3431 data_t *input_data,
3432 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003433{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003434 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435 psa_key_type_t key_type = key_type_arg;
3436 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003437 unsigned char *output_data = NULL;
3438 size_t output_size = 0;
3439 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003440 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003441 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003442
Gilles Peskine4abf7412018-06-18 16:35:34 +02003443 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003444 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3445 * should be exact. */
3446 TEST_EQUAL( output_size,
3447 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003448 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003449
Gilles Peskine8817f612018-12-18 00:18:46 +01003450 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003451
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003452 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3453 psa_set_key_algorithm( &attributes, alg );
3454 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003455
Gilles Peskine049c7532019-05-15 20:22:09 +02003456 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3457 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003458
Gilles Peskine8817f612018-12-18 00:18:46 +01003459 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3460 nonce->x, nonce->len,
3461 additional_data->x, additional_data->len,
3462 input_data->x, input_data->len,
3463 output_data, output_size,
3464 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003465
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003466 ASSERT_COMPARE( expected_result->x, expected_result->len,
3467 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003468
Gilles Peskinea1cac842018-06-11 19:33:02 +02003469exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003470 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003471 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003472 mbedtls_psa_crypto_free( );
3473}
3474/* END_CASE */
3475
3476/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003477void aead_decrypt( int key_type_arg, data_t *key_data,
3478 int alg_arg,
3479 data_t *nonce,
3480 data_t *additional_data,
3481 data_t *input_data,
3482 data_t *expected_data,
3483 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003484{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003485 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003486 psa_key_type_t key_type = key_type_arg;
3487 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488 unsigned char *output_data = NULL;
3489 size_t output_size = 0;
3490 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003491 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003492 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003493 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003494
Gilles Peskine003a4a92019-05-14 16:09:40 +02003495 output_size = input_data->len - tag_length;
3496 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3497 * should be exact. */
3498 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3499 TEST_EQUAL( output_size,
3500 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003501 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003502
Gilles Peskine8817f612018-12-18 00:18:46 +01003503 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003504
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003505 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3506 psa_set_key_algorithm( &attributes, alg );
3507 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003508
Gilles Peskine049c7532019-05-15 20:22:09 +02003509 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3510 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003511
Gilles Peskinefe11b722018-12-18 00:24:04 +01003512 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3513 nonce->x, nonce->len,
3514 additional_data->x,
3515 additional_data->len,
3516 input_data->x, input_data->len,
3517 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003518 &output_length ),
3519 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003520
Gilles Peskine2d277862018-06-18 15:41:12 +02003521 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003522 ASSERT_COMPARE( expected_data->x, expected_data->len,
3523 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003524
Gilles Peskinea1cac842018-06-11 19:33:02 +02003525exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003526 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003527 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003528 mbedtls_psa_crypto_free( );
3529}
3530/* END_CASE */
3531
3532/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003533void signature_size( int type_arg,
3534 int bits,
3535 int alg_arg,
3536 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003537{
3538 psa_key_type_t type = type_arg;
3539 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003540 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003541 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003542exit:
3543 ;
3544}
3545/* END_CASE */
3546
3547/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003548void sign_deterministic( int key_type_arg, data_t *key_data,
3549 int alg_arg, data_t *input_data,
3550 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003551{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003552 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003553 psa_key_type_t key_type = key_type_arg;
3554 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003555 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003556 unsigned char *signature = NULL;
3557 size_t signature_size;
3558 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003559 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003560
Gilles Peskine8817f612018-12-18 00:18:46 +01003561 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003562
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003563 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3564 psa_set_key_algorithm( &attributes, alg );
3565 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003566
Gilles Peskine049c7532019-05-15 20:22:09 +02003567 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3568 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003569 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3570 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003571
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003572 /* Allocate a buffer which has the size advertized by the
3573 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003574 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3575 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003576 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003577 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003578 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003579
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003580 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003581 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3582 input_data->x, input_data->len,
3583 signature, signature_size,
3584 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003585 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003586 ASSERT_COMPARE( output_data->x, output_data->len,
3587 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003588
3589exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003590 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003591 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003592 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003593 mbedtls_psa_crypto_free( );
3594}
3595/* END_CASE */
3596
3597/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003598void sign_fail( int key_type_arg, data_t *key_data,
3599 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003600 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003601{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003602 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003603 psa_key_type_t key_type = key_type_arg;
3604 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003605 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003606 psa_status_t actual_status;
3607 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003608 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003609 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003610 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003611
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003612 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003613
Gilles Peskine8817f612018-12-18 00:18:46 +01003614 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003615
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003616 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3617 psa_set_key_algorithm( &attributes, alg );
3618 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003619
Gilles Peskine049c7532019-05-15 20:22:09 +02003620 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3621 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003622
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003623 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003624 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003625 signature, signature_size,
3626 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003627 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003628 /* The value of *signature_length is unspecified on error, but
3629 * whatever it is, it should be less than signature_size, so that
3630 * if the caller tries to read *signature_length bytes without
3631 * checking the error code then they don't overflow a buffer. */
3632 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003633
3634exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003635 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003636 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003637 mbedtls_free( signature );
3638 mbedtls_psa_crypto_free( );
3639}
3640/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003641
3642/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003643void sign_verify( int key_type_arg, data_t *key_data,
3644 int alg_arg, data_t *input_data )
3645{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003646 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003647 psa_key_type_t key_type = key_type_arg;
3648 psa_algorithm_t alg = alg_arg;
3649 size_t key_bits;
3650 unsigned char *signature = NULL;
3651 size_t signature_size;
3652 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003653 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003654
Gilles Peskine8817f612018-12-18 00:18:46 +01003655 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003656
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003657 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3658 psa_set_key_algorithm( &attributes, alg );
3659 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003660
Gilles Peskine049c7532019-05-15 20:22:09 +02003661 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3662 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003663 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3664 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003665
3666 /* Allocate a buffer which has the size advertized by the
3667 * library. */
3668 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3669 key_bits, alg );
3670 TEST_ASSERT( signature_size != 0 );
3671 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003672 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003673
3674 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003675 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3676 input_data->x, input_data->len,
3677 signature, signature_size,
3678 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003679 /* Check that the signature length looks sensible. */
3680 TEST_ASSERT( signature_length <= signature_size );
3681 TEST_ASSERT( signature_length > 0 );
3682
3683 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003684 PSA_ASSERT( psa_asymmetric_verify(
3685 handle, alg,
3686 input_data->x, input_data->len,
3687 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003688
3689 if( input_data->len != 0 )
3690 {
3691 /* Flip a bit in the input and verify that the signature is now
3692 * detected as invalid. Flip a bit at the beginning, not at the end,
3693 * because ECDSA may ignore the last few bits of the input. */
3694 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003695 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3696 input_data->x, input_data->len,
3697 signature, signature_length ),
3698 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003699 }
3700
3701exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003702 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003703 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003704 mbedtls_free( signature );
3705 mbedtls_psa_crypto_free( );
3706}
3707/* END_CASE */
3708
3709/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003710void asymmetric_verify( int key_type_arg, data_t *key_data,
3711 int alg_arg, data_t *hash_data,
3712 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003713{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003714 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003715 psa_key_type_t key_type = key_type_arg;
3716 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003717 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003718
Gilles Peskine69c12672018-06-28 00:07:19 +02003719 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3720
Gilles Peskine8817f612018-12-18 00:18:46 +01003721 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003722
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003723 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3724 psa_set_key_algorithm( &attributes, alg );
3725 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003726
Gilles Peskine049c7532019-05-15 20:22:09 +02003727 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3728 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003729
Gilles Peskine8817f612018-12-18 00:18:46 +01003730 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3731 hash_data->x, hash_data->len,
3732 signature_data->x,
3733 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003734exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003735 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003736 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003737 mbedtls_psa_crypto_free( );
3738}
3739/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003740
3741/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003742void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3743 int alg_arg, data_t *hash_data,
3744 data_t *signature_data,
3745 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003746{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003747 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003748 psa_key_type_t key_type = key_type_arg;
3749 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003750 psa_status_t actual_status;
3751 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003752 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003753
Gilles Peskine8817f612018-12-18 00:18:46 +01003754 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003755
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003756 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3757 psa_set_key_algorithm( &attributes, alg );
3758 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003759
Gilles Peskine049c7532019-05-15 20:22:09 +02003760 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3761 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003762
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003763 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003764 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003765 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003766 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003767
Gilles Peskinefe11b722018-12-18 00:24:04 +01003768 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003769
3770exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003771 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003772 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003773 mbedtls_psa_crypto_free( );
3774}
3775/* END_CASE */
3776
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003777/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003778void asymmetric_encrypt( int key_type_arg,
3779 data_t *key_data,
3780 int alg_arg,
3781 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003782 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003783 int expected_output_length_arg,
3784 int expected_status_arg )
3785{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003786 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003787 psa_key_type_t key_type = key_type_arg;
3788 psa_algorithm_t alg = alg_arg;
3789 size_t expected_output_length = expected_output_length_arg;
3790 size_t key_bits;
3791 unsigned char *output = NULL;
3792 size_t output_size;
3793 size_t output_length = ~0;
3794 psa_status_t actual_status;
3795 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003796 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003797
Gilles Peskine8817f612018-12-18 00:18:46 +01003798 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003799
Gilles Peskine656896e2018-06-29 19:12:28 +02003800 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003801 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3802 psa_set_key_algorithm( &attributes, alg );
3803 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003804 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3805 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003806
3807 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003808 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3809 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003810 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003811 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003812
3813 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003814 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003815 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003816 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003817 output, output_size,
3818 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003819 TEST_EQUAL( actual_status, expected_status );
3820 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003821
Gilles Peskine68428122018-06-30 18:42:41 +02003822 /* If the label is empty, the test framework puts a non-null pointer
3823 * in label->x. Test that a null pointer works as well. */
3824 if( label->len == 0 )
3825 {
3826 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003827 if( output_size != 0 )
3828 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003829 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003830 input_data->x, input_data->len,
3831 NULL, label->len,
3832 output, output_size,
3833 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003834 TEST_EQUAL( actual_status, expected_status );
3835 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003836 }
3837
Gilles Peskine656896e2018-06-29 19:12:28 +02003838exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003839 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003840 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003841 mbedtls_free( output );
3842 mbedtls_psa_crypto_free( );
3843}
3844/* END_CASE */
3845
3846/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003847void asymmetric_encrypt_decrypt( int key_type_arg,
3848 data_t *key_data,
3849 int alg_arg,
3850 data_t *input_data,
3851 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003852{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003853 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003854 psa_key_type_t key_type = key_type_arg;
3855 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003856 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003857 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003858 size_t output_size;
3859 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003860 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003861 size_t output2_size;
3862 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003863 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003864
Gilles Peskine8817f612018-12-18 00:18:46 +01003865 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003866
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003867 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3868 psa_set_key_algorithm( &attributes, alg );
3869 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003870
Gilles Peskine049c7532019-05-15 20:22:09 +02003871 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3872 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003873
3874 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003875 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3876 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003877 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003878 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003879 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003880 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003881
Gilles Peskineeebd7382018-06-08 18:11:54 +02003882 /* We test encryption by checking that encrypt-then-decrypt gives back
3883 * the original plaintext because of the non-optional random
3884 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003885 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3886 input_data->x, input_data->len,
3887 label->x, label->len,
3888 output, output_size,
3889 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003890 /* We don't know what ciphertext length to expect, but check that
3891 * it looks sensible. */
3892 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003893
Gilles Peskine8817f612018-12-18 00:18:46 +01003894 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3895 output, output_length,
3896 label->x, label->len,
3897 output2, output2_size,
3898 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003899 ASSERT_COMPARE( input_data->x, input_data->len,
3900 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003901
3902exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003903 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003904 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003905 mbedtls_free( output );
3906 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003907 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003908}
3909/* END_CASE */
3910
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003911/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003912void asymmetric_decrypt( int key_type_arg,
3913 data_t *key_data,
3914 int alg_arg,
3915 data_t *input_data,
3916 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003917 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003918{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003919 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003920 psa_key_type_t key_type = key_type_arg;
3921 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003922 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003923 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003924 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003925 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003926
Jaeden Amero412654a2019-02-06 12:57:46 +00003927 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003928 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003929
Gilles Peskine8817f612018-12-18 00:18:46 +01003930 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003931
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003932 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3933 psa_set_key_algorithm( &attributes, alg );
3934 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003935
Gilles Peskine049c7532019-05-15 20:22:09 +02003936 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3937 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003938
Gilles Peskine8817f612018-12-18 00:18:46 +01003939 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3940 input_data->x, input_data->len,
3941 label->x, label->len,
3942 output,
3943 output_size,
3944 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003945 ASSERT_COMPARE( expected_data->x, expected_data->len,
3946 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003947
Gilles Peskine68428122018-06-30 18:42:41 +02003948 /* If the label is empty, the test framework puts a non-null pointer
3949 * in label->x. Test that a null pointer works as well. */
3950 if( label->len == 0 )
3951 {
3952 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003953 if( output_size != 0 )
3954 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003955 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3956 input_data->x, input_data->len,
3957 NULL, label->len,
3958 output,
3959 output_size,
3960 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003961 ASSERT_COMPARE( expected_data->x, expected_data->len,
3962 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003963 }
3964
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003965exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003966 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003967 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003968 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003969 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003970}
3971/* END_CASE */
3972
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003973/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003974void asymmetric_decrypt_fail( int key_type_arg,
3975 data_t *key_data,
3976 int alg_arg,
3977 data_t *input_data,
3978 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003979 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003980 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003981{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003982 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003983 psa_key_type_t key_type = key_type_arg;
3984 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003985 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003986 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003987 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003988 psa_status_t actual_status;
3989 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003990 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003991
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003992 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003993
Gilles Peskine8817f612018-12-18 00:18:46 +01003994 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003995
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003996 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3997 psa_set_key_algorithm( &attributes, alg );
3998 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003999
Gilles Peskine049c7532019-05-15 20:22:09 +02004000 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4001 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004002
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004003 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004004 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004005 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004006 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004007 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004008 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004009 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004010
Gilles Peskine68428122018-06-30 18:42:41 +02004011 /* If the label is empty, the test framework puts a non-null pointer
4012 * in label->x. Test that a null pointer works as well. */
4013 if( label->len == 0 )
4014 {
4015 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004016 if( output_size != 0 )
4017 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004018 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004019 input_data->x, input_data->len,
4020 NULL, label->len,
4021 output, output_size,
4022 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004023 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004024 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004025 }
4026
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004027exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004028 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004029 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004030 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004031 mbedtls_psa_crypto_free( );
4032}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004033/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004034
4035/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004036void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004037{
4038 /* Test each valid way of initializing the object, except for `= {0}`, as
4039 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4040 * though it's OK by the C standard. We could test for this, but we'd need
4041 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004042 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004043 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4044 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4045 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004046
4047 memset( &zero, 0, sizeof( zero ) );
4048
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004049 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004050 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004051 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004052 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004053 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004054 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004055 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004056
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004057 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004058 PSA_ASSERT( psa_key_derivation_abort(&func) );
4059 PSA_ASSERT( psa_key_derivation_abort(&init) );
4060 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004061}
4062/* END_CASE */
4063
4064/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004065void derive_setup( int key_type_arg,
4066 data_t *key_data,
4067 int alg_arg,
4068 data_t *salt,
4069 data_t *label,
4070 int requested_capacity_arg,
4071 int expected_status_arg )
4072{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004073 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004074 size_t key_type = key_type_arg;
4075 psa_algorithm_t alg = alg_arg;
4076 size_t requested_capacity = requested_capacity_arg;
4077 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004078 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004079 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004080
Gilles Peskine8817f612018-12-18 00:18:46 +01004081 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004082
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004083 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4084 psa_set_key_algorithm( &attributes, alg );
4085 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004086
Gilles Peskine049c7532019-05-15 20:22:09 +02004087 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4088 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004089
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004090 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004091 salt->x, salt->len,
4092 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004093 requested_capacity ),
4094 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004095
4096exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004097 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004098 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004099 mbedtls_psa_crypto_free( );
4100}
4101/* END_CASE */
4102
4103/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004104void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004105{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004106 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004107 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004108 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004109 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004110 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004111 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004112 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4113 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4114 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004115 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004116
Gilles Peskine8817f612018-12-18 00:18:46 +01004117 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004118
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004119 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4120 psa_set_key_algorithm( &attributes, alg );
4121 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004122
Gilles Peskine73676cb2019-05-15 20:15:10 +02004123 PSA_ASSERT( psa_import_key( &attributes,
4124 key_data, sizeof( key_data ),
4125 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004126
4127 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004128 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004129 NULL, 0,
4130 NULL, 0,
4131 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004132
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004133 /* state of operation shouldn't allow additional generation */
4134 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004135 NULL, 0,
4136 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004137 capacity ),
4138 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004139
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004140 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004141
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004142 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004143 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004144
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004145exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004146 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004147 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004148 mbedtls_psa_crypto_free( );
4149}
4150/* END_CASE */
4151
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004152/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004153void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004154{
4155 uint8_t output_buffer[16];
4156 size_t buffer_size = 16;
4157 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004158 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004159
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004160 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4161 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004162 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004163
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004164 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004165 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004166
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004167 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004168
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004169 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4170 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004171 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004172
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004173 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004174 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004175
4176exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004177 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004178}
4179/* END_CASE */
4180
4181/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004182void derive_output( int alg_arg,
4183 data_t *key_data,
4184 data_t *salt,
4185 data_t *label,
4186 int requested_capacity_arg,
4187 data_t *expected_output1,
4188 data_t *expected_output2 )
4189{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004190 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004191 psa_algorithm_t alg = alg_arg;
4192 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004193 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004194 uint8_t *expected_outputs[2] =
4195 {expected_output1->x, expected_output2->x};
4196 size_t output_sizes[2] =
4197 {expected_output1->len, expected_output2->len};
4198 size_t output_buffer_size = 0;
4199 uint8_t *output_buffer = NULL;
4200 size_t expected_capacity;
4201 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004202 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004203 psa_status_t status;
4204 unsigned i;
4205
4206 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4207 {
4208 if( output_sizes[i] > output_buffer_size )
4209 output_buffer_size = output_sizes[i];
4210 if( output_sizes[i] == 0 )
4211 expected_outputs[i] = NULL;
4212 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004213 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004214 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004215
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004216 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4217 psa_set_key_algorithm( &attributes, alg );
4218 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004219
Gilles Peskine049c7532019-05-15 20:22:09 +02004220 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4221 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004222
4223 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004224 if( PSA_ALG_IS_HKDF( alg ) )
4225 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004226 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4227 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004228 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004229 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004230 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004231 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004232 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004233 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004234 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004235 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004236 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004237 label->x, label->len ) );
4238 }
4239 else
4240 {
4241 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004242 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004243 salt->x, salt->len,
4244 label->x, label->len,
4245 requested_capacity ) );
4246 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004247 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004248 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004249 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004250 expected_capacity = requested_capacity;
4251
4252 /* Expansion phase. */
4253 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4254 {
4255 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004256 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004257 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004258 if( expected_capacity == 0 && output_sizes[i] == 0 )
4259 {
4260 /* Reading 0 bytes when 0 bytes are available can go either way. */
4261 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004262 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004263 continue;
4264 }
4265 else if( expected_capacity == 0 ||
4266 output_sizes[i] > expected_capacity )
4267 {
4268 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004269 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004270 expected_capacity = 0;
4271 continue;
4272 }
4273 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004274 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004275 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004276 ASSERT_COMPARE( output_buffer, output_sizes[i],
4277 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004278 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004279 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004280 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004281 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004282 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004283 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004284 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004285
4286exit:
4287 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004288 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004289 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004290 mbedtls_psa_crypto_free( );
4291}
4292/* END_CASE */
4293
4294/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004295void derive_full( int alg_arg,
4296 data_t *key_data,
4297 data_t *salt,
4298 data_t *label,
4299 int requested_capacity_arg )
4300{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004301 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004302 psa_algorithm_t alg = alg_arg;
4303 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004304 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004305 unsigned char output_buffer[16];
4306 size_t expected_capacity = requested_capacity;
4307 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004308 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004309
Gilles Peskine8817f612018-12-18 00:18:46 +01004310 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004311
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004312 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4313 psa_set_key_algorithm( &attributes, alg );
4314 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004315
Gilles Peskine049c7532019-05-15 20:22:09 +02004316 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4317 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004318
4319 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004320 if( PSA_ALG_IS_HKDF( alg ) )
4321 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004322 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4323 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004324 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004325 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004326 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004327 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004328 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004329 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004330 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004331 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004332 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004333 label->x, label->len ) );
4334 }
4335 else
4336 {
4337 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004338 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004339 salt->x, salt->len,
4340 label->x, label->len,
4341 requested_capacity ) );
4342 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004343 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004344 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004345 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004346
4347 /* Expansion phase. */
4348 while( current_capacity > 0 )
4349 {
4350 size_t read_size = sizeof( output_buffer );
4351 if( read_size > current_capacity )
4352 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004353 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004354 output_buffer,
4355 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004356 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004357 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004358 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004359 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004360 }
4361
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004362 /* Check that the operation refuses to go over capacity. */
4363 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004364 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004365
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004366 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004367
4368exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004369 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004370 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004371 mbedtls_psa_crypto_free( );
4372}
4373/* END_CASE */
4374
4375/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004376void derive_key_exercise( int alg_arg,
4377 data_t *key_data,
4378 data_t *salt,
4379 data_t *label,
4380 int derived_type_arg,
4381 int derived_bits_arg,
4382 int derived_usage_arg,
4383 int derived_alg_arg )
4384{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004385 psa_key_handle_t base_handle = 0;
4386 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004387 psa_algorithm_t alg = alg_arg;
4388 psa_key_type_t derived_type = derived_type_arg;
4389 size_t derived_bits = derived_bits_arg;
4390 psa_key_usage_t derived_usage = derived_usage_arg;
4391 psa_algorithm_t derived_alg = derived_alg_arg;
4392 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004393 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004394 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004395 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004396
Gilles Peskine8817f612018-12-18 00:18:46 +01004397 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004398
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004399 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4400 psa_set_key_algorithm( &attributes, alg );
4401 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004402 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4403 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004404
4405 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004406 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004407 salt->x, salt->len,
4408 label->x, label->len,
4409 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004410 psa_set_key_usage_flags( &attributes, derived_usage );
4411 psa_set_key_algorithm( &attributes, derived_alg );
4412 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004413 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004414 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004415 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004416
4417 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004418 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4419 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4420 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004421
4422 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004423 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004424 goto exit;
4425
4426exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004427 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004428 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004429 psa_destroy_key( base_handle );
4430 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004431 mbedtls_psa_crypto_free( );
4432}
4433/* END_CASE */
4434
4435/* BEGIN_CASE */
4436void derive_key_export( int alg_arg,
4437 data_t *key_data,
4438 data_t *salt,
4439 data_t *label,
4440 int bytes1_arg,
4441 int bytes2_arg )
4442{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004443 psa_key_handle_t base_handle = 0;
4444 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004445 psa_algorithm_t alg = alg_arg;
4446 size_t bytes1 = bytes1_arg;
4447 size_t bytes2 = bytes2_arg;
4448 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004449 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004450 uint8_t *output_buffer = NULL;
4451 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004452 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4453 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004454 size_t length;
4455
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004456 ASSERT_ALLOC( output_buffer, capacity );
4457 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004458 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004459
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004460 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4461 psa_set_key_algorithm( &base_attributes, alg );
4462 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004463 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4464 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004465
4466 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004467 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004468 salt->x, salt->len,
4469 label->x, label->len,
4470 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004471 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004472 output_buffer,
4473 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004474 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004475
4476 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004477 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004478 salt->x, salt->len,
4479 label->x, label->len,
4480 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004481 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4482 psa_set_key_algorithm( &derived_attributes, 0 );
4483 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004484 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004485 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004486 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004487 PSA_ASSERT( psa_export_key( derived_handle,
4488 export_buffer, bytes1,
4489 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004490 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004491 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004492 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004493 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004494 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004495 PSA_ASSERT( psa_export_key( derived_handle,
4496 export_buffer + bytes1, bytes2,
4497 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004498 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004499
4500 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004501 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4502 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004503
4504exit:
4505 mbedtls_free( output_buffer );
4506 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004507 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004508 psa_destroy_key( base_handle );
4509 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004510 mbedtls_psa_crypto_free( );
4511}
4512/* END_CASE */
4513
4514/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004515void key_agreement_setup( int alg_arg,
4516 int our_key_type_arg, data_t *our_key_data,
4517 data_t *peer_key_data,
4518 int expected_status_arg )
4519{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004520 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004521 psa_algorithm_t alg = alg_arg;
4522 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004523 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004524 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004525 psa_status_t expected_status = expected_status_arg;
4526 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004527
Gilles Peskine8817f612018-12-18 00:18:46 +01004528 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004529
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004530 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4531 psa_set_key_algorithm( &attributes, alg );
4532 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004533 PSA_ASSERT( psa_import_key( &attributes,
4534 our_key_data->x, our_key_data->len,
4535 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004536
Gilles Peskine77f40d82019-04-11 21:27:06 +02004537 /* The tests currently include inputs that should fail at either step.
4538 * Test cases that fail at the setup step should be changed to call
4539 * key_derivation_setup instead, and this function should be renamed
4540 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004541 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004542 if( status == PSA_SUCCESS )
4543 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004544 TEST_EQUAL( psa_key_derivation_key_agreement(
4545 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4546 our_key,
4547 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004548 expected_status );
4549 }
4550 else
4551 {
4552 TEST_ASSERT( status == expected_status );
4553 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004554
4555exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004556 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004557 psa_destroy_key( our_key );
4558 mbedtls_psa_crypto_free( );
4559}
4560/* END_CASE */
4561
4562/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004563void raw_key_agreement( int alg_arg,
4564 int our_key_type_arg, data_t *our_key_data,
4565 data_t *peer_key_data,
4566 data_t *expected_output )
4567{
4568 psa_key_handle_t our_key = 0;
4569 psa_algorithm_t alg = alg_arg;
4570 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004571 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004572 unsigned char *output = NULL;
4573 size_t output_length = ~0;
4574
4575 ASSERT_ALLOC( output, expected_output->len );
4576 PSA_ASSERT( psa_crypto_init( ) );
4577
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004578 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4579 psa_set_key_algorithm( &attributes, alg );
4580 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004581 PSA_ASSERT( psa_import_key( &attributes,
4582 our_key_data->x, our_key_data->len,
4583 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004584
Gilles Peskinebe697d82019-05-16 18:00:41 +02004585 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4586 peer_key_data->x, peer_key_data->len,
4587 output, expected_output->len,
4588 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004589 ASSERT_COMPARE( output, output_length,
4590 expected_output->x, expected_output->len );
4591
4592exit:
4593 mbedtls_free( output );
4594 psa_destroy_key( our_key );
4595 mbedtls_psa_crypto_free( );
4596}
4597/* END_CASE */
4598
4599/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004600void key_agreement_capacity( int alg_arg,
4601 int our_key_type_arg, data_t *our_key_data,
4602 data_t *peer_key_data,
4603 int expected_capacity_arg )
4604{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004605 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004606 psa_algorithm_t alg = alg_arg;
4607 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004608 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004609 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004610 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004611 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004612
Gilles Peskine8817f612018-12-18 00:18:46 +01004613 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004614
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004615 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4616 psa_set_key_algorithm( &attributes, alg );
4617 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004618 PSA_ASSERT( psa_import_key( &attributes,
4619 our_key_data->x, our_key_data->len,
4620 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004621
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004622 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004623 PSA_ASSERT( psa_key_derivation_key_agreement(
4624 &operation,
4625 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4626 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004627 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4628 {
4629 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004630 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004631 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004632 NULL, 0 ) );
4633 }
Gilles Peskine59685592018-09-18 12:11:34 +02004634
Gilles Peskinebf491972018-10-25 22:36:12 +02004635 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004636 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004637 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004638 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004639
Gilles Peskinebf491972018-10-25 22:36:12 +02004640 /* Test the actual capacity by reading the output. */
4641 while( actual_capacity > sizeof( output ) )
4642 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004643 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004644 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004645 actual_capacity -= sizeof( output );
4646 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004647 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004648 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004649 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004650 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004651
Gilles Peskine59685592018-09-18 12:11:34 +02004652exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004653 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004654 psa_destroy_key( our_key );
4655 mbedtls_psa_crypto_free( );
4656}
4657/* END_CASE */
4658
4659/* BEGIN_CASE */
4660void key_agreement_output( int alg_arg,
4661 int our_key_type_arg, data_t *our_key_data,
4662 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004663 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004664{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004665 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004666 psa_algorithm_t alg = alg_arg;
4667 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004668 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004669 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004670 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004671
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004672 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4673 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004674
Gilles Peskine8817f612018-12-18 00:18:46 +01004675 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004676
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004677 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4678 psa_set_key_algorithm( &attributes, alg );
4679 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004680 PSA_ASSERT( psa_import_key( &attributes,
4681 our_key_data->x, our_key_data->len,
4682 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004683
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004684 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004685 PSA_ASSERT( psa_key_derivation_key_agreement(
4686 &operation,
4687 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4688 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004689 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4690 {
4691 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004692 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004693 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004694 NULL, 0 ) );
4695 }
Gilles Peskine59685592018-09-18 12:11:34 +02004696
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004697 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004698 actual_output,
4699 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004700 ASSERT_COMPARE( actual_output, expected_output1->len,
4701 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004702 if( expected_output2->len != 0 )
4703 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004704 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004705 actual_output,
4706 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004707 ASSERT_COMPARE( actual_output, expected_output2->len,
4708 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004709 }
Gilles Peskine59685592018-09-18 12:11:34 +02004710
4711exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004712 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004713 psa_destroy_key( our_key );
4714 mbedtls_psa_crypto_free( );
4715 mbedtls_free( actual_output );
4716}
4717/* END_CASE */
4718
4719/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004720void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004721{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004722 size_t bytes = bytes_arg;
4723 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004724 unsigned char *output = NULL;
4725 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004726 size_t i;
4727 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004728
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004729 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4730 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004731 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004732
Gilles Peskine8817f612018-12-18 00:18:46 +01004733 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004734
Gilles Peskinea50d7392018-06-21 10:22:13 +02004735 /* Run several times, to ensure that every output byte will be
4736 * nonzero at least once with overwhelming probability
4737 * (2^(-8*number_of_runs)). */
4738 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004739 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004740 if( bytes != 0 )
4741 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004742 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004743
4744 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004745 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4746 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004747
4748 for( i = 0; i < bytes; i++ )
4749 {
4750 if( output[i] != 0 )
4751 ++changed[i];
4752 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004753 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004754
4755 /* Check that every byte was changed to nonzero at least once. This
4756 * validates that psa_generate_random is overwriting every byte of
4757 * the output buffer. */
4758 for( i = 0; i < bytes; i++ )
4759 {
4760 TEST_ASSERT( changed[i] != 0 );
4761 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004762
4763exit:
4764 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004765 mbedtls_free( output );
4766 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004767}
4768/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004769
4770/* BEGIN_CASE */
4771void generate_key( int type_arg,
4772 int bits_arg,
4773 int usage_arg,
4774 int alg_arg,
4775 int expected_status_arg )
4776{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004777 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004778 psa_key_type_t type = type_arg;
4779 psa_key_usage_t usage = usage_arg;
4780 size_t bits = bits_arg;
4781 psa_algorithm_t alg = alg_arg;
4782 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004783 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004784 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004785
Gilles Peskine8817f612018-12-18 00:18:46 +01004786 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004787
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004788 psa_set_key_usage_flags( &attributes, usage );
4789 psa_set_key_algorithm( &attributes, alg );
4790 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004791 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004792
4793 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004794 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004795 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004796 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004797
4798 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004799 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4800 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4801 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004802
Gilles Peskine818ca122018-06-20 18:16:48 +02004803 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004804 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004805 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004806
4807exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004808 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004809 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004810 mbedtls_psa_crypto_free( );
4811}
4812/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004813
Gilles Peskinee56e8782019-04-26 17:34:02 +02004814/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4815void generate_key_rsa( int bits_arg,
4816 data_t *e_arg,
4817 int expected_status_arg )
4818{
4819 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02004820 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02004821 size_t bits = bits_arg;
4822 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4823 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4824 psa_status_t expected_status = expected_status_arg;
4825 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4826 uint8_t *exported = NULL;
4827 size_t exported_size =
4828 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4829 size_t exported_length = SIZE_MAX;
4830 uint8_t *e_read_buffer = NULL;
4831 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004832 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004833 size_t e_read_length = SIZE_MAX;
4834
4835 if( e_arg->len == 0 ||
4836 ( e_arg->len == 3 &&
4837 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4838 {
4839 is_default_public_exponent = 1;
4840 e_read_size = 0;
4841 }
4842 ASSERT_ALLOC( e_read_buffer, e_read_size );
4843 ASSERT_ALLOC( exported, exported_size );
4844
4845 PSA_ASSERT( psa_crypto_init( ) );
4846
4847 psa_set_key_usage_flags( &attributes, usage );
4848 psa_set_key_algorithm( &attributes, alg );
4849 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4850 e_arg->x, e_arg->len ) );
4851 psa_set_key_bits( &attributes, bits );
4852
4853 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004854 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004855 if( expected_status != PSA_SUCCESS )
4856 goto exit;
4857
4858 /* Test the key information */
4859 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4860 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4861 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4862 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4863 e_read_buffer, e_read_size,
4864 &e_read_length ) );
4865 if( is_default_public_exponent )
4866 TEST_EQUAL( e_read_length, 0 );
4867 else
4868 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4869
4870 /* Do something with the key according to its type and permitted usage. */
4871 if( ! exercise_key( handle, usage, alg ) )
4872 goto exit;
4873
4874 /* Export the key and check the public exponent. */
4875 PSA_ASSERT( psa_export_public_key( handle,
4876 exported, exported_size,
4877 &exported_length ) );
4878 {
4879 uint8_t *p = exported;
4880 uint8_t *end = exported + exported_length;
4881 size_t len;
4882 /* RSAPublicKey ::= SEQUENCE {
4883 * modulus INTEGER, -- n
4884 * publicExponent INTEGER } -- e
4885 */
4886 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004887 MBEDTLS_ASN1_SEQUENCE |
4888 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004889 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4890 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4891 MBEDTLS_ASN1_INTEGER ) );
4892 if( len >= 1 && p[0] == 0 )
4893 {
4894 ++p;
4895 --len;
4896 }
4897 if( e_arg->len == 0 )
4898 {
4899 TEST_EQUAL( len, 3 );
4900 TEST_EQUAL( p[0], 1 );
4901 TEST_EQUAL( p[1], 0 );
4902 TEST_EQUAL( p[2], 1 );
4903 }
4904 else
4905 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4906 }
4907
4908exit:
4909 psa_reset_key_attributes( &attributes );
4910 psa_destroy_key( handle );
4911 mbedtls_psa_crypto_free( );
4912 mbedtls_free( e_read_buffer );
4913 mbedtls_free( exported );
4914}
4915/* END_CASE */
4916
Darryl Greend49a4992018-06-18 17:27:26 +01004917/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004918void persistent_key_load_key_from_storage( data_t *data,
4919 int type_arg, int bits_arg,
4920 int usage_flags_arg, int alg_arg,
4921 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004922{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004923 psa_key_id_t key_id = 1;
4924 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004925 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004926 psa_key_handle_t base_key = 0;
4927 psa_key_type_t type = type_arg;
4928 size_t bits = bits_arg;
4929 psa_key_usage_t usage_flags = usage_flags_arg;
4930 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004931 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004932 unsigned char *first_export = NULL;
4933 unsigned char *second_export = NULL;
4934 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4935 size_t first_exported_length;
4936 size_t second_exported_length;
4937
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004938 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4939 {
4940 ASSERT_ALLOC( first_export, export_size );
4941 ASSERT_ALLOC( second_export, export_size );
4942 }
Darryl Greend49a4992018-06-18 17:27:26 +01004943
Gilles Peskine8817f612018-12-18 00:18:46 +01004944 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004945
Gilles Peskinec87af662019-05-15 16:12:22 +02004946 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004947 psa_set_key_usage_flags( &attributes, usage_flags );
4948 psa_set_key_algorithm( &attributes, alg );
4949 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004950 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004951
Darryl Green0c6575a2018-11-07 16:05:30 +00004952 switch( generation_method )
4953 {
4954 case IMPORT_KEY:
4955 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004956 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4957 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004958 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004959
Darryl Green0c6575a2018-11-07 16:05:30 +00004960 case GENERATE_KEY:
4961 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004962 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004963 break;
4964
4965 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004966 {
4967 /* Create base key */
4968 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4969 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4970 psa_set_key_usage_flags( &base_attributes,
4971 PSA_KEY_USAGE_DERIVE );
4972 psa_set_key_algorithm( &base_attributes, derive_alg );
4973 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004974 PSA_ASSERT( psa_import_key( &base_attributes,
4975 data->x, data->len,
4976 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004977 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004978 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004979 PSA_ASSERT( psa_key_derivation_input_key(
4980 &operation,
4981 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004982 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004983 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004984 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004985 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
4986 &operation,
4987 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004988 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004989 PSA_ASSERT( psa_destroy_key( base_key ) );
4990 base_key = 0;
4991 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004992 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00004993 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004994 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004995
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004996 /* Export the key if permitted by the key policy. */
4997 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4998 {
4999 PSA_ASSERT( psa_export_key( handle,
5000 first_export, export_size,
5001 &first_exported_length ) );
5002 if( generation_method == IMPORT_KEY )
5003 ASSERT_COMPARE( data->x, data->len,
5004 first_export, first_exported_length );
5005 }
Darryl Greend49a4992018-06-18 17:27:26 +01005006
5007 /* Shutdown and restart */
5008 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01005009 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005010
Darryl Greend49a4992018-06-18 17:27:26 +01005011 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005012 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005013 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5014 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5015 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5016 PSA_KEY_LIFETIME_PERSISTENT );
5017 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5018 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5019 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5020 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005021
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005022 /* Export the key again if permitted by the key policy. */
5023 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005024 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005025 PSA_ASSERT( psa_export_key( handle,
5026 second_export, export_size,
5027 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005028 ASSERT_COMPARE( first_export, first_exported_length,
5029 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005030 }
5031
5032 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005033 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005034 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005035
5036exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005037 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005038 mbedtls_free( first_export );
5039 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005040 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005041 psa_destroy_key( base_key );
5042 if( handle == 0 )
5043 {
5044 /* In case there was a test failure after creating the persistent key
5045 * but while it was not open, try to re-open the persistent key
5046 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005047 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005048 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005049 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01005050 mbedtls_psa_crypto_free();
5051}
5052/* END_CASE */