blob: 90948d7bacfb0f2a55a66f6fbb142322e66c4eda [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/* BEGIN_HEADER */
itayzafrir3e02b3b2018-06-12 17:06:52 +03002#include <stdint.h>
mohammad160327010052018-07-03 13:16:15 +03003
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02004#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02005#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02006#include "mbedtls/oid.h"
7
Gilles Peskine1838e822019-06-20 12:40:56 +02008#include "psa_crypto_helpers.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +03009
Jaeden Amerof24c7f82018-06-27 17:20:43 +010010/** An invalid export length that will never be set by psa_export_key(). */
11static const size_t INVALID_EXPORT_LENGTH = ~0U;
12
Gilles Peskinef426e0f2019-02-25 17:42:03 +010013/* A hash algorithm that is known to be supported.
14 *
15 * This is used in some smoke tests.
16 */
17#if defined(MBEDTLS_MD2_C)
18#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
19#elif defined(MBEDTLS_MD4_C)
20#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
21#elif defined(MBEDTLS_MD5_C)
22#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
23/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
24 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
25 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
26 * implausible anyway. */
27#elif defined(MBEDTLS_SHA1_C)
28#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
29#elif defined(MBEDTLS_SHA256_C)
30#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
31#elif defined(MBEDTLS_SHA512_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
33#elif defined(MBEDTLS_SHA3_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
35#else
36#undef KNOWN_SUPPORTED_HASH_ALG
37#endif
38
39/* A block cipher that is known to be supported.
40 *
41 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
42 */
43#if defined(MBEDTLS_AES_C)
44#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
45#elif defined(MBEDTLS_ARIA_C)
46#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
47#elif defined(MBEDTLS_CAMELLIA_C)
48#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
49#undef KNOWN_SUPPORTED_BLOCK_CIPHER
50#endif
51
52/* A MAC mode that is known to be supported.
53 *
54 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
55 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
56 *
57 * This is used in some smoke tests.
58 */
59#if defined(KNOWN_SUPPORTED_HASH_ALG)
60#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
61#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
62#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
63#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
64#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
65#else
66#undef KNOWN_SUPPORTED_MAC_ALG
67#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
68#endif
69
70/* A cipher algorithm and key type that are known to be supported.
71 *
72 * This is used in some smoke tests.
73 */
74#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
75#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
76#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
77#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
78#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
79#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
80#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
81#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
82#else
83#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
84#endif
85#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
86#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
87#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
88#elif defined(MBEDTLS_RC4_C)
89#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
90#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
91#else
92#undef KNOWN_SUPPORTED_CIPHER_ALG
93#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
94#endif
95
Gilles Peskinea7aa4422018-08-14 15:17:54 +020096/** Test if a buffer contains a constant byte value.
97 *
98 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +020099 *
100 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200101 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200102 * \param size Size of the buffer in bytes.
103 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200104 * \return 1 if the buffer is all-bits-zero.
105 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200107static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200108{
109 size_t i;
110 for( i = 0; i < size; i++ )
111 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200112 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200113 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200114 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200115 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200116}
Gilles Peskine818ca122018-06-20 18:16:48 +0200117
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200118/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
119static int asn1_write_10x( unsigned char **p,
120 unsigned char *start,
121 size_t bits,
122 unsigned char x )
123{
124 int ret;
125 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200126 if( bits == 0 )
127 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
128 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200129 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300130 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200131 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
132 *p -= len;
133 ( *p )[len-1] = x;
134 if( bits % 8 == 0 )
135 ( *p )[1] |= 1;
136 else
137 ( *p )[0] |= 1 << ( bits % 8 );
138 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
139 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
140 MBEDTLS_ASN1_INTEGER ) );
141 return( len );
142}
143
144static int construct_fake_rsa_key( unsigned char *buffer,
145 size_t buffer_size,
146 unsigned char **p,
147 size_t bits,
148 int keypair )
149{
150 size_t half_bits = ( bits + 1 ) / 2;
151 int ret;
152 int len = 0;
153 /* Construct something that looks like a DER encoding of
154 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
155 * RSAPrivateKey ::= SEQUENCE {
156 * version Version,
157 * modulus INTEGER, -- n
158 * publicExponent INTEGER, -- e
159 * privateExponent INTEGER, -- d
160 * prime1 INTEGER, -- p
161 * prime2 INTEGER, -- q
162 * exponent1 INTEGER, -- d mod (p-1)
163 * exponent2 INTEGER, -- d mod (q-1)
164 * coefficient INTEGER, -- (inverse of q) mod p
165 * otherPrimeInfos OtherPrimeInfos OPTIONAL
166 * }
167 * Or, for a public key, the same structure with only
168 * version, modulus and publicExponent.
169 */
170 *p = buffer + buffer_size;
171 if( keypair )
172 {
173 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
174 asn1_write_10x( p, buffer, half_bits, 1 ) );
175 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
176 asn1_write_10x( p, buffer, half_bits, 1 ) );
177 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
178 asn1_write_10x( p, buffer, half_bits, 1 ) );
179 MBEDTLS_ASN1_CHK_ADD( len, /* q */
180 asn1_write_10x( p, buffer, half_bits, 1 ) );
181 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
182 asn1_write_10x( p, buffer, half_bits, 3 ) );
183 MBEDTLS_ASN1_CHK_ADD( len, /* d */
184 asn1_write_10x( p, buffer, bits, 1 ) );
185 }
186 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
187 asn1_write_10x( p, buffer, 17, 1 ) );
188 MBEDTLS_ASN1_CHK_ADD( len, /* n */
189 asn1_write_10x( p, buffer, bits, 1 ) );
190 if( keypair )
191 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
192 mbedtls_asn1_write_int( p, buffer, 0 ) );
193 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
194 {
195 const unsigned char tag =
196 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
198 }
199 return( len );
200}
201
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100202int exercise_mac_setup( psa_key_type_t key_type,
203 const unsigned char *key_bytes,
204 size_t key_length,
205 psa_algorithm_t alg,
206 psa_mac_operation_t *operation,
207 psa_status_t *status )
208{
209 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200210 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100211
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200212 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
213 psa_set_key_algorithm( &attributes, alg );
214 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200215 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
216 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100217
218 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100219 /* Whether setup succeeded or failed, abort must succeed. */
220 PSA_ASSERT( psa_mac_abort( operation ) );
221 /* If setup failed, reproduce the failure, so that the caller can
222 * test the resulting state of the operation object. */
223 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100224 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100225 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
226 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100227 }
228
229 psa_destroy_key( handle );
230 return( 1 );
231
232exit:
233 psa_destroy_key( handle );
234 return( 0 );
235}
236
237int exercise_cipher_setup( psa_key_type_t key_type,
238 const unsigned char *key_bytes,
239 size_t key_length,
240 psa_algorithm_t alg,
241 psa_cipher_operation_t *operation,
242 psa_status_t *status )
243{
244 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200245 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100246
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200247 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
248 psa_set_key_algorithm( &attributes, alg );
249 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200250 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
251 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100252
253 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100254 /* Whether setup succeeded or failed, abort must succeed. */
255 PSA_ASSERT( psa_cipher_abort( operation ) );
256 /* If setup failed, reproduce the failure, so that the caller can
257 * test the resulting state of the operation object. */
258 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100259 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100260 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
261 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100262 }
263
264 psa_destroy_key( handle );
265 return( 1 );
266
267exit:
268 psa_destroy_key( handle );
269 return( 0 );
270}
271
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100272static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200273 psa_key_usage_t usage,
274 psa_algorithm_t alg )
275{
Jaeden Amero769ce272019-01-04 11:48:03 +0000276 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200277 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200278 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200279 size_t mac_length = sizeof( mac );
280
281 if( usage & PSA_KEY_USAGE_SIGN )
282 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100283 PSA_ASSERT( psa_mac_sign_setup( &operation,
284 handle, alg ) );
285 PSA_ASSERT( psa_mac_update( &operation,
286 input, sizeof( input ) ) );
287 PSA_ASSERT( psa_mac_sign_finish( &operation,
288 mac, sizeof( mac ),
289 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200290 }
291
292 if( usage & PSA_KEY_USAGE_VERIFY )
293 {
294 psa_status_t verify_status =
295 ( usage & PSA_KEY_USAGE_SIGN ?
296 PSA_SUCCESS :
297 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100298 PSA_ASSERT( psa_mac_verify_setup( &operation,
299 handle, alg ) );
300 PSA_ASSERT( psa_mac_update( &operation,
301 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100302 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
303 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200304 }
305
306 return( 1 );
307
308exit:
309 psa_mac_abort( &operation );
310 return( 0 );
311}
312
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100313static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200314 psa_key_usage_t usage,
315 psa_algorithm_t alg )
316{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000317 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200318 unsigned char iv[16] = {0};
319 size_t iv_length = sizeof( iv );
320 const unsigned char plaintext[16] = "Hello, world...";
321 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
322 size_t ciphertext_length = sizeof( ciphertext );
323 unsigned char decrypted[sizeof( ciphertext )];
324 size_t part_length;
325
326 if( usage & PSA_KEY_USAGE_ENCRYPT )
327 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100328 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
329 handle, alg ) );
330 PSA_ASSERT( psa_cipher_generate_iv( &operation,
331 iv, sizeof( iv ),
332 &iv_length ) );
333 PSA_ASSERT( psa_cipher_update( &operation,
334 plaintext, sizeof( plaintext ),
335 ciphertext, sizeof( ciphertext ),
336 &ciphertext_length ) );
337 PSA_ASSERT( psa_cipher_finish( &operation,
338 ciphertext + ciphertext_length,
339 sizeof( ciphertext ) - ciphertext_length,
340 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200341 ciphertext_length += part_length;
342 }
343
344 if( usage & PSA_KEY_USAGE_DECRYPT )
345 {
346 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200347 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200348 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
349 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200350 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
351 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
352 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
353 * have this macro yet. */
354 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
355 psa_get_key_type( &attributes ) );
356 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200357 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100358 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
359 handle, alg ) );
360 PSA_ASSERT( psa_cipher_set_iv( &operation,
361 iv, iv_length ) );
362 PSA_ASSERT( psa_cipher_update( &operation,
363 ciphertext, ciphertext_length,
364 decrypted, sizeof( decrypted ),
365 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200366 status = psa_cipher_finish( &operation,
367 decrypted + part_length,
368 sizeof( decrypted ) - part_length,
369 &part_length );
370 /* For a stream cipher, all inputs are valid. For a block cipher,
371 * if the input is some aribtrary data rather than an actual
372 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200373 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200374 TEST_ASSERT( status == PSA_SUCCESS ||
375 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200376 else
377 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200378 }
379
380 return( 1 );
381
382exit:
383 psa_cipher_abort( &operation );
384 return( 0 );
385}
386
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100387static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200388 psa_key_usage_t usage,
389 psa_algorithm_t alg )
390{
391 unsigned char nonce[16] = {0};
392 size_t nonce_length = sizeof( nonce );
393 unsigned char plaintext[16] = "Hello, world...";
394 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
395 size_t ciphertext_length = sizeof( ciphertext );
396 size_t plaintext_length = sizeof( ciphertext );
397
398 if( usage & PSA_KEY_USAGE_ENCRYPT )
399 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100400 PSA_ASSERT( psa_aead_encrypt( handle, alg,
401 nonce, nonce_length,
402 NULL, 0,
403 plaintext, sizeof( plaintext ),
404 ciphertext, sizeof( ciphertext ),
405 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200406 }
407
408 if( usage & PSA_KEY_USAGE_DECRYPT )
409 {
410 psa_status_t verify_status =
411 ( usage & PSA_KEY_USAGE_ENCRYPT ?
412 PSA_SUCCESS :
413 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100414 TEST_EQUAL( psa_aead_decrypt( handle, alg,
415 nonce, nonce_length,
416 NULL, 0,
417 ciphertext, ciphertext_length,
418 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100419 &plaintext_length ),
420 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200421 }
422
423 return( 1 );
424
425exit:
426 return( 0 );
427}
428
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100429static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200430 psa_key_usage_t usage,
431 psa_algorithm_t alg )
432{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200433 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
434 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200435 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200436 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100437 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
438
439 /* If the policy allows signing with any hash, just pick one. */
440 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
441 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100442#if defined(KNOWN_SUPPORTED_HASH_ALG)
443 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
444 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100445#else
446 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100447 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100448#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100449 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200450
451 if( usage & PSA_KEY_USAGE_SIGN )
452 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200453 /* Some algorithms require the payload to have the size of
454 * the hash encoded in the algorithm. Use this input size
455 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200456 if( hash_alg != 0 )
457 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100458 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
459 payload, payload_length,
460 signature, sizeof( signature ),
461 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200462 }
463
464 if( usage & PSA_KEY_USAGE_VERIFY )
465 {
466 psa_status_t verify_status =
467 ( usage & PSA_KEY_USAGE_SIGN ?
468 PSA_SUCCESS :
469 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100470 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
471 payload, payload_length,
472 signature, signature_length ),
473 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200474 }
475
476 return( 1 );
477
478exit:
479 return( 0 );
480}
481
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100482static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200483 psa_key_usage_t usage,
484 psa_algorithm_t alg )
485{
486 unsigned char plaintext[256] = "Hello, world...";
487 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
488 size_t ciphertext_length = sizeof( ciphertext );
489 size_t plaintext_length = 16;
490
491 if( usage & PSA_KEY_USAGE_ENCRYPT )
492 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100493 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
494 plaintext, plaintext_length,
495 NULL, 0,
496 ciphertext, sizeof( ciphertext ),
497 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200498 }
499
500 if( usage & PSA_KEY_USAGE_DECRYPT )
501 {
502 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100503 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200504 ciphertext, ciphertext_length,
505 NULL, 0,
506 plaintext, sizeof( plaintext ),
507 &plaintext_length );
508 TEST_ASSERT( status == PSA_SUCCESS ||
509 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
510 ( status == PSA_ERROR_INVALID_ARGUMENT ||
511 status == PSA_ERROR_INVALID_PADDING ) ) );
512 }
513
514 return( 1 );
515
516exit:
517 return( 0 );
518}
Gilles Peskine02b75072018-07-01 22:31:34 +0200519
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100520static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200521 psa_key_usage_t usage,
522 psa_algorithm_t alg )
523{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200524 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +0200525 unsigned char label[16] = "This is a label.";
526 size_t label_length = sizeof( label );
527 unsigned char seed[16] = "abcdefghijklmnop";
528 size_t seed_length = sizeof( seed );
529 unsigned char output[1];
530
531 if( usage & PSA_KEY_USAGE_DERIVE )
532 {
Gilles Peskine7607cd62019-05-29 17:35:00 +0200533 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100534 if( PSA_ALG_IS_HKDF( alg ) )
535 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200536 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200537 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100538 label,
539 label_length ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200540 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200541 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100542 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200543 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200544 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100545 seed,
546 seed_length ) );
547 }
Gilles Peskine7607cd62019-05-29 17:35:00 +0200548 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
549 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
550 {
551 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
552 PSA_KEY_DERIVATION_INPUT_SEED,
553 seed,
554 seed_length ) );
555 PSA_ASSERT( psa_key_derivation_input_key( &operation,
556 PSA_KEY_DERIVATION_INPUT_SECRET,
557 handle ) );
558 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
559 PSA_KEY_DERIVATION_INPUT_LABEL,
560 label,
561 label_length ) );
562 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100563 else
564 {
Gilles Peskine7607cd62019-05-29 17:35:00 +0200565 TEST_ASSERT( ! "Key derivation algorithm not supported" );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100566 }
Gilles Peskine7607cd62019-05-29 17:35:00 +0200567
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200568 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200569 output,
570 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200571 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200572 }
573
574 return( 1 );
575
576exit:
577 return( 0 );
578}
579
Gilles Peskinec7998b72018-11-07 18:45:02 +0100580/* We need two keys to exercise key agreement. Exercise the
581 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200582static psa_status_t key_agreement_with_self(
583 psa_key_derivation_operation_t *operation,
584 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100585{
586 psa_key_type_t private_key_type;
587 psa_key_type_t public_key_type;
588 size_t key_bits;
589 uint8_t *public_key = NULL;
590 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200591 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200592 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
593 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200594 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200595 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100596
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200597 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
598 private_key_type = psa_get_key_type( &attributes );
599 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200600 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100601 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
602 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100603 PSA_ASSERT( psa_export_public_key( handle,
604 public_key, public_key_length,
605 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100606
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200607 status = psa_key_derivation_key_agreement(
608 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
609 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100610exit:
611 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200612 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100613 return( status );
614}
615
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200616/* We need two keys to exercise key agreement. Exercise the
617 * private key against its own public key. */
618static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
619 psa_key_handle_t handle )
620{
621 psa_key_type_t private_key_type;
622 psa_key_type_t public_key_type;
623 size_t key_bits;
624 uint8_t *public_key = NULL;
625 size_t public_key_length;
626 uint8_t output[1024];
627 size_t output_length;
628 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200629 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
630 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200631 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200632 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200633
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200634 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
635 private_key_type = psa_get_key_type( &attributes );
636 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200637 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200638 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
639 ASSERT_ALLOC( public_key, public_key_length );
640 PSA_ASSERT( psa_export_public_key( handle,
641 public_key, public_key_length,
642 &public_key_length ) );
643
Gilles Peskinebe697d82019-05-16 18:00:41 +0200644 status = psa_raw_key_agreement( alg, handle,
645 public_key, public_key_length,
646 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200647exit:
648 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200649 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200650 return( status );
651}
652
653static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
654 psa_key_usage_t usage,
655 psa_algorithm_t alg )
656{
657 int ok = 0;
658
659 if( usage & PSA_KEY_USAGE_DERIVE )
660 {
661 /* We need two keys to exercise key agreement. Exercise the
662 * private key against its own public key. */
663 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
664 }
665 ok = 1;
666
667exit:
668 return( ok );
669}
670
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100671static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200672 psa_key_usage_t usage,
673 psa_algorithm_t alg )
674{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200675 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200676 unsigned char output[1];
677 int ok = 0;
678
679 if( usage & PSA_KEY_USAGE_DERIVE )
680 {
681 /* We need two keys to exercise key agreement. Exercise the
682 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200683 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
684 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
685 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200686 output,
687 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200688 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200689 }
690 ok = 1;
691
692exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200693 return( ok );
694}
695
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200696static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
697 size_t min_bits, size_t max_bits,
698 int must_be_odd )
699{
700 size_t len;
701 size_t actual_bits;
702 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100703 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100704 MBEDTLS_ASN1_INTEGER ),
705 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200706 /* Tolerate a slight departure from DER encoding:
707 * - 0 may be represented by an empty string or a 1-byte string.
708 * - The sign bit may be used as a value bit. */
709 if( ( len == 1 && ( *p )[0] == 0 ) ||
710 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
711 {
712 ++( *p );
713 --len;
714 }
715 if( min_bits == 0 && len == 0 )
716 return( 1 );
717 msb = ( *p )[0];
718 TEST_ASSERT( msb != 0 );
719 actual_bits = 8 * ( len - 1 );
720 while( msb != 0 )
721 {
722 msb >>= 1;
723 ++actual_bits;
724 }
725 TEST_ASSERT( actual_bits >= min_bits );
726 TEST_ASSERT( actual_bits <= max_bits );
727 if( must_be_odd )
728 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
729 *p += len;
730 return( 1 );
731exit:
732 return( 0 );
733}
734
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200735static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
736 uint8_t *exported, size_t exported_length )
737{
738 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100739 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200740 else
741 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200742
743#if defined(MBEDTLS_DES_C)
744 if( type == PSA_KEY_TYPE_DES )
745 {
746 /* Check the parity bits. */
747 unsigned i;
748 for( i = 0; i < bits / 8; i++ )
749 {
750 unsigned bit_count = 0;
751 unsigned m;
752 for( m = 1; m <= 0x100; m <<= 1 )
753 {
754 if( exported[i] & m )
755 ++bit_count;
756 }
757 TEST_ASSERT( bit_count % 2 != 0 );
758 }
759 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200760 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200761#endif
762
763#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200764 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200765 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200766 uint8_t *p = exported;
767 uint8_t *end = exported + exported_length;
768 size_t len;
769 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200770 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200771 * modulus INTEGER, -- n
772 * publicExponent INTEGER, -- e
773 * privateExponent INTEGER, -- d
774 * prime1 INTEGER, -- p
775 * prime2 INTEGER, -- q
776 * exponent1 INTEGER, -- d mod (p-1)
777 * exponent2 INTEGER, -- d mod (q-1)
778 * coefficient INTEGER, -- (inverse of q) mod p
779 * }
780 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100781 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
782 MBEDTLS_ASN1_SEQUENCE |
783 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
784 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200785 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
786 goto exit;
787 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
788 goto exit;
789 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
790 goto exit;
791 /* Require d to be at least half the size of n. */
792 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
793 goto exit;
794 /* Require p and q to be at most half the size of n, rounded up. */
795 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
796 goto exit;
797 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
798 goto exit;
799 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
800 goto exit;
801 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
802 goto exit;
803 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
804 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100805 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100806 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200807 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200808#endif /* MBEDTLS_RSA_C */
809
810#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200811 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200812 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100813 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100814 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100815 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200816 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200817#endif /* MBEDTLS_ECP_C */
818
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200819 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
820 {
821 uint8_t *p = exported;
822 uint8_t *end = exported + exported_length;
823 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200824#if defined(MBEDTLS_RSA_C)
825 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
826 {
827 /* RSAPublicKey ::= SEQUENCE {
828 * modulus INTEGER, -- n
829 * publicExponent INTEGER } -- e
830 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100831 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
832 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100833 MBEDTLS_ASN1_CONSTRUCTED ),
834 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100835 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200836 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;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100840 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200841 }
842 else
843#endif /* MBEDTLS_RSA_C */
844#if defined(MBEDTLS_ECP_C)
845 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
846 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000847 /* The representation of an ECC public key is:
848 * - The byte 0x04;
849 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
850 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
851 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000852 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100853 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
854 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200855 }
856 else
857#endif /* MBEDTLS_ECP_C */
858 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100859 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200860 mbedtls_snprintf( message, sizeof( message ),
861 "No sanity check for public key type=0x%08lx",
862 (unsigned long) type );
863 test_fail( message, __LINE__, __FILE__ );
864 return( 0 );
865 }
866 }
867 else
868
869 {
870 /* No sanity checks for other types */
871 }
872
873 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200874
875exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200876 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200877}
878
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100879static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200880 psa_key_usage_t usage )
881{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200882 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200883 uint8_t *exported = NULL;
884 size_t exported_size = 0;
885 size_t exported_length = 0;
886 int ok = 0;
887
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200888 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200889
890 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200891 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200892 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100893 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
894 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200895 ok = 1;
896 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200897 }
898
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200899 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
900 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200901 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200902
Gilles Peskine8817f612018-12-18 00:18:46 +0100903 PSA_ASSERT( psa_export_key( handle,
904 exported, exported_size,
905 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200906 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
907 psa_get_key_bits( &attributes ),
908 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200909
910exit:
911 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200912 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200913 return( ok );
914}
915
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100916static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200917{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200918 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200919 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200920 uint8_t *exported = NULL;
921 size_t exported_size = 0;
922 size_t exported_length = 0;
923 int ok = 0;
924
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200925 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
926 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200927 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100928 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100929 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200930 return( 1 );
931 }
932
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200933 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200934 psa_get_key_type( &attributes ) );
935 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
936 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200937 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200938
Gilles Peskine8817f612018-12-18 00:18:46 +0100939 PSA_ASSERT( psa_export_public_key( handle,
940 exported, exported_size,
941 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200942 ok = exported_key_sanity_check( public_type,
943 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200944 exported, exported_length );
945
946exit:
947 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200948 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200949 return( ok );
950}
951
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100952/** Do smoke tests on a key.
953 *
954 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
955 * sign/verify, or derivation) that is permitted according to \p usage.
956 * \p usage and \p alg should correspond to the expected policy on the
957 * key.
958 *
959 * Export the key if permitted by \p usage, and check that the output
960 * looks sensible. If \p usage forbids export, check that
961 * \p psa_export_key correctly rejects the attempt. If the key is
962 * asymmetric, also check \p psa_export_public_key.
963 *
964 * If the key fails the tests, this function calls the test framework's
965 * `test_fail` function and returns false. Otherwise this function returns
966 * true. Therefore it should be used as follows:
967 * ```
968 * if( ! exercise_key( ... ) ) goto exit;
969 * ```
970 *
971 * \param handle The key to exercise. It should be capable of performing
972 * \p alg.
973 * \param usage The usage flags to assume.
974 * \param alg The algorithm to exercise.
975 *
976 * \retval 0 The key failed the smoke tests.
977 * \retval 1 The key passed the smoke tests.
978 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100979static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +0200980 psa_key_usage_t usage,
981 psa_algorithm_t alg )
982{
983 int ok;
984 if( alg == 0 )
985 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
986 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100987 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200988 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100989 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200990 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100991 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200992 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100993 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200994 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100995 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200996 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100997 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200998 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
999 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001000 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001001 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001002 else
1003 {
1004 char message[40];
1005 mbedtls_snprintf( message, sizeof( message ),
1006 "No code to exercise alg=0x%08lx",
1007 (unsigned long) alg );
1008 test_fail( message, __LINE__, __FILE__ );
1009 ok = 0;
1010 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001011
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001012 ok = ok && exercise_export_key( handle, usage );
1013 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001014
Gilles Peskine02b75072018-07-01 22:31:34 +02001015 return( ok );
1016}
1017
Gilles Peskine10df3412018-10-25 22:35:43 +02001018static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1019 psa_algorithm_t alg )
1020{
1021 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1022 {
1023 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1024 PSA_KEY_USAGE_VERIFY :
1025 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1026 }
1027 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1028 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1029 {
1030 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1031 PSA_KEY_USAGE_ENCRYPT :
1032 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1033 }
1034 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1035 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1036 {
1037 return( PSA_KEY_USAGE_DERIVE );
1038 }
1039 else
1040 {
1041 return( 0 );
1042 }
1043
1044}
Darryl Green0c6575a2018-11-07 16:05:30 +00001045
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001046static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1047{
1048 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1049 uint8_t buffer[1];
1050 size_t length;
1051 int ok = 0;
1052
Gilles Peskinec87af662019-05-15 16:12:22 +02001053 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001054 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1055 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1056 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1057 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1058 PSA_ERROR_INVALID_HANDLE );
1059 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001060 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001061 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1062 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1063 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1064 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1065
1066 TEST_EQUAL( psa_export_key( handle,
1067 buffer, sizeof( buffer ), &length ),
1068 PSA_ERROR_INVALID_HANDLE );
1069 TEST_EQUAL( psa_export_public_key( handle,
1070 buffer, sizeof( buffer ), &length ),
1071 PSA_ERROR_INVALID_HANDLE );
1072
1073 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1074 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1075
1076 ok = 1;
1077
1078exit:
1079 psa_reset_key_attributes( &attributes );
1080 return( ok );
1081}
1082
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001083/* An overapproximation of the amount of storage needed for a key of the
1084 * given type and with the given content. The API doesn't make it easy
1085 * to find a good value for the size. The current implementation doesn't
1086 * care about the value anyway. */
1087#define KEY_BITS_FROM_DATA( type, data ) \
1088 ( data )->len
1089
Darryl Green0c6575a2018-11-07 16:05:30 +00001090typedef enum {
1091 IMPORT_KEY = 0,
1092 GENERATE_KEY = 1,
1093 DERIVE_KEY = 2
1094} generate_method;
1095
Gilles Peskinee59236f2018-01-27 23:32:46 +01001096/* END_HEADER */
1097
1098/* BEGIN_DEPENDENCIES
1099 * depends_on:MBEDTLS_PSA_CRYPTO_C
1100 * END_DEPENDENCIES
1101 */
1102
1103/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001104void static_checks( )
1105{
1106 size_t max_truncated_mac_size =
1107 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1108
1109 /* Check that the length for a truncated MAC always fits in the algorithm
1110 * encoding. The shifted mask is the maximum truncated value. The
1111 * untruncated algorithm may be one byte larger. */
1112 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1113}
1114/* END_CASE */
1115
1116/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001117void attributes_set_get( int id_arg, int lifetime_arg,
1118 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001119 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001120{
Gilles Peskine4747d192019-04-17 15:05:45 +02001121 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001122 psa_key_id_t id = id_arg;
1123 psa_key_lifetime_t lifetime = lifetime_arg;
1124 psa_key_usage_t usage_flags = usage_flags_arg;
1125 psa_algorithm_t alg = alg_arg;
1126 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001127 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001128
1129 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1130 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1131 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1132 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1133 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001134 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001135
Gilles Peskinec87af662019-05-15 16:12:22 +02001136 psa_set_key_id( &attributes, id );
1137 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001138 psa_set_key_usage_flags( &attributes, usage_flags );
1139 psa_set_key_algorithm( &attributes, alg );
1140 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001141 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001142
1143 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1144 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1145 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1146 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1147 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001148 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001149
1150 psa_reset_key_attributes( &attributes );
1151
1152 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1153 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1154 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1155 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1156 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001157 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001158}
1159/* END_CASE */
1160
1161/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001162void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1163 int expected_id_arg, int expected_lifetime_arg )
1164{
1165 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1166 psa_key_id_t id1 = id1_arg;
1167 psa_key_lifetime_t lifetime = lifetime_arg;
1168 psa_key_id_t id2 = id2_arg;
1169 psa_key_id_t expected_id = expected_id_arg;
1170 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1171
1172 if( id1_arg != -1 )
1173 psa_set_key_id( &attributes, id1 );
1174 if( lifetime_arg != -1 )
1175 psa_set_key_lifetime( &attributes, lifetime );
1176 if( id2_arg != -1 )
1177 psa_set_key_id( &attributes, id2 );
1178
1179 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1180 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1181}
1182/* END_CASE */
1183
1184/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001185void import( data_t *data, int type_arg,
1186 int attr_bits_arg,
1187 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001188{
1189 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1190 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001191 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001192 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001193 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001194 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001195 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001196
Gilles Peskine8817f612018-12-18 00:18:46 +01001197 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001198
Gilles Peskine4747d192019-04-17 15:05:45 +02001199 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001200 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001201 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001202 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001203 if( status != PSA_SUCCESS )
1204 goto exit;
1205
1206 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1207 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001208 if( attr_bits != 0 )
1209 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001210
1211 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001212 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001213
1214exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001215 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001216 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001217 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001218}
1219/* END_CASE */
1220
1221/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001222void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1223{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001224 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001225 size_t bits = bits_arg;
1226 psa_status_t expected_status = expected_status_arg;
1227 psa_status_t status;
1228 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001229 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001230 size_t buffer_size = /* Slight overapproximations */
1231 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001232 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001233 unsigned char *p;
1234 int ret;
1235 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001236 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001237
Gilles Peskine8817f612018-12-18 00:18:46 +01001238 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001239 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001240
1241 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1242 bits, keypair ) ) >= 0 );
1243 length = ret;
1244
1245 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001246 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001247 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001248 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001249
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001250 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001251 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001252
1253exit:
1254 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001255 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001256}
1257/* END_CASE */
1258
1259/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001260void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001261 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001262 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001263 int expected_bits,
1264 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001265 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001266 int canonical_input )
1267{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001268 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001269 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001270 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001271 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001272 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001273 unsigned char *exported = NULL;
1274 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001275 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001276 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001277 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001278 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001279 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001280
Moran Pekercb088e72018-07-17 17:36:59 +03001281 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001282 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001283 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001284 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001285 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001286
Gilles Peskine4747d192019-04-17 15:05:45 +02001287 psa_set_key_usage_flags( &attributes, usage_arg );
1288 psa_set_key_algorithm( &attributes, alg );
1289 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001290
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001291 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001292 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001293
1294 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001295 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1296 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1297 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001298
1299 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001300 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001301 exported, export_size,
1302 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001303 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001304
1305 /* The exported length must be set by psa_export_key() to a value between 0
1306 * and export_size. On errors, the exported length must be 0. */
1307 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1308 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1309 TEST_ASSERT( exported_length <= export_size );
1310
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001311 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001312 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001313 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001314 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001315 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001316 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001317 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001318
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001319 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001320 goto exit;
1321
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001322 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001323 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001324 else
1325 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001326 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001327 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1328 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001329 PSA_ASSERT( psa_export_key( handle2,
1330 reexported,
1331 export_size,
1332 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001333 ASSERT_COMPARE( exported, exported_length,
1334 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001335 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001336 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001337 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001338
1339destroy:
1340 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001341 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001342 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001343
1344exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001345 mbedtls_free( exported );
1346 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001347 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001348 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001349}
1350/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001351
Moran Pekerf709f4a2018-06-06 17:26:04 +03001352/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001353void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001354{
Gilles Peskine8817f612018-12-18 00:18:46 +01001355 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001356 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001357
1358exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001359 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001360}
1361/* END_CASE */
1362
1363/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001364void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001365 int type_arg,
1366 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001367 int export_size_delta,
1368 int expected_export_status_arg,
1369 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001370{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001371 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001372 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001373 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001374 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001375 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001376 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001377 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001378 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001379 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001380
Gilles Peskine8817f612018-12-18 00:18:46 +01001381 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001382
Gilles Peskine4747d192019-04-17 15:05:45 +02001383 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1384 psa_set_key_algorithm( &attributes, alg );
1385 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001386
1387 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001388 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001389
Gilles Peskine49c25912018-10-29 15:15:31 +01001390 /* Export the public key */
1391 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001392 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001393 exported, export_size,
1394 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001395 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001396 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001397 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001398 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001399 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001400 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1401 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001402 TEST_ASSERT( expected_public_key->len <=
1403 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001404 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1405 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001406 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001407
1408exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001409 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001410 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001411 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001412 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001413}
1414/* END_CASE */
1415
Gilles Peskine20035e32018-02-03 22:44:14 +01001416/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001417void import_and_exercise_key( data_t *data,
1418 int type_arg,
1419 int bits_arg,
1420 int alg_arg )
1421{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001422 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001423 psa_key_type_t type = type_arg;
1424 size_t bits = bits_arg;
1425 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001426 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001427 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001428 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001429
Gilles Peskine8817f612018-12-18 00:18:46 +01001430 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001431
Gilles Peskine4747d192019-04-17 15:05:45 +02001432 psa_set_key_usage_flags( &attributes, usage );
1433 psa_set_key_algorithm( &attributes, alg );
1434 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001435
1436 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001437 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001438
1439 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001440 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1441 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1442 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001443
1444 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001445 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001446 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001447
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001448 PSA_ASSERT( psa_destroy_key( handle ) );
1449 test_operations_on_invalid_handle( handle );
1450
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001451exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001452 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001453 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001454 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001455}
1456/* END_CASE */
1457
1458/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001459void key_policy( int usage_arg, int alg_arg )
1460{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001461 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001462 psa_algorithm_t alg = alg_arg;
1463 psa_key_usage_t usage = usage_arg;
1464 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1465 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001466 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001467
1468 memset( key, 0x2a, sizeof( key ) );
1469
Gilles Peskine8817f612018-12-18 00:18:46 +01001470 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001471
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001472 psa_set_key_usage_flags( &attributes, usage );
1473 psa_set_key_algorithm( &attributes, alg );
1474 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001475
Gilles Peskine73676cb2019-05-15 20:15:10 +02001476 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001477
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001478 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1479 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1480 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1481 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001482
1483exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001484 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001485 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001486 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001487}
1488/* END_CASE */
1489
1490/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001491void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001492{
1493 /* Test each valid way of initializing the object, except for `= {0}`, as
1494 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1495 * though it's OK by the C standard. We could test for this, but we'd need
1496 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001497 psa_key_attributes_t func = psa_key_attributes_init( );
1498 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1499 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001500
1501 memset( &zero, 0, sizeof( zero ) );
1502
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001503 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1504 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1505 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001506
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001507 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1508 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1509 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1510
1511 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1512 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1513 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1514
1515 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1516 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1517 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1518
1519 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1520 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1521 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001522}
1523/* END_CASE */
1524
1525/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001526void mac_key_policy( int policy_usage,
1527 int policy_alg,
1528 int key_type,
1529 data_t *key_data,
1530 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001531{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001532 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001533 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001534 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001535 psa_status_t status;
1536 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001537
Gilles Peskine8817f612018-12-18 00:18:46 +01001538 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001539
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001540 psa_set_key_usage_flags( &attributes, policy_usage );
1541 psa_set_key_algorithm( &attributes, policy_alg );
1542 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001543
Gilles Peskine049c7532019-05-15 20:22:09 +02001544 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1545 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001546
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001547 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001548 if( policy_alg == exercise_alg &&
1549 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001550 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001551 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001552 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001553 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001554
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001555 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001556 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001557 if( policy_alg == exercise_alg &&
1558 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001559 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001560 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001561 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001562
1563exit:
1564 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001565 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001566 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001567}
1568/* END_CASE */
1569
1570/* BEGIN_CASE */
1571void cipher_key_policy( int policy_usage,
1572 int policy_alg,
1573 int key_type,
1574 data_t *key_data,
1575 int exercise_alg )
1576{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001577 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001578 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001579 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001580 psa_status_t status;
1581
Gilles Peskine8817f612018-12-18 00:18:46 +01001582 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001583
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001584 psa_set_key_usage_flags( &attributes, policy_usage );
1585 psa_set_key_algorithm( &attributes, policy_alg );
1586 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001587
Gilles Peskine049c7532019-05-15 20:22:09 +02001588 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1589 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001590
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001591 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001592 if( policy_alg == exercise_alg &&
1593 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001594 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001595 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001596 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001597 psa_cipher_abort( &operation );
1598
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001599 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001600 if( policy_alg == exercise_alg &&
1601 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001602 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001603 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001604 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001605
1606exit:
1607 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001608 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001609 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001610}
1611/* END_CASE */
1612
1613/* BEGIN_CASE */
1614void aead_key_policy( int policy_usage,
1615 int policy_alg,
1616 int key_type,
1617 data_t *key_data,
1618 int nonce_length_arg,
1619 int tag_length_arg,
1620 int exercise_alg )
1621{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001622 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001623 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001624 psa_status_t status;
1625 unsigned char nonce[16] = {0};
1626 size_t nonce_length = nonce_length_arg;
1627 unsigned char tag[16];
1628 size_t tag_length = tag_length_arg;
1629 size_t output_length;
1630
1631 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1632 TEST_ASSERT( tag_length <= sizeof( tag ) );
1633
Gilles Peskine8817f612018-12-18 00:18:46 +01001634 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001635
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001636 psa_set_key_usage_flags( &attributes, policy_usage );
1637 psa_set_key_algorithm( &attributes, policy_alg );
1638 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001639
Gilles Peskine049c7532019-05-15 20:22:09 +02001640 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1641 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001642
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001643 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001644 nonce, nonce_length,
1645 NULL, 0,
1646 NULL, 0,
1647 tag, tag_length,
1648 &output_length );
1649 if( policy_alg == exercise_alg &&
1650 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001651 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001652 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001653 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654
1655 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001656 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001657 nonce, nonce_length,
1658 NULL, 0,
1659 tag, tag_length,
1660 NULL, 0,
1661 &output_length );
1662 if( policy_alg == exercise_alg &&
1663 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001664 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001665 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001666 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001667
1668exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001669 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001670 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001671}
1672/* END_CASE */
1673
1674/* BEGIN_CASE */
1675void asymmetric_encryption_key_policy( int policy_usage,
1676 int policy_alg,
1677 int key_type,
1678 data_t *key_data,
1679 int exercise_alg )
1680{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001681 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001682 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001683 psa_status_t status;
1684 size_t key_bits;
1685 size_t buffer_length;
1686 unsigned char *buffer = NULL;
1687 size_t output_length;
1688
Gilles Peskine8817f612018-12-18 00:18:46 +01001689 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001690
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001691 psa_set_key_usage_flags( &attributes, policy_usage );
1692 psa_set_key_algorithm( &attributes, policy_alg );
1693 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001694
Gilles Peskine049c7532019-05-15 20:22:09 +02001695 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1696 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001697
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001698 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1699 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001700 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1701 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001702 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001703
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001704 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705 NULL, 0,
1706 NULL, 0,
1707 buffer, buffer_length,
1708 &output_length );
1709 if( policy_alg == exercise_alg &&
1710 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001711 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001712 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001713 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001714
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001715 if( buffer_length != 0 )
1716 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001717 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001718 buffer, buffer_length,
1719 NULL, 0,
1720 buffer, buffer_length,
1721 &output_length );
1722 if( policy_alg == exercise_alg &&
1723 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001724 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001725 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001726 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001727
1728exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001729 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001730 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001731 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001732 mbedtls_free( buffer );
1733}
1734/* END_CASE */
1735
1736/* BEGIN_CASE */
1737void asymmetric_signature_key_policy( int policy_usage,
1738 int policy_alg,
1739 int key_type,
1740 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001741 int exercise_alg,
1742 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001743{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001744 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001745 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001746 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001747 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1748 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1749 * compatible with the policy and `payload_length_arg` is supposed to be
1750 * a valid input length to sign. If `payload_length_arg <= 0`,
1751 * `exercise_alg` is supposed to be forbidden by the policy. */
1752 int compatible_alg = payload_length_arg > 0;
1753 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001754 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1755 size_t signature_length;
1756
Gilles Peskine8817f612018-12-18 00:18:46 +01001757 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001759 psa_set_key_usage_flags( &attributes, policy_usage );
1760 psa_set_key_algorithm( &attributes, policy_alg );
1761 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762
Gilles Peskine049c7532019-05-15 20:22:09 +02001763 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1764 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001765
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001766 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001768 signature, sizeof( signature ),
1769 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001770 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001771 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001772 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001773 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001774
1775 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001776 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001777 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001778 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001779 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001780 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001781 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001782 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001783
1784exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001785 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001786 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001787}
1788/* END_CASE */
1789
Janos Follathba3fab92019-06-11 14:50:16 +01001790/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001791void derive_key_policy( int policy_usage,
1792 int policy_alg,
1793 int key_type,
1794 data_t *key_data,
1795 int exercise_alg )
1796{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001797 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001798 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001799 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001800 psa_status_t status;
1801
Gilles Peskine8817f612018-12-18 00:18:46 +01001802 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001803
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001804 psa_set_key_usage_flags( &attributes, policy_usage );
1805 psa_set_key_algorithm( &attributes, policy_alg );
1806 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001807
Gilles Peskine049c7532019-05-15 20:22:09 +02001808 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1809 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001810
Janos Follathba3fab92019-06-11 14:50:16 +01001811 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1812
1813 if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
1814 PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
Janos Follath0c1ed842019-06-28 13:35:36 +01001815 {
Janos Follathba3fab92019-06-11 14:50:16 +01001816 PSA_ASSERT( psa_key_derivation_input_bytes(
1817 &operation,
1818 PSA_KEY_DERIVATION_INPUT_SEED,
1819 (const uint8_t*) "", 0) );
Janos Follath0c1ed842019-06-28 13:35:36 +01001820 }
Janos Follathba3fab92019-06-11 14:50:16 +01001821
1822 status = psa_key_derivation_input_key( &operation,
1823 PSA_KEY_DERIVATION_INPUT_SECRET,
1824 handle );
1825
Gilles Peskineea0fb492018-07-12 17:17:20 +02001826 if( policy_alg == exercise_alg &&
1827 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001828 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001829 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001830 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001831
1832exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001833 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001834 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001835 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001836}
1837/* END_CASE */
1838
1839/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001840void agreement_key_policy( int policy_usage,
1841 int policy_alg,
1842 int key_type_arg,
1843 data_t *key_data,
1844 int exercise_alg )
1845{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001846 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001847 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001848 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001849 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001850 psa_status_t status;
1851
Gilles Peskine8817f612018-12-18 00:18:46 +01001852 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001853
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001854 psa_set_key_usage_flags( &attributes, policy_usage );
1855 psa_set_key_algorithm( &attributes, policy_alg );
1856 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001857
Gilles Peskine049c7532019-05-15 20:22:09 +02001858 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1859 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001860
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001861 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1862 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001863
Gilles Peskine01d718c2018-09-18 12:01:02 +02001864 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 Peskine01d718c2018-09-18 12:01:02 +02001867 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001868 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +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 Peskine1153e7b2019-05-28 15:10:21 +02001873 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001874}
1875/* END_CASE */
1876
1877/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001878void key_policy_alg2( int key_type_arg, data_t *key_data,
1879 int usage_arg, int alg_arg, int alg2_arg )
1880{
1881 psa_key_handle_t handle = 0;
1882 psa_key_type_t key_type = key_type_arg;
1883 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1884 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1885 psa_key_usage_t usage = usage_arg;
1886 psa_algorithm_t alg = alg_arg;
1887 psa_algorithm_t alg2 = alg2_arg;
1888
1889 PSA_ASSERT( psa_crypto_init( ) );
1890
1891 psa_set_key_usage_flags( &attributes, usage );
1892 psa_set_key_algorithm( &attributes, alg );
1893 psa_set_key_enrollment_algorithm( &attributes, alg2 );
1894 psa_set_key_type( &attributes, key_type );
1895 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1896 &handle ) );
1897
1898 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1899 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1900 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1901 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
1902
1903 if( ! exercise_key( handle, usage, alg ) )
1904 goto exit;
1905 if( ! exercise_key( handle, usage, alg2 ) )
1906 goto exit;
1907
1908exit:
1909 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001910 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001911}
1912/* END_CASE */
1913
1914/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001915void raw_agreement_key_policy( int policy_usage,
1916 int policy_alg,
1917 int key_type_arg,
1918 data_t *key_data,
1919 int exercise_alg )
1920{
1921 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001922 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001923 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001924 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001925 psa_status_t status;
1926
1927 PSA_ASSERT( psa_crypto_init( ) );
1928
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001929 psa_set_key_usage_flags( &attributes, policy_usage );
1930 psa_set_key_algorithm( &attributes, policy_alg );
1931 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001932
Gilles Peskine049c7532019-05-15 20:22:09 +02001933 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1934 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001935
1936 status = raw_key_agreement_with_self( exercise_alg, handle );
1937
1938 if( policy_alg == exercise_alg &&
1939 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1940 PSA_ASSERT( status );
1941 else
1942 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1943
1944exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001945 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001946 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001947 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001948}
1949/* END_CASE */
1950
1951/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001952void copy_success( int source_usage_arg,
1953 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02001954 int type_arg, data_t *material,
1955 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001956 int target_usage_arg,
1957 int target_alg_arg, int target_alg2_arg,
1958 int expected_usage_arg,
1959 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001960{
Gilles Peskineca25db92019-04-19 11:43:08 +02001961 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1962 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001963 psa_key_usage_t expected_usage = expected_usage_arg;
1964 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001965 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001966 psa_key_handle_t source_handle = 0;
1967 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001968 uint8_t *export_buffer = NULL;
1969
Gilles Peskine57ab7212019-01-28 13:03:09 +01001970 PSA_ASSERT( psa_crypto_init( ) );
1971
Gilles Peskineca25db92019-04-19 11:43:08 +02001972 /* Prepare the source key. */
1973 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1974 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001975 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02001976 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02001977 PSA_ASSERT( psa_import_key( &source_attributes,
1978 material->x, material->len,
1979 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001980 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001981
Gilles Peskineca25db92019-04-19 11:43:08 +02001982 /* Prepare the target attributes. */
1983 if( copy_attributes )
1984 target_attributes = source_attributes;
1985 if( target_usage_arg != -1 )
1986 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1987 if( target_alg_arg != -1 )
1988 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001989 if( target_alg2_arg != -1 )
1990 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001991
1992 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02001993 PSA_ASSERT( psa_copy_key( source_handle,
1994 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001995
1996 /* Destroy the source to ensure that this doesn't affect the target. */
1997 PSA_ASSERT( psa_destroy_key( source_handle ) );
1998
1999 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002000 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2001 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2002 psa_get_key_type( &target_attributes ) );
2003 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2004 psa_get_key_bits( &target_attributes ) );
2005 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2006 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002007 TEST_EQUAL( expected_alg2,
2008 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002009 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2010 {
2011 size_t length;
2012 ASSERT_ALLOC( export_buffer, material->len );
2013 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2014 material->len, &length ) );
2015 ASSERT_COMPARE( material->x, material->len,
2016 export_buffer, length );
2017 }
2018 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2019 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002020 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2021 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002022
2023 PSA_ASSERT( psa_close_key( target_handle ) );
2024
2025exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002026 psa_reset_key_attributes( &source_attributes );
2027 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002028 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002029 mbedtls_free( export_buffer );
2030}
2031/* END_CASE */
2032
2033/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002034void copy_fail( int source_usage_arg,
2035 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002036 int type_arg, data_t *material,
2037 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002038 int target_usage_arg,
2039 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002040 int expected_status_arg )
2041{
2042 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2043 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2044 psa_key_handle_t source_handle = 0;
2045 psa_key_handle_t target_handle = 0;
2046
2047 PSA_ASSERT( psa_crypto_init( ) );
2048
2049 /* Prepare the source key. */
2050 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2051 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002052 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002053 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002054 PSA_ASSERT( psa_import_key( &source_attributes,
2055 material->x, material->len,
2056 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002057
2058 /* Prepare the target attributes. */
2059 psa_set_key_type( &target_attributes, target_type_arg );
2060 psa_set_key_bits( &target_attributes, target_bits_arg );
2061 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2062 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002063 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002064
2065 /* Try to copy the key. */
2066 TEST_EQUAL( psa_copy_key( source_handle,
2067 &target_attributes, &target_handle ),
2068 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002069
2070 PSA_ASSERT( psa_destroy_key( source_handle ) );
2071
Gilles Peskine4a644642019-05-03 17:14:08 +02002072exit:
2073 psa_reset_key_attributes( &source_attributes );
2074 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002075 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002076}
2077/* END_CASE */
2078
2079/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002080void hash_operation_init( )
2081{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002082 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002083 /* Test each valid way of initializing the object, except for `= {0}`, as
2084 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2085 * though it's OK by the C standard. We could test for this, but we'd need
2086 * to supress the Clang warning for the test. */
2087 psa_hash_operation_t func = psa_hash_operation_init( );
2088 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2089 psa_hash_operation_t zero;
2090
2091 memset( &zero, 0, sizeof( zero ) );
2092
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002093 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002094 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2095 PSA_ERROR_BAD_STATE );
2096 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2097 PSA_ERROR_BAD_STATE );
2098 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2099 PSA_ERROR_BAD_STATE );
2100
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002101 /* A default hash operation should be abortable without error. */
2102 PSA_ASSERT( psa_hash_abort( &func ) );
2103 PSA_ASSERT( psa_hash_abort( &init ) );
2104 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002105}
2106/* END_CASE */
2107
2108/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002109void hash_setup( int alg_arg,
2110 int expected_status_arg )
2111{
2112 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002113 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002114 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002115 psa_status_t status;
2116
Gilles Peskine8817f612018-12-18 00:18:46 +01002117 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002118
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002119 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002120 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002121
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002122 /* Whether setup succeeded or failed, abort must succeed. */
2123 PSA_ASSERT( psa_hash_abort( &operation ) );
2124
2125 /* If setup failed, reproduce the failure, so as to
2126 * test the resulting state of the operation object. */
2127 if( status != PSA_SUCCESS )
2128 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2129
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002130 /* Now the operation object should be reusable. */
2131#if defined(KNOWN_SUPPORTED_HASH_ALG)
2132 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2133 PSA_ASSERT( psa_hash_abort( &operation ) );
2134#endif
2135
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002136exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002137 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002138}
2139/* END_CASE */
2140
2141/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002142void hash_bad_order( )
2143{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002144 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002145 unsigned char input[] = "";
2146 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002147 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002148 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2149 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2150 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002151 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002152 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002153 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002154
Gilles Peskine8817f612018-12-18 00:18:46 +01002155 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002156
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002157 /* Call setup twice in a row. */
2158 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2159 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2160 PSA_ERROR_BAD_STATE );
2161 PSA_ASSERT( psa_hash_abort( &operation ) );
2162
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002163 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002164 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002165 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002166 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002167
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002168 /* Call update after finish. */
2169 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2170 PSA_ASSERT( psa_hash_finish( &operation,
2171 hash, sizeof( hash ), &hash_len ) );
2172 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002173 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002174 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002175
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002176 /* Call verify without calling setup beforehand. */
2177 TEST_EQUAL( psa_hash_verify( &operation,
2178 valid_hash, sizeof( valid_hash ) ),
2179 PSA_ERROR_BAD_STATE );
2180 PSA_ASSERT( psa_hash_abort( &operation ) );
2181
2182 /* Call verify after finish. */
2183 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2184 PSA_ASSERT( psa_hash_finish( &operation,
2185 hash, sizeof( hash ), &hash_len ) );
2186 TEST_EQUAL( psa_hash_verify( &operation,
2187 valid_hash, sizeof( valid_hash ) ),
2188 PSA_ERROR_BAD_STATE );
2189 PSA_ASSERT( psa_hash_abort( &operation ) );
2190
2191 /* Call verify twice in a row. */
2192 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2193 PSA_ASSERT( psa_hash_verify( &operation,
2194 valid_hash, sizeof( valid_hash ) ) );
2195 TEST_EQUAL( psa_hash_verify( &operation,
2196 valid_hash, sizeof( valid_hash ) ),
2197 PSA_ERROR_BAD_STATE );
2198 PSA_ASSERT( psa_hash_abort( &operation ) );
2199
2200 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002201 TEST_EQUAL( psa_hash_finish( &operation,
2202 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002203 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002204 PSA_ASSERT( psa_hash_abort( &operation ) );
2205
2206 /* Call finish twice in a row. */
2207 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2208 PSA_ASSERT( psa_hash_finish( &operation,
2209 hash, sizeof( hash ), &hash_len ) );
2210 TEST_EQUAL( psa_hash_finish( &operation,
2211 hash, sizeof( hash ), &hash_len ),
2212 PSA_ERROR_BAD_STATE );
2213 PSA_ASSERT( psa_hash_abort( &operation ) );
2214
2215 /* Call finish after calling verify. */
2216 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2217 PSA_ASSERT( psa_hash_verify( &operation,
2218 valid_hash, sizeof( valid_hash ) ) );
2219 TEST_EQUAL( psa_hash_finish( &operation,
2220 hash, sizeof( hash ), &hash_len ),
2221 PSA_ERROR_BAD_STATE );
2222 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002223
2224exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002225 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002226}
2227/* END_CASE */
2228
itayzafrir27e69452018-11-01 14:26:34 +02002229/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2230void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002231{
2232 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002233 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2234 * appended to it */
2235 unsigned char hash[] = {
2236 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2237 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2238 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002239 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002240 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002241
Gilles Peskine8817f612018-12-18 00:18:46 +01002242 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002243
itayzafrir27e69452018-11-01 14:26:34 +02002244 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002245 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002246 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002247 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002248
itayzafrir27e69452018-11-01 14:26:34 +02002249 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002250 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002251 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002252 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002253
itayzafrir27e69452018-11-01 14:26:34 +02002254 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002255 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002256 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002257 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002258
itayzafrirec93d302018-10-18 18:01:10 +03002259exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002260 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002261}
2262/* END_CASE */
2263
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002264/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2265void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002266{
2267 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002268 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002269 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002270 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002271 size_t hash_len;
2272
Gilles Peskine8817f612018-12-18 00:18:46 +01002273 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002274
itayzafrir58028322018-10-25 10:22:01 +03002275 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002276 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002277 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002278 hash, expected_size - 1, &hash_len ),
2279 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002280
2281exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002282 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002283}
2284/* END_CASE */
2285
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002286/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2287void hash_clone_source_state( )
2288{
2289 psa_algorithm_t alg = PSA_ALG_SHA_256;
2290 unsigned char hash[PSA_HASH_MAX_SIZE];
2291 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2292 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2293 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2294 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2295 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2296 size_t hash_len;
2297
2298 PSA_ASSERT( psa_crypto_init( ) );
2299 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2300
2301 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2302 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2303 PSA_ASSERT( psa_hash_finish( &op_finished,
2304 hash, sizeof( hash ), &hash_len ) );
2305 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2306 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2307
2308 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2309 PSA_ERROR_BAD_STATE );
2310
2311 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2312 PSA_ASSERT( psa_hash_finish( &op_init,
2313 hash, sizeof( hash ), &hash_len ) );
2314 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2315 PSA_ASSERT( psa_hash_finish( &op_finished,
2316 hash, sizeof( hash ), &hash_len ) );
2317 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2318 PSA_ASSERT( psa_hash_finish( &op_aborted,
2319 hash, sizeof( hash ), &hash_len ) );
2320
2321exit:
2322 psa_hash_abort( &op_source );
2323 psa_hash_abort( &op_init );
2324 psa_hash_abort( &op_setup );
2325 psa_hash_abort( &op_finished );
2326 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002327 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002328}
2329/* END_CASE */
2330
2331/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2332void hash_clone_target_state( )
2333{
2334 psa_algorithm_t alg = PSA_ALG_SHA_256;
2335 unsigned char hash[PSA_HASH_MAX_SIZE];
2336 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2337 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2338 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2339 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2340 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2341 size_t hash_len;
2342
2343 PSA_ASSERT( psa_crypto_init( ) );
2344
2345 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2346 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2347 PSA_ASSERT( psa_hash_finish( &op_finished,
2348 hash, sizeof( hash ), &hash_len ) );
2349 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2350 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2351
2352 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2353 PSA_ASSERT( psa_hash_finish( &op_target,
2354 hash, sizeof( hash ), &hash_len ) );
2355
2356 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2357 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2358 PSA_ERROR_BAD_STATE );
2359 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2360 PSA_ERROR_BAD_STATE );
2361
2362exit:
2363 psa_hash_abort( &op_target );
2364 psa_hash_abort( &op_init );
2365 psa_hash_abort( &op_setup );
2366 psa_hash_abort( &op_finished );
2367 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002368 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002369}
2370/* END_CASE */
2371
itayzafrir58028322018-10-25 10:22:01 +03002372/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002373void mac_operation_init( )
2374{
Jaeden Amero252ef282019-02-15 14:05:35 +00002375 const uint8_t input[1] = { 0 };
2376
Jaeden Amero769ce272019-01-04 11:48:03 +00002377 /* Test each valid way of initializing the object, except for `= {0}`, as
2378 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2379 * though it's OK by the C standard. We could test for this, but we'd need
2380 * to supress the Clang warning for the test. */
2381 psa_mac_operation_t func = psa_mac_operation_init( );
2382 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2383 psa_mac_operation_t zero;
2384
2385 memset( &zero, 0, sizeof( zero ) );
2386
Jaeden Amero252ef282019-02-15 14:05:35 +00002387 /* A freshly-initialized MAC operation should not be usable. */
2388 TEST_EQUAL( psa_mac_update( &func,
2389 input, sizeof( input ) ),
2390 PSA_ERROR_BAD_STATE );
2391 TEST_EQUAL( psa_mac_update( &init,
2392 input, sizeof( input ) ),
2393 PSA_ERROR_BAD_STATE );
2394 TEST_EQUAL( psa_mac_update( &zero,
2395 input, sizeof( input ) ),
2396 PSA_ERROR_BAD_STATE );
2397
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002398 /* A default MAC operation should be abortable without error. */
2399 PSA_ASSERT( psa_mac_abort( &func ) );
2400 PSA_ASSERT( psa_mac_abort( &init ) );
2401 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002402}
2403/* END_CASE */
2404
2405/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002406void mac_setup( int key_type_arg,
2407 data_t *key,
2408 int alg_arg,
2409 int expected_status_arg )
2410{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002411 psa_key_type_t key_type = key_type_arg;
2412 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002413 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002414 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002415 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2416#if defined(KNOWN_SUPPORTED_MAC_ALG)
2417 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2418#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002419
Gilles Peskine8817f612018-12-18 00:18:46 +01002420 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002421
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002422 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2423 &operation, &status ) )
2424 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002425 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002426
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002427 /* The operation object should be reusable. */
2428#if defined(KNOWN_SUPPORTED_MAC_ALG)
2429 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2430 smoke_test_key_data,
2431 sizeof( smoke_test_key_data ),
2432 KNOWN_SUPPORTED_MAC_ALG,
2433 &operation, &status ) )
2434 goto exit;
2435 TEST_EQUAL( status, PSA_SUCCESS );
2436#endif
2437
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002438exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002439 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002440}
2441/* END_CASE */
2442
2443/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002444void mac_bad_order( )
2445{
2446 psa_key_handle_t handle = 0;
2447 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2448 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2449 const uint8_t key[] = {
2450 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2451 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2452 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002453 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002454 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2455 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2456 size_t sign_mac_length = 0;
2457 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2458 const uint8_t verify_mac[] = {
2459 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2460 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2461 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2462
2463 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002464 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2465 psa_set_key_algorithm( &attributes, alg );
2466 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002467
Gilles Peskine73676cb2019-05-15 20:15:10 +02002468 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002469
Jaeden Amero252ef282019-02-15 14:05:35 +00002470 /* Call update without calling setup beforehand. */
2471 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2472 PSA_ERROR_BAD_STATE );
2473 PSA_ASSERT( psa_mac_abort( &operation ) );
2474
2475 /* Call sign finish without calling setup beforehand. */
2476 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2477 &sign_mac_length),
2478 PSA_ERROR_BAD_STATE );
2479 PSA_ASSERT( psa_mac_abort( &operation ) );
2480
2481 /* Call verify finish without calling setup beforehand. */
2482 TEST_EQUAL( psa_mac_verify_finish( &operation,
2483 verify_mac, sizeof( verify_mac ) ),
2484 PSA_ERROR_BAD_STATE );
2485 PSA_ASSERT( psa_mac_abort( &operation ) );
2486
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002487 /* Call setup twice in a row. */
2488 PSA_ASSERT( psa_mac_sign_setup( &operation,
2489 handle, alg ) );
2490 TEST_EQUAL( psa_mac_sign_setup( &operation,
2491 handle, alg ),
2492 PSA_ERROR_BAD_STATE );
2493 PSA_ASSERT( psa_mac_abort( &operation ) );
2494
Jaeden Amero252ef282019-02-15 14:05:35 +00002495 /* Call update after sign finish. */
2496 PSA_ASSERT( psa_mac_sign_setup( &operation,
2497 handle, alg ) );
2498 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2499 PSA_ASSERT( psa_mac_sign_finish( &operation,
2500 sign_mac, sizeof( sign_mac ),
2501 &sign_mac_length ) );
2502 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2503 PSA_ERROR_BAD_STATE );
2504 PSA_ASSERT( psa_mac_abort( &operation ) );
2505
2506 /* Call update after verify finish. */
2507 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002508 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002509 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2510 PSA_ASSERT( psa_mac_verify_finish( &operation,
2511 verify_mac, sizeof( verify_mac ) ) );
2512 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2513 PSA_ERROR_BAD_STATE );
2514 PSA_ASSERT( psa_mac_abort( &operation ) );
2515
2516 /* Call sign finish twice in a row. */
2517 PSA_ASSERT( psa_mac_sign_setup( &operation,
2518 handle, alg ) );
2519 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2520 PSA_ASSERT( psa_mac_sign_finish( &operation,
2521 sign_mac, sizeof( sign_mac ),
2522 &sign_mac_length ) );
2523 TEST_EQUAL( psa_mac_sign_finish( &operation,
2524 sign_mac, sizeof( sign_mac ),
2525 &sign_mac_length ),
2526 PSA_ERROR_BAD_STATE );
2527 PSA_ASSERT( psa_mac_abort( &operation ) );
2528
2529 /* Call verify finish twice in a row. */
2530 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002531 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002532 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2533 PSA_ASSERT( psa_mac_verify_finish( &operation,
2534 verify_mac, sizeof( verify_mac ) ) );
2535 TEST_EQUAL( psa_mac_verify_finish( &operation,
2536 verify_mac, sizeof( verify_mac ) ),
2537 PSA_ERROR_BAD_STATE );
2538 PSA_ASSERT( psa_mac_abort( &operation ) );
2539
2540 /* Setup sign but try verify. */
2541 PSA_ASSERT( psa_mac_sign_setup( &operation,
2542 handle, alg ) );
2543 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2544 TEST_EQUAL( psa_mac_verify_finish( &operation,
2545 verify_mac, sizeof( verify_mac ) ),
2546 PSA_ERROR_BAD_STATE );
2547 PSA_ASSERT( psa_mac_abort( &operation ) );
2548
2549 /* Setup verify but try sign. */
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 TEST_EQUAL( psa_mac_sign_finish( &operation,
2554 sign_mac, sizeof( sign_mac ),
2555 &sign_mac_length ),
2556 PSA_ERROR_BAD_STATE );
2557 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002558
Gilles Peskine76b29a72019-05-28 14:08:50 +02002559 PSA_ASSERT( psa_destroy_key( handle ) );
2560
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002561exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002562 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002563}
2564/* END_CASE */
2565
2566/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002567void mac_sign( int key_type_arg,
2568 data_t *key,
2569 int alg_arg,
2570 data_t *input,
2571 data_t *expected_mac )
2572{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002573 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002574 psa_key_type_t key_type = key_type_arg;
2575 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002576 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002577 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002578 /* Leave a little extra room in the output buffer. At the end of the
2579 * test, we'll check that the implementation didn't overwrite onto
2580 * this extra room. */
2581 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2582 size_t mac_buffer_size =
2583 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2584 size_t mac_length = 0;
2585
2586 memset( actual_mac, '+', sizeof( actual_mac ) );
2587 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2588 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2589
Gilles Peskine8817f612018-12-18 00:18:46 +01002590 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002591
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002592 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2593 psa_set_key_algorithm( &attributes, alg );
2594 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002595
Gilles Peskine73676cb2019-05-15 20:15:10 +02002596 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002597
2598 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002599 PSA_ASSERT( psa_mac_sign_setup( &operation,
2600 handle, alg ) );
2601 PSA_ASSERT( psa_mac_update( &operation,
2602 input->x, input->len ) );
2603 PSA_ASSERT( psa_mac_sign_finish( &operation,
2604 actual_mac, mac_buffer_size,
2605 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002606
2607 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002608 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2609 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002610
2611 /* Verify that the end of the buffer is untouched. */
2612 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2613 sizeof( actual_mac ) - mac_length ) );
2614
2615exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002616 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002617 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002618}
2619/* END_CASE */
2620
2621/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002622void mac_verify( int key_type_arg,
2623 data_t *key,
2624 int alg_arg,
2625 data_t *input,
2626 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002627{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002628 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002629 psa_key_type_t key_type = key_type_arg;
2630 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002631 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002632 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002633
Gilles Peskine69c12672018-06-28 00:07:19 +02002634 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2635
Gilles Peskine8817f612018-12-18 00:18:46 +01002636 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002637
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002638 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2639 psa_set_key_algorithm( &attributes, alg );
2640 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002641
Gilles Peskine73676cb2019-05-15 20:15:10 +02002642 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002643
Gilles Peskine8817f612018-12-18 00:18:46 +01002644 PSA_ASSERT( psa_mac_verify_setup( &operation,
2645 handle, alg ) );
2646 PSA_ASSERT( psa_destroy_key( handle ) );
2647 PSA_ASSERT( psa_mac_update( &operation,
2648 input->x, input->len ) );
2649 PSA_ASSERT( psa_mac_verify_finish( &operation,
2650 expected_mac->x,
2651 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002652
2653exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002654 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002655 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002656}
2657/* END_CASE */
2658
2659/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002660void cipher_operation_init( )
2661{
Jaeden Ameroab439972019-02-15 14:12:05 +00002662 const uint8_t input[1] = { 0 };
2663 unsigned char output[1] = { 0 };
2664 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002665 /* Test each valid way of initializing the object, except for `= {0}`, as
2666 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2667 * though it's OK by the C standard. We could test for this, but we'd need
2668 * to supress the Clang warning for the test. */
2669 psa_cipher_operation_t func = psa_cipher_operation_init( );
2670 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2671 psa_cipher_operation_t zero;
2672
2673 memset( &zero, 0, sizeof( zero ) );
2674
Jaeden Ameroab439972019-02-15 14:12:05 +00002675 /* A freshly-initialized cipher operation should not be usable. */
2676 TEST_EQUAL( psa_cipher_update( &func,
2677 input, sizeof( input ),
2678 output, sizeof( output ),
2679 &output_length ),
2680 PSA_ERROR_BAD_STATE );
2681 TEST_EQUAL( psa_cipher_update( &init,
2682 input, sizeof( input ),
2683 output, sizeof( output ),
2684 &output_length ),
2685 PSA_ERROR_BAD_STATE );
2686 TEST_EQUAL( psa_cipher_update( &zero,
2687 input, sizeof( input ),
2688 output, sizeof( output ),
2689 &output_length ),
2690 PSA_ERROR_BAD_STATE );
2691
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002692 /* A default cipher operation should be abortable without error. */
2693 PSA_ASSERT( psa_cipher_abort( &func ) );
2694 PSA_ASSERT( psa_cipher_abort( &init ) );
2695 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002696}
2697/* END_CASE */
2698
2699/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002700void cipher_setup( int key_type_arg,
2701 data_t *key,
2702 int alg_arg,
2703 int expected_status_arg )
2704{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002705 psa_key_type_t key_type = key_type_arg;
2706 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002707 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002708 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002709 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002710#if defined(KNOWN_SUPPORTED_MAC_ALG)
2711 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2712#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002713
Gilles Peskine8817f612018-12-18 00:18:46 +01002714 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002715
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002716 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2717 &operation, &status ) )
2718 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002719 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002720
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002721 /* The operation object should be reusable. */
2722#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2723 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2724 smoke_test_key_data,
2725 sizeof( smoke_test_key_data ),
2726 KNOWN_SUPPORTED_CIPHER_ALG,
2727 &operation, &status ) )
2728 goto exit;
2729 TEST_EQUAL( status, PSA_SUCCESS );
2730#endif
2731
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002732exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002733 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002734}
2735/* END_CASE */
2736
2737/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002738void cipher_bad_order( )
2739{
2740 psa_key_handle_t handle = 0;
2741 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2742 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002743 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002744 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2745 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2746 const uint8_t key[] = {
2747 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2748 0xaa, 0xaa, 0xaa, 0xaa };
2749 const uint8_t text[] = {
2750 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2751 0xbb, 0xbb, 0xbb, 0xbb };
2752 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2753 size_t length = 0;
2754
2755 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002756 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2757 psa_set_key_algorithm( &attributes, alg );
2758 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002759 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002760
2761
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002762 /* Call encrypt setup twice in a row. */
2763 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2764 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2765 PSA_ERROR_BAD_STATE );
2766 PSA_ASSERT( psa_cipher_abort( &operation ) );
2767
2768 /* Call decrypt setup twice in a row. */
2769 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2770 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2771 PSA_ERROR_BAD_STATE );
2772 PSA_ASSERT( psa_cipher_abort( &operation ) );
2773
Jaeden Ameroab439972019-02-15 14:12:05 +00002774 /* Generate an IV without calling setup beforehand. */
2775 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2776 buffer, sizeof( buffer ),
2777 &length ),
2778 PSA_ERROR_BAD_STATE );
2779 PSA_ASSERT( psa_cipher_abort( &operation ) );
2780
2781 /* Generate an IV twice in a row. */
2782 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2783 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2784 buffer, sizeof( buffer ),
2785 &length ) );
2786 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2787 buffer, sizeof( buffer ),
2788 &length ),
2789 PSA_ERROR_BAD_STATE );
2790 PSA_ASSERT( psa_cipher_abort( &operation ) );
2791
2792 /* Generate an IV after it's already set. */
2793 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2794 PSA_ASSERT( psa_cipher_set_iv( &operation,
2795 iv, sizeof( iv ) ) );
2796 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2797 buffer, sizeof( buffer ),
2798 &length ),
2799 PSA_ERROR_BAD_STATE );
2800 PSA_ASSERT( psa_cipher_abort( &operation ) );
2801
2802 /* Set an IV without calling setup beforehand. */
2803 TEST_EQUAL( psa_cipher_set_iv( &operation,
2804 iv, sizeof( iv ) ),
2805 PSA_ERROR_BAD_STATE );
2806 PSA_ASSERT( psa_cipher_abort( &operation ) );
2807
2808 /* Set an IV after it's already set. */
2809 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2810 PSA_ASSERT( psa_cipher_set_iv( &operation,
2811 iv, sizeof( iv ) ) );
2812 TEST_EQUAL( psa_cipher_set_iv( &operation,
2813 iv, sizeof( iv ) ),
2814 PSA_ERROR_BAD_STATE );
2815 PSA_ASSERT( psa_cipher_abort( &operation ) );
2816
2817 /* Set an IV after it's already generated. */
2818 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2819 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2820 buffer, sizeof( buffer ),
2821 &length ) );
2822 TEST_EQUAL( psa_cipher_set_iv( &operation,
2823 iv, sizeof( iv ) ),
2824 PSA_ERROR_BAD_STATE );
2825 PSA_ASSERT( psa_cipher_abort( &operation ) );
2826
2827 /* Call update without calling setup beforehand. */
2828 TEST_EQUAL( psa_cipher_update( &operation,
2829 text, sizeof( text ),
2830 buffer, sizeof( buffer ),
2831 &length ),
2832 PSA_ERROR_BAD_STATE );
2833 PSA_ASSERT( psa_cipher_abort( &operation ) );
2834
2835 /* Call update without an IV where an IV is required. */
2836 TEST_EQUAL( psa_cipher_update( &operation,
2837 text, sizeof( text ),
2838 buffer, sizeof( buffer ),
2839 &length ),
2840 PSA_ERROR_BAD_STATE );
2841 PSA_ASSERT( psa_cipher_abort( &operation ) );
2842
2843 /* Call update after finish. */
2844 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2845 PSA_ASSERT( psa_cipher_set_iv( &operation,
2846 iv, sizeof( iv ) ) );
2847 PSA_ASSERT( psa_cipher_finish( &operation,
2848 buffer, sizeof( buffer ), &length ) );
2849 TEST_EQUAL( psa_cipher_update( &operation,
2850 text, sizeof( text ),
2851 buffer, sizeof( buffer ),
2852 &length ),
2853 PSA_ERROR_BAD_STATE );
2854 PSA_ASSERT( psa_cipher_abort( &operation ) );
2855
2856 /* Call finish without calling setup beforehand. */
2857 TEST_EQUAL( psa_cipher_finish( &operation,
2858 buffer, sizeof( buffer ), &length ),
2859 PSA_ERROR_BAD_STATE );
2860 PSA_ASSERT( psa_cipher_abort( &operation ) );
2861
2862 /* Call finish without an IV where an IV is required. */
2863 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2864 /* Not calling update means we are encrypting an empty buffer, which is OK
2865 * for cipher modes with padding. */
2866 TEST_EQUAL( psa_cipher_finish( &operation,
2867 buffer, sizeof( buffer ), &length ),
2868 PSA_ERROR_BAD_STATE );
2869 PSA_ASSERT( psa_cipher_abort( &operation ) );
2870
2871 /* Call finish twice in a row. */
2872 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2873 PSA_ASSERT( psa_cipher_set_iv( &operation,
2874 iv, sizeof( iv ) ) );
2875 PSA_ASSERT( psa_cipher_finish( &operation,
2876 buffer, sizeof( buffer ), &length ) );
2877 TEST_EQUAL( psa_cipher_finish( &operation,
2878 buffer, sizeof( buffer ), &length ),
2879 PSA_ERROR_BAD_STATE );
2880 PSA_ASSERT( psa_cipher_abort( &operation ) );
2881
Gilles Peskine76b29a72019-05-28 14:08:50 +02002882 PSA_ASSERT( psa_destroy_key( handle ) );
2883
Jaeden Ameroab439972019-02-15 14:12:05 +00002884exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002885 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002886}
2887/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002888
Gilles Peskine50e586b2018-06-08 14:28:46 +02002889/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002890void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002891 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002892 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002893 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002894{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002895 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002896 psa_status_t status;
2897 psa_key_type_t key_type = key_type_arg;
2898 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002899 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002900 unsigned char *output = NULL;
2901 size_t output_buffer_size = 0;
2902 size_t function_output_length = 0;
2903 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002904 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002905 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002906
Gilles Peskine8817f612018-12-18 00:18:46 +01002907 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002908
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002909 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2910 psa_set_key_algorithm( &attributes, alg );
2911 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002912
Gilles Peskine73676cb2019-05-15 20:15:10 +02002913 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002914
Gilles Peskine8817f612018-12-18 00:18:46 +01002915 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2916 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002917
Gilles Peskine423005e2019-05-06 15:22:57 +02002918 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002919 output_buffer_size = ( (size_t) input->len +
2920 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002921 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002922
Gilles Peskine8817f612018-12-18 00:18:46 +01002923 PSA_ASSERT( psa_cipher_update( &operation,
2924 input->x, input->len,
2925 output, output_buffer_size,
2926 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002927 total_output_length += function_output_length;
2928 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002929 output + total_output_length,
2930 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002931 &function_output_length );
2932 total_output_length += function_output_length;
2933
Gilles Peskinefe11b722018-12-18 00:24:04 +01002934 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002935 if( expected_status == PSA_SUCCESS )
2936 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002937 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002938 ASSERT_COMPARE( expected_output->x, expected_output->len,
2939 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002940 }
2941
2942exit:
2943 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002944 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002945 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002946}
2947/* END_CASE */
2948
2949/* BEGIN_CASE */
2950void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002951 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002953 int first_part_size_arg,
2954 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002955 data_t *expected_output )
2956{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002957 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002958 psa_key_type_t key_type = key_type_arg;
2959 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002960 size_t first_part_size = first_part_size_arg;
2961 size_t output1_length = output1_length_arg;
2962 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002963 unsigned char *output = NULL;
2964 size_t output_buffer_size = 0;
2965 size_t function_output_length = 0;
2966 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002967 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002968 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002969
Gilles Peskine8817f612018-12-18 00:18:46 +01002970 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002971
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002972 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2973 psa_set_key_algorithm( &attributes, alg );
2974 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002975
Gilles Peskine73676cb2019-05-15 20:15:10 +02002976 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002977
Gilles Peskine8817f612018-12-18 00:18:46 +01002978 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2979 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002980
Gilles Peskine423005e2019-05-06 15:22:57 +02002981 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002982 output_buffer_size = ( (size_t) input->len +
2983 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002984 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002985
Gilles Peskinee0866522019-02-19 19:44:00 +01002986 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002987 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2988 output, output_buffer_size,
2989 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002990 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002991 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002992 PSA_ASSERT( psa_cipher_update( &operation,
2993 input->x + first_part_size,
2994 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002995 output + total_output_length,
2996 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002997 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002998 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002999 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003000 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003001 output + total_output_length,
3002 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003003 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003004 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003005 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003006
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003007 ASSERT_COMPARE( expected_output->x, expected_output->len,
3008 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003009
3010exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003011 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003012 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003013 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003014}
3015/* END_CASE */
3016
3017/* BEGIN_CASE */
3018void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003019 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003020 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003021 int first_part_size_arg,
3022 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003023 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003024{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003025 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003026
3027 psa_key_type_t key_type = key_type_arg;
3028 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003029 size_t first_part_size = first_part_size_arg;
3030 size_t output1_length = output1_length_arg;
3031 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003032 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003033 size_t output_buffer_size = 0;
3034 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003035 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003036 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003037 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003038
Gilles Peskine8817f612018-12-18 00:18:46 +01003039 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003040
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003041 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3042 psa_set_key_algorithm( &attributes, alg );
3043 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003044
Gilles Peskine73676cb2019-05-15 20:15:10 +02003045 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003046
Gilles Peskine8817f612018-12-18 00:18:46 +01003047 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3048 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003049
Gilles Peskine423005e2019-05-06 15:22:57 +02003050 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003051
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003052 output_buffer_size = ( (size_t) input->len +
3053 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003054 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003055
Gilles Peskinee0866522019-02-19 19:44:00 +01003056 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003057 PSA_ASSERT( psa_cipher_update( &operation,
3058 input->x, first_part_size,
3059 output, output_buffer_size,
3060 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003061 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003062 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003063 PSA_ASSERT( psa_cipher_update( &operation,
3064 input->x + first_part_size,
3065 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003066 output + total_output_length,
3067 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003068 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003069 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003070 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003071 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003072 output + total_output_length,
3073 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003074 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003075 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003076 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003077
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003078 ASSERT_COMPARE( expected_output->x, expected_output->len,
3079 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003080
3081exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003082 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003083 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003084 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003085}
3086/* END_CASE */
3087
Gilles Peskine50e586b2018-06-08 14:28:46 +02003088/* BEGIN_CASE */
3089void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003090 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003091 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003092 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003093{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003094 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003095 psa_status_t status;
3096 psa_key_type_t key_type = key_type_arg;
3097 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003098 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003099 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003100 size_t output_buffer_size = 0;
3101 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003102 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003103 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003104 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003105
Gilles Peskine8817f612018-12-18 00:18:46 +01003106 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003107
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003108 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3109 psa_set_key_algorithm( &attributes, alg );
3110 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003111
Gilles Peskine73676cb2019-05-15 20:15:10 +02003112 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003113
Gilles Peskine8817f612018-12-18 00:18:46 +01003114 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3115 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003116
Gilles Peskine423005e2019-05-06 15:22:57 +02003117 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003118
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003119 output_buffer_size = ( (size_t) input->len +
3120 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003121 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003122
Gilles Peskine8817f612018-12-18 00:18:46 +01003123 PSA_ASSERT( psa_cipher_update( &operation,
3124 input->x, input->len,
3125 output, output_buffer_size,
3126 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003127 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003128 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003129 output + total_output_length,
3130 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003131 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003132 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003133 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003134
3135 if( expected_status == PSA_SUCCESS )
3136 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003137 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003138 ASSERT_COMPARE( expected_output->x, expected_output->len,
3139 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003140 }
3141
Gilles Peskine50e586b2018-06-08 14:28:46 +02003142exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003143 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003144 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003145 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003146}
3147/* END_CASE */
3148
Gilles Peskine50e586b2018-06-08 14:28:46 +02003149/* BEGIN_CASE */
3150void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003151 data_t *key,
3152 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003153{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003154 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003155 psa_key_type_t key_type = key_type_arg;
3156 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003157 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003158 size_t iv_size = 16;
3159 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003160 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003161 size_t output1_size = 0;
3162 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003163 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003164 size_t output2_size = 0;
3165 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003166 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003167 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3168 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003169 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003170
Gilles Peskine8817f612018-12-18 00:18:46 +01003171 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003172
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003173 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3174 psa_set_key_algorithm( &attributes, alg );
3175 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003176
Gilles Peskine73676cb2019-05-15 20:15:10 +02003177 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003178
Gilles Peskine8817f612018-12-18 00:18:46 +01003179 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3180 handle, alg ) );
3181 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3182 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003183
Gilles Peskine8817f612018-12-18 00:18:46 +01003184 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3185 iv, iv_size,
3186 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003187 output1_size = ( (size_t) input->len +
3188 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003189 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003190
Gilles Peskine8817f612018-12-18 00:18:46 +01003191 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3192 output1, output1_size,
3193 &output1_length ) );
3194 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003195 output1 + output1_length,
3196 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003197 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003198
Gilles Peskine048b7f02018-06-08 14:20:49 +02003199 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003200
Gilles Peskine8817f612018-12-18 00:18:46 +01003201 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003202
3203 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003204 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003205
Gilles Peskine8817f612018-12-18 00:18:46 +01003206 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3207 iv, iv_length ) );
3208 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3209 output2, output2_size,
3210 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003211 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003212 PSA_ASSERT( psa_cipher_finish( &operation2,
3213 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003214 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003215 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003216
Gilles Peskine048b7f02018-06-08 14:20:49 +02003217 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003218
Gilles Peskine8817f612018-12-18 00:18:46 +01003219 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003220
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003221 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003222
3223exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003224 mbedtls_free( output1 );
3225 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003226 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003227 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003228}
3229/* END_CASE */
3230
3231/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003232void cipher_verify_output_multipart( int alg_arg,
3233 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003234 data_t *key,
3235 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003236 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003237{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003238 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003239 psa_key_type_t key_type = key_type_arg;
3240 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003241 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003242 unsigned char iv[16] = {0};
3243 size_t iv_size = 16;
3244 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003245 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003246 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003247 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003248 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003249 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003250 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003251 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003252 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3253 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003254 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003255
Gilles Peskine8817f612018-12-18 00:18:46 +01003256 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003257
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003258 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3259 psa_set_key_algorithm( &attributes, alg );
3260 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003261
Gilles Peskine73676cb2019-05-15 20:15:10 +02003262 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003263
Gilles Peskine8817f612018-12-18 00:18:46 +01003264 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3265 handle, alg ) );
3266 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3267 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003268
Gilles Peskine8817f612018-12-18 00:18:46 +01003269 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3270 iv, iv_size,
3271 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003272 output1_buffer_size = ( (size_t) input->len +
3273 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003274 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003275
Gilles Peskinee0866522019-02-19 19:44:00 +01003276 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003277
Gilles Peskine8817f612018-12-18 00:18:46 +01003278 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3279 output1, output1_buffer_size,
3280 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003281 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003282
Gilles Peskine8817f612018-12-18 00:18:46 +01003283 PSA_ASSERT( psa_cipher_update( &operation1,
3284 input->x + first_part_size,
3285 input->len - first_part_size,
3286 output1, output1_buffer_size,
3287 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003288 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003289
Gilles Peskine8817f612018-12-18 00:18:46 +01003290 PSA_ASSERT( psa_cipher_finish( &operation1,
3291 output1 + output1_length,
3292 output1_buffer_size - output1_length,
3293 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003294 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003295
Gilles Peskine8817f612018-12-18 00:18:46 +01003296 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003297
Gilles Peskine048b7f02018-06-08 14:20:49 +02003298 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003299 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003300
Gilles Peskine8817f612018-12-18 00:18:46 +01003301 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3302 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003303
Gilles Peskine8817f612018-12-18 00:18:46 +01003304 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3305 output2, output2_buffer_size,
3306 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003307 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003308
Gilles Peskine8817f612018-12-18 00:18:46 +01003309 PSA_ASSERT( psa_cipher_update( &operation2,
3310 output1 + first_part_size,
3311 output1_length - first_part_size,
3312 output2, output2_buffer_size,
3313 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003314 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003315
Gilles Peskine8817f612018-12-18 00:18:46 +01003316 PSA_ASSERT( psa_cipher_finish( &operation2,
3317 output2 + output2_length,
3318 output2_buffer_size - output2_length,
3319 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003320 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003321
Gilles Peskine8817f612018-12-18 00:18:46 +01003322 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003323
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003324 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003325
3326exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003327 mbedtls_free( output1 );
3328 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003329 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003330 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003331}
3332/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003333
Gilles Peskine20035e32018-02-03 22:44:14 +01003334/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003335void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003336 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003337 data_t *nonce,
3338 data_t *additional_data,
3339 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003340 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003341{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003342 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003343 psa_key_type_t key_type = key_type_arg;
3344 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003345 unsigned char *output_data = NULL;
3346 size_t output_size = 0;
3347 size_t output_length = 0;
3348 unsigned char *output_data2 = NULL;
3349 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003350 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003351 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003352 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003353
Gilles Peskine4abf7412018-06-18 16:35:34 +02003354 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003355 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3356 * should be exact. */
3357 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3358 TEST_EQUAL( output_size,
3359 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003360 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003361
Gilles Peskine8817f612018-12-18 00:18:46 +01003362 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003363
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003364 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3365 psa_set_key_algorithm( &attributes, alg );
3366 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003367
Gilles Peskine049c7532019-05-15 20:22:09 +02003368 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3369 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003370
Gilles Peskinefe11b722018-12-18 00:24:04 +01003371 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3372 nonce->x, nonce->len,
3373 additional_data->x,
3374 additional_data->len,
3375 input_data->x, input_data->len,
3376 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003377 &output_length ),
3378 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003379
3380 if( PSA_SUCCESS == expected_result )
3381 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003382 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003383
Gilles Peskine003a4a92019-05-14 16:09:40 +02003384 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3385 * should be exact. */
3386 TEST_EQUAL( input_data->len,
3387 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3388
Gilles Peskinefe11b722018-12-18 00:24:04 +01003389 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3390 nonce->x, nonce->len,
3391 additional_data->x,
3392 additional_data->len,
3393 output_data, output_length,
3394 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003395 &output_length2 ),
3396 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003397
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003398 ASSERT_COMPARE( input_data->x, input_data->len,
3399 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003401
Gilles Peskinea1cac842018-06-11 19:33:02 +02003402exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003403 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003404 mbedtls_free( output_data );
3405 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003406 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003407}
3408/* END_CASE */
3409
3410/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003411void aead_encrypt( int key_type_arg, data_t *key_data,
3412 int alg_arg,
3413 data_t *nonce,
3414 data_t *additional_data,
3415 data_t *input_data,
3416 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003417{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003418 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003419 psa_key_type_t key_type = key_type_arg;
3420 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421 unsigned char *output_data = NULL;
3422 size_t output_size = 0;
3423 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003424 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003425 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003426
Gilles Peskine4abf7412018-06-18 16:35:34 +02003427 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003428 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3429 * should be exact. */
3430 TEST_EQUAL( output_size,
3431 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003432 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003433
Gilles Peskine8817f612018-12-18 00:18:46 +01003434 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003436 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3437 psa_set_key_algorithm( &attributes, alg );
3438 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003439
Gilles Peskine049c7532019-05-15 20:22:09 +02003440 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3441 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003442
Gilles Peskine8817f612018-12-18 00:18:46 +01003443 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3444 nonce->x, nonce->len,
3445 additional_data->x, additional_data->len,
3446 input_data->x, input_data->len,
3447 output_data, output_size,
3448 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003449
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003450 ASSERT_COMPARE( expected_result->x, expected_result->len,
3451 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003452
Gilles Peskinea1cac842018-06-11 19:33:02 +02003453exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003454 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003455 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003456 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003457}
3458/* END_CASE */
3459
3460/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003461void aead_decrypt( int key_type_arg, data_t *key_data,
3462 int alg_arg,
3463 data_t *nonce,
3464 data_t *additional_data,
3465 data_t *input_data,
3466 data_t *expected_data,
3467 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003468{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003469 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003470 psa_key_type_t key_type = key_type_arg;
3471 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003472 unsigned char *output_data = NULL;
3473 size_t output_size = 0;
3474 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003475 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003476 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003477 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003478
Gilles Peskine003a4a92019-05-14 16:09:40 +02003479 output_size = input_data->len - tag_length;
3480 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3481 * should be exact. */
3482 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3483 TEST_EQUAL( output_size,
3484 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003485 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003486
Gilles Peskine8817f612018-12-18 00:18:46 +01003487 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003489 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3490 psa_set_key_algorithm( &attributes, alg );
3491 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003492
Gilles Peskine049c7532019-05-15 20:22:09 +02003493 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3494 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003495
Gilles Peskinefe11b722018-12-18 00:24:04 +01003496 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3497 nonce->x, nonce->len,
3498 additional_data->x,
3499 additional_data->len,
3500 input_data->x, input_data->len,
3501 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003502 &output_length ),
3503 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003504
Gilles Peskine2d277862018-06-18 15:41:12 +02003505 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003506 ASSERT_COMPARE( expected_data->x, expected_data->len,
3507 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003508
Gilles Peskinea1cac842018-06-11 19:33:02 +02003509exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003510 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003511 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003512 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003513}
3514/* END_CASE */
3515
3516/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003517void signature_size( int type_arg,
3518 int bits,
3519 int alg_arg,
3520 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003521{
3522 psa_key_type_t type = type_arg;
3523 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003524 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003525 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003526exit:
3527 ;
3528}
3529/* END_CASE */
3530
3531/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003532void sign_deterministic( int key_type_arg, data_t *key_data,
3533 int alg_arg, data_t *input_data,
3534 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003535{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003536 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003537 psa_key_type_t key_type = key_type_arg;
3538 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003539 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003540 unsigned char *signature = NULL;
3541 size_t signature_size;
3542 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003543 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003544
Gilles Peskine8817f612018-12-18 00:18:46 +01003545 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003546
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003547 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3548 psa_set_key_algorithm( &attributes, alg );
3549 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003550
Gilles Peskine049c7532019-05-15 20:22:09 +02003551 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3552 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003553 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3554 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003555
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003556 /* Allocate a buffer which has the size advertized by the
3557 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003558 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3559 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003560 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003561 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003562 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003563
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003564 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003565 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3566 input_data->x, input_data->len,
3567 signature, signature_size,
3568 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003569 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003570 ASSERT_COMPARE( output_data->x, output_data->len,
3571 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003572
3573exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003574 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003575 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003576 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003577 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003578}
3579/* END_CASE */
3580
3581/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003582void sign_fail( int key_type_arg, data_t *key_data,
3583 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003584 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003585{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003586 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003587 psa_key_type_t key_type = key_type_arg;
3588 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003589 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003590 psa_status_t actual_status;
3591 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003592 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003593 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003594 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003595
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003596 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003597
Gilles Peskine8817f612018-12-18 00:18:46 +01003598 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003599
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003600 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3601 psa_set_key_algorithm( &attributes, alg );
3602 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003603
Gilles Peskine049c7532019-05-15 20:22:09 +02003604 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3605 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003606
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003607 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003608 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003609 signature, signature_size,
3610 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003611 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003612 /* The value of *signature_length is unspecified on error, but
3613 * whatever it is, it should be less than signature_size, so that
3614 * if the caller tries to read *signature_length bytes without
3615 * checking the error code then they don't overflow a buffer. */
3616 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003617
3618exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003619 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003620 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003621 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003622 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003623}
3624/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003625
3626/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003627void sign_verify( int key_type_arg, data_t *key_data,
3628 int alg_arg, data_t *input_data )
3629{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003630 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003631 psa_key_type_t key_type = key_type_arg;
3632 psa_algorithm_t alg = alg_arg;
3633 size_t key_bits;
3634 unsigned char *signature = NULL;
3635 size_t signature_size;
3636 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003637 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003638
Gilles Peskine8817f612018-12-18 00:18:46 +01003639 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003640
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003641 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3642 psa_set_key_algorithm( &attributes, alg );
3643 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003644
Gilles Peskine049c7532019-05-15 20:22:09 +02003645 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3646 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003647 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3648 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003649
3650 /* Allocate a buffer which has the size advertized by the
3651 * library. */
3652 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3653 key_bits, alg );
3654 TEST_ASSERT( signature_size != 0 );
3655 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003656 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003657
3658 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003659 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3660 input_data->x, input_data->len,
3661 signature, signature_size,
3662 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003663 /* Check that the signature length looks sensible. */
3664 TEST_ASSERT( signature_length <= signature_size );
3665 TEST_ASSERT( signature_length > 0 );
3666
3667 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003668 PSA_ASSERT( psa_asymmetric_verify(
3669 handle, alg,
3670 input_data->x, input_data->len,
3671 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003672
3673 if( input_data->len != 0 )
3674 {
3675 /* Flip a bit in the input and verify that the signature is now
3676 * detected as invalid. Flip a bit at the beginning, not at the end,
3677 * because ECDSA may ignore the last few bits of the input. */
3678 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003679 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3680 input_data->x, input_data->len,
3681 signature, signature_length ),
3682 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003683 }
3684
3685exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003686 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003687 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003688 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003689 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003690}
3691/* END_CASE */
3692
3693/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003694void asymmetric_verify( int key_type_arg, data_t *key_data,
3695 int alg_arg, data_t *hash_data,
3696 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003697{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003698 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003699 psa_key_type_t key_type = key_type_arg;
3700 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003701 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003702
Gilles Peskine69c12672018-06-28 00:07:19 +02003703 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3704
Gilles Peskine8817f612018-12-18 00:18:46 +01003705 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003706
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003707 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3708 psa_set_key_algorithm( &attributes, alg );
3709 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003710
Gilles Peskine049c7532019-05-15 20:22:09 +02003711 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3712 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003713
Gilles Peskine8817f612018-12-18 00:18:46 +01003714 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3715 hash_data->x, hash_data->len,
3716 signature_data->x,
3717 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003718exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003719 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003720 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003721 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003722}
3723/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003724
3725/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003726void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3727 int alg_arg, data_t *hash_data,
3728 data_t *signature_data,
3729 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003730{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003731 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003732 psa_key_type_t key_type = key_type_arg;
3733 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003734 psa_status_t actual_status;
3735 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003736 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003737
Gilles Peskine8817f612018-12-18 00:18:46 +01003738 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003739
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003740 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3741 psa_set_key_algorithm( &attributes, alg );
3742 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003743
Gilles Peskine049c7532019-05-15 20:22:09 +02003744 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3745 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003746
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003747 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003748 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003749 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003750 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003751
Gilles Peskinefe11b722018-12-18 00:24:04 +01003752 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003753
3754exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003755 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003756 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003757 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003758}
3759/* END_CASE */
3760
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003761/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003762void asymmetric_encrypt( int key_type_arg,
3763 data_t *key_data,
3764 int alg_arg,
3765 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003766 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003767 int expected_output_length_arg,
3768 int expected_status_arg )
3769{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003770 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003771 psa_key_type_t key_type = key_type_arg;
3772 psa_algorithm_t alg = alg_arg;
3773 size_t expected_output_length = expected_output_length_arg;
3774 size_t key_bits;
3775 unsigned char *output = NULL;
3776 size_t output_size;
3777 size_t output_length = ~0;
3778 psa_status_t actual_status;
3779 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003780 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003781
Gilles Peskine8817f612018-12-18 00:18:46 +01003782 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003783
Gilles Peskine656896e2018-06-29 19:12:28 +02003784 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003785 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3786 psa_set_key_algorithm( &attributes, alg );
3787 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003788 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3789 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003790
3791 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003792 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3793 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003794 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003795 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003796
3797 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003798 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003799 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003800 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003801 output, output_size,
3802 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003803 TEST_EQUAL( actual_status, expected_status );
3804 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003805
Gilles Peskine68428122018-06-30 18:42:41 +02003806 /* If the label is empty, the test framework puts a non-null pointer
3807 * in label->x. Test that a null pointer works as well. */
3808 if( label->len == 0 )
3809 {
3810 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003811 if( output_size != 0 )
3812 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003813 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003814 input_data->x, input_data->len,
3815 NULL, label->len,
3816 output, output_size,
3817 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003818 TEST_EQUAL( actual_status, expected_status );
3819 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003820 }
3821
Gilles Peskine656896e2018-06-29 19:12:28 +02003822exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003823 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003824 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003825 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003826 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02003827}
3828/* END_CASE */
3829
3830/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003831void asymmetric_encrypt_decrypt( int key_type_arg,
3832 data_t *key_data,
3833 int alg_arg,
3834 data_t *input_data,
3835 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003836{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003837 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003838 psa_key_type_t key_type = key_type_arg;
3839 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003840 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003841 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003842 size_t output_size;
3843 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003844 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003845 size_t output2_size;
3846 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003847 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003848
Gilles Peskine8817f612018-12-18 00:18:46 +01003849 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003850
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003851 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3852 psa_set_key_algorithm( &attributes, alg );
3853 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003854
Gilles Peskine049c7532019-05-15 20:22:09 +02003855 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3856 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003857
3858 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003859 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3860 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003861 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003862 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003863 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003864 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003865
Gilles Peskineeebd7382018-06-08 18:11:54 +02003866 /* We test encryption by checking that encrypt-then-decrypt gives back
3867 * the original plaintext because of the non-optional random
3868 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003869 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3870 input_data->x, input_data->len,
3871 label->x, label->len,
3872 output, output_size,
3873 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003874 /* We don't know what ciphertext length to expect, but check that
3875 * it looks sensible. */
3876 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003877
Gilles Peskine8817f612018-12-18 00:18:46 +01003878 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3879 output, output_length,
3880 label->x, label->len,
3881 output2, output2_size,
3882 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003883 ASSERT_COMPARE( input_data->x, input_data->len,
3884 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003885
3886exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003887 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003888 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003889 mbedtls_free( output );
3890 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003891 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003892}
3893/* END_CASE */
3894
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003895/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003896void asymmetric_decrypt( int key_type_arg,
3897 data_t *key_data,
3898 int alg_arg,
3899 data_t *input_data,
3900 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003901 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003902{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003903 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003904 psa_key_type_t key_type = key_type_arg;
3905 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003906 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003907 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003908 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003909 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003910
Jaeden Amero412654a2019-02-06 12:57:46 +00003911 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003912 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003913
Gilles Peskine8817f612018-12-18 00:18:46 +01003914 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003915
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003916 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3917 psa_set_key_algorithm( &attributes, alg );
3918 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003919
Gilles Peskine049c7532019-05-15 20:22:09 +02003920 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3921 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003922
Gilles Peskine8817f612018-12-18 00:18:46 +01003923 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3924 input_data->x, input_data->len,
3925 label->x, label->len,
3926 output,
3927 output_size,
3928 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003929 ASSERT_COMPARE( expected_data->x, expected_data->len,
3930 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003931
Gilles Peskine68428122018-06-30 18:42:41 +02003932 /* If the label is empty, the test framework puts a non-null pointer
3933 * in label->x. Test that a null pointer works as well. */
3934 if( label->len == 0 )
3935 {
3936 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003937 if( output_size != 0 )
3938 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003939 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3940 input_data->x, input_data->len,
3941 NULL, 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 );
Gilles Peskine68428122018-06-30 18:42:41 +02003947 }
3948
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003949exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003950 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003951 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003952 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003953 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003954}
3955/* END_CASE */
3956
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003957/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003958void asymmetric_decrypt_fail( int key_type_arg,
3959 data_t *key_data,
3960 int alg_arg,
3961 data_t *input_data,
3962 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003963 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003964 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003965{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003966 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003967 psa_key_type_t key_type = key_type_arg;
3968 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003969 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003970 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003971 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003972 psa_status_t actual_status;
3973 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003974 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003975
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003976 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003977
Gilles Peskine8817f612018-12-18 00:18:46 +01003978 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003979
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003980 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3981 psa_set_key_algorithm( &attributes, alg );
3982 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003983
Gilles Peskine049c7532019-05-15 20:22:09 +02003984 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3985 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003986
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003987 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003988 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003989 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003990 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003991 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003992 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003993 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003994
Gilles Peskine68428122018-06-30 18:42:41 +02003995 /* If the label is empty, the test framework puts a non-null pointer
3996 * in label->x. Test that a null pointer works as well. */
3997 if( label->len == 0 )
3998 {
3999 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004000 if( output_size != 0 )
4001 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004002 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004003 input_data->x, input_data->len,
4004 NULL, label->len,
4005 output, output_size,
4006 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004007 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004008 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004009 }
4010
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004011exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004012 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004013 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004014 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004015 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004016}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004017/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004018
4019/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004020void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004021{
4022 /* Test each valid way of initializing the object, except for `= {0}`, as
4023 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4024 * though it's OK by the C standard. We could test for this, but we'd need
4025 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004026 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004027 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4028 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4029 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004030
4031 memset( &zero, 0, sizeof( zero ) );
4032
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004033 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004034 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004035 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004036 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004037 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004038 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004039 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004040
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004041 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004042 PSA_ASSERT( psa_key_derivation_abort(&func) );
4043 PSA_ASSERT( psa_key_derivation_abort(&init) );
4044 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004045}
4046/* END_CASE */
4047
Janos Follath16de4a42019-06-13 16:32:24 +01004048/* BEGIN_CASE */
4049void derive_setup( int alg_arg, int expected_status_arg )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004050{
Gilles Peskineea0fb492018-07-12 17:17:20 +02004051 psa_algorithm_t alg = alg_arg;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004052 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004053 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004054
Gilles Peskine8817f612018-12-18 00:18:46 +01004055 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004056
Janos Follath16de4a42019-06-13 16:32:24 +01004057 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004058 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004059
4060exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004061 psa_key_derivation_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004062 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004063}
4064/* END_CASE */
4065
Janos Follathaf3c2a02019-06-12 12:34:34 +01004066/* BEGIN_CASE */
Janos Follatha27c9272019-06-14 09:59:36 +01004067void derive_set_capacity( int alg_arg, int capacity_arg,
4068 int expected_status_arg )
4069{
4070 psa_algorithm_t alg = alg_arg;
4071 size_t capacity = capacity_arg;
4072 psa_status_t expected_status = expected_status_arg;
4073 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4074
4075 PSA_ASSERT( psa_crypto_init( ) );
4076
4077 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4078
4079 TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
4080 expected_status );
4081
4082exit:
4083 psa_key_derivation_abort( &operation );
4084 PSA_DONE( );
4085}
4086/* END_CASE */
4087
4088/* BEGIN_CASE */
Janos Follathaf3c2a02019-06-12 12:34:34 +01004089void derive_input( int alg_arg,
4090 int key_type_arg,
4091 int step1_arg, data_t *input1,
4092 int step2_arg, data_t *input2,
4093 int step3_arg, data_t *input3,
4094 int expected_status_arg1,
4095 int expected_status_arg2,
4096 int expected_status_arg3 )
4097{
4098 psa_algorithm_t alg = alg_arg;
4099 size_t key_type = key_type_arg;
4100 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4101 psa_status_t expected_statuses[] = {expected_status_arg1,
4102 expected_status_arg2,
4103 expected_status_arg3};
4104 data_t *inputs[] = {input1, input2, input3};
4105 psa_key_handle_t handles[] = {0, 0, 0};
4106 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4107 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4108 size_t i;
4109
4110 PSA_ASSERT( psa_crypto_init( ) );
4111
4112 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4113 psa_set_key_algorithm( &attributes, alg );
4114 psa_set_key_type( &attributes, key_type );
4115
4116 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4117
4118 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
4119 {
4120 switch( steps[i] )
4121 {
4122 case PSA_KEY_DERIVATION_INPUT_SECRET:
4123 PSA_ASSERT( psa_import_key( &attributes,
4124 inputs[i]->x, inputs[i]->len,
4125 &handles[i] ) );
4126 TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
4127 handles[i] ),
4128 expected_statuses[i] );
4129 break;
4130 default:
4131 TEST_EQUAL( psa_key_derivation_input_bytes(
4132 &operation, steps[i],
4133 inputs[i]->x, inputs[i]->len ),
4134 expected_statuses[i] );
4135 break;
4136 }
4137 }
4138
4139exit:
4140 psa_key_derivation_abort( &operation );
4141 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4142 psa_destroy_key( handles[i] );
4143 PSA_DONE( );
4144}
4145/* END_CASE */
4146
Janos Follath71a4c912019-06-11 09:14:47 +01004147/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004148void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004149{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004150 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004151 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004152 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004153 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004154 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004155 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004156 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4157 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4158 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004159 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004160
Gilles Peskine8817f612018-12-18 00:18:46 +01004161 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004162
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004163 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4164 psa_set_key_algorithm( &attributes, alg );
4165 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004166
Gilles Peskine73676cb2019-05-15 20:15:10 +02004167 PSA_ASSERT( psa_import_key( &attributes,
4168 key_data, sizeof( key_data ),
4169 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004170
4171 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004172 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004173 NULL, 0,
4174 NULL, 0,
4175 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004176
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004177 /* state of operation shouldn't allow additional generation */
4178 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004179 NULL, 0,
4180 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004181 capacity ),
4182 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004183
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004184 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004185
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004186 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004187 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004188
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004189exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004190 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004191 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004192 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004193}
4194/* END_CASE */
4195
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004196/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004197void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004198{
4199 uint8_t output_buffer[16];
4200 size_t buffer_size = 16;
4201 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004202 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004203
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004204 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4205 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004206 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004207
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004208 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004209 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004210
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004211 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004212
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004213 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4214 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004215 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004216
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004217 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004218 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004219
4220exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004221 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004222}
4223/* END_CASE */
4224
4225/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004226void derive_output( int alg_arg,
Gilles Peskine1468da72019-05-29 17:35:49 +02004227 int step1_arg, data_t *input1,
4228 int step2_arg, data_t *input2,
4229 int step3_arg, data_t *input3,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004230 int requested_capacity_arg,
4231 data_t *expected_output1,
4232 data_t *expected_output2 )
4233{
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004234 psa_algorithm_t alg = alg_arg;
Gilles Peskine1468da72019-05-29 17:35:49 +02004235 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4236 data_t *inputs[] = {input1, input2, input3};
4237 psa_key_handle_t handles[] = {0, 0, 0};
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004238 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004239 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004240 uint8_t *expected_outputs[2] =
4241 {expected_output1->x, expected_output2->x};
4242 size_t output_sizes[2] =
4243 {expected_output1->len, expected_output2->len};
4244 size_t output_buffer_size = 0;
4245 uint8_t *output_buffer = NULL;
4246 size_t expected_capacity;
4247 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004248 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004249 psa_status_t status;
Gilles Peskine1468da72019-05-29 17:35:49 +02004250 size_t i;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004251
4252 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4253 {
4254 if( output_sizes[i] > output_buffer_size )
4255 output_buffer_size = output_sizes[i];
4256 if( output_sizes[i] == 0 )
4257 expected_outputs[i] = NULL;
4258 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004259 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004260 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004261
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004262 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4263 psa_set_key_algorithm( &attributes, alg );
4264 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004265
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004266 /* Extraction phase. */
Gilles Peskine1468da72019-05-29 17:35:49 +02004267 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4268 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4269 requested_capacity ) );
4270 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004271 {
Gilles Peskine1468da72019-05-29 17:35:49 +02004272 switch( steps[i] )
4273 {
4274 case 0:
4275 break;
4276 case PSA_KEY_DERIVATION_INPUT_SECRET:
4277 PSA_ASSERT( psa_import_key( &attributes,
4278 inputs[i]->x, inputs[i]->len,
4279 &handles[i] ) );
4280 PSA_ASSERT( psa_key_derivation_input_key(
4281 &operation, steps[i],
4282 handles[i] ) );
4283 break;
4284 default:
4285 PSA_ASSERT( psa_key_derivation_input_bytes(
4286 &operation, steps[i],
4287 inputs[i]->x, inputs[i]->len ) );
4288 break;
4289 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004290 }
Gilles Peskine1468da72019-05-29 17:35:49 +02004291
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004292 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004293 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004294 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004295 expected_capacity = requested_capacity;
4296
4297 /* Expansion phase. */
4298 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4299 {
4300 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004301 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004302 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004303 if( expected_capacity == 0 && output_sizes[i] == 0 )
4304 {
4305 /* Reading 0 bytes when 0 bytes are available can go either way. */
4306 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004307 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004308 continue;
4309 }
4310 else if( expected_capacity == 0 ||
4311 output_sizes[i] > expected_capacity )
4312 {
4313 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004314 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004315 expected_capacity = 0;
4316 continue;
4317 }
4318 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004319 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004320 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004321 ASSERT_COMPARE( output_buffer, output_sizes[i],
4322 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004323 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004324 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004325 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004326 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004327 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004328 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004329 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004330
4331exit:
4332 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004333 psa_key_derivation_abort( &operation );
Gilles Peskine1468da72019-05-29 17:35:49 +02004334 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4335 psa_destroy_key( handles[i] );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004336 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004337}
4338/* END_CASE */
4339
4340/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004341void derive_full( int alg_arg,
4342 data_t *key_data,
Janos Follath47f27ed2019-06-25 13:24:52 +01004343 data_t *input1,
4344 data_t *input2,
Gilles Peskined54931c2018-07-17 21:06:59 +02004345 int requested_capacity_arg )
4346{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004347 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004348 psa_algorithm_t alg = alg_arg;
4349 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004350 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004351 unsigned char output_buffer[16];
4352 size_t expected_capacity = requested_capacity;
4353 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004354 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004355
Gilles Peskine8817f612018-12-18 00:18:46 +01004356 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004357
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004358 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4359 psa_set_key_algorithm( &attributes, alg );
4360 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004361
Gilles Peskine049c7532019-05-15 20:22:09 +02004362 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4363 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004364
Janos Follath47f27ed2019-06-25 13:24:52 +01004365 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4366 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4367 requested_capacity ) );
4368
Gilles Peskined54931c2018-07-17 21:06:59 +02004369 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004370 if( PSA_ALG_IS_HKDF( alg ) )
4371 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004372 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004373 PSA_KEY_DERIVATION_INPUT_SALT,
Janos Follath47f27ed2019-06-25 13:24:52 +01004374 input1->x, input1->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004375 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004376 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004377 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004378 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004379 PSA_KEY_DERIVATION_INPUT_INFO,
Janos Follath47f27ed2019-06-25 13:24:52 +01004380 input2->x, input2->len ) );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004381 }
Janos Follath47f27ed2019-06-25 13:24:52 +01004382 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
4383 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
4384 {
4385 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
4386 PSA_KEY_DERIVATION_INPUT_SEED,
4387 input1->x, input1->len ) );
4388 PSA_ASSERT( psa_key_derivation_input_key( &operation,
4389 PSA_KEY_DERIVATION_INPUT_SECRET,
4390 handle ) );
4391 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
4392 PSA_KEY_DERIVATION_INPUT_LABEL,
4393 input2->x, input2->len ) );
4394 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004395 else
4396 {
Janos Follath47f27ed2019-06-25 13:24:52 +01004397 TEST_ASSERT( ! "Key derivation algorithm not supported" );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004398 }
Janos Follath47f27ed2019-06-25 13:24:52 +01004399
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004400 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004401 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004402 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004403
4404 /* Expansion phase. */
4405 while( current_capacity > 0 )
4406 {
4407 size_t read_size = sizeof( output_buffer );
4408 if( read_size > current_capacity )
4409 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004410 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004411 output_buffer,
4412 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004413 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004414 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004415 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004416 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004417 }
4418
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004419 /* Check that the operation refuses to go over capacity. */
4420 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004421 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004422
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004423 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004424
4425exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004426 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004427 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004428 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004429}
4430/* END_CASE */
4431
Janos Follath71a4c912019-06-11 09:14:47 +01004432/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004433void derive_key_exercise( int alg_arg,
4434 data_t *key_data,
4435 data_t *salt,
4436 data_t *label,
4437 int derived_type_arg,
4438 int derived_bits_arg,
4439 int derived_usage_arg,
4440 int derived_alg_arg )
4441{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004442 psa_key_handle_t base_handle = 0;
4443 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004444 psa_algorithm_t alg = alg_arg;
4445 psa_key_type_t derived_type = derived_type_arg;
4446 size_t derived_bits = derived_bits_arg;
4447 psa_key_usage_t derived_usage = derived_usage_arg;
4448 psa_algorithm_t derived_alg = derived_alg_arg;
4449 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004450 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004451 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004452 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004453
Gilles Peskine8817f612018-12-18 00:18:46 +01004454 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004455
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004456 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4457 psa_set_key_algorithm( &attributes, alg );
4458 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004459 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4460 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004461
4462 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004463 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004464 salt->x, salt->len,
4465 label->x, label->len,
4466 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004467 psa_set_key_usage_flags( &attributes, derived_usage );
4468 psa_set_key_algorithm( &attributes, derived_alg );
4469 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004470 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004471 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004472 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004473
4474 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004475 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4476 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4477 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004478
4479 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004480 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004481 goto exit;
4482
4483exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004484 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004485 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004486 psa_destroy_key( base_handle );
4487 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004488 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004489}
4490/* END_CASE */
4491
Janos Follath71a4c912019-06-11 09:14:47 +01004492/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004493void derive_key_export( int alg_arg,
4494 data_t *key_data,
4495 data_t *salt,
4496 data_t *label,
4497 int bytes1_arg,
4498 int bytes2_arg )
4499{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004500 psa_key_handle_t base_handle = 0;
4501 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004502 psa_algorithm_t alg = alg_arg;
4503 size_t bytes1 = bytes1_arg;
4504 size_t bytes2 = bytes2_arg;
4505 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004506 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004507 uint8_t *output_buffer = NULL;
4508 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004509 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4510 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004511 size_t length;
4512
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004513 ASSERT_ALLOC( output_buffer, capacity );
4514 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004515 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004516
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004517 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4518 psa_set_key_algorithm( &base_attributes, alg );
4519 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004520 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4521 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004522
4523 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004524 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004525 salt->x, salt->len,
4526 label->x, label->len,
4527 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004528 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004529 output_buffer,
4530 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004531 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004532
4533 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004534 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004535 salt->x, salt->len,
4536 label->x, label->len,
4537 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004538 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4539 psa_set_key_algorithm( &derived_attributes, 0 );
4540 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004541 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004542 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004543 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004544 PSA_ASSERT( psa_export_key( derived_handle,
4545 export_buffer, bytes1,
4546 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004547 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004548 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004549 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004550 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004551 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004552 PSA_ASSERT( psa_export_key( derived_handle,
4553 export_buffer + bytes1, bytes2,
4554 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004555 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004556
4557 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004558 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4559 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004560
4561exit:
4562 mbedtls_free( output_buffer );
4563 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004564 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004565 psa_destroy_key( base_handle );
4566 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004567 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004568}
4569/* END_CASE */
4570
4571/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004572void key_agreement_setup( int alg_arg,
4573 int our_key_type_arg, data_t *our_key_data,
4574 data_t *peer_key_data,
4575 int expected_status_arg )
4576{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004577 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004578 psa_algorithm_t alg = alg_arg;
4579 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004580 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004581 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004582 psa_status_t expected_status = expected_status_arg;
4583 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004584
Gilles Peskine8817f612018-12-18 00:18:46 +01004585 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004586
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004587 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4588 psa_set_key_algorithm( &attributes, alg );
4589 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004590 PSA_ASSERT( psa_import_key( &attributes,
4591 our_key_data->x, our_key_data->len,
4592 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004593
Gilles Peskine77f40d82019-04-11 21:27:06 +02004594 /* The tests currently include inputs that should fail at either step.
4595 * Test cases that fail at the setup step should be changed to call
4596 * key_derivation_setup instead, and this function should be renamed
4597 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004598 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004599 if( status == PSA_SUCCESS )
4600 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004601 TEST_EQUAL( psa_key_derivation_key_agreement(
4602 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4603 our_key,
4604 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004605 expected_status );
4606 }
4607 else
4608 {
4609 TEST_ASSERT( status == expected_status );
4610 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004611
4612exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004613 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004614 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004615 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004616}
4617/* END_CASE */
4618
4619/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004620void raw_key_agreement( int alg_arg,
4621 int our_key_type_arg, data_t *our_key_data,
4622 data_t *peer_key_data,
4623 data_t *expected_output )
4624{
4625 psa_key_handle_t our_key = 0;
4626 psa_algorithm_t alg = alg_arg;
4627 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004628 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004629 unsigned char *output = NULL;
4630 size_t output_length = ~0;
4631
4632 ASSERT_ALLOC( output, expected_output->len );
4633 PSA_ASSERT( psa_crypto_init( ) );
4634
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004635 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4636 psa_set_key_algorithm( &attributes, alg );
4637 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004638 PSA_ASSERT( psa_import_key( &attributes,
4639 our_key_data->x, our_key_data->len,
4640 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004641
Gilles Peskinebe697d82019-05-16 18:00:41 +02004642 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4643 peer_key_data->x, peer_key_data->len,
4644 output, expected_output->len,
4645 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004646 ASSERT_COMPARE( output, output_length,
4647 expected_output->x, expected_output->len );
4648
4649exit:
4650 mbedtls_free( output );
4651 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004652 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004653}
4654/* END_CASE */
4655
4656/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004657void key_agreement_capacity( int alg_arg,
4658 int our_key_type_arg, data_t *our_key_data,
4659 data_t *peer_key_data,
4660 int expected_capacity_arg )
4661{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004662 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004663 psa_algorithm_t alg = alg_arg;
4664 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004665 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004666 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004667 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004668 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004669
Gilles Peskine8817f612018-12-18 00:18:46 +01004670 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004671
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004672 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4673 psa_set_key_algorithm( &attributes, alg );
4674 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004675 PSA_ASSERT( psa_import_key( &attributes,
4676 our_key_data->x, our_key_data->len,
4677 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004678
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004679 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004680 PSA_ASSERT( psa_key_derivation_key_agreement(
4681 &operation,
4682 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4683 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004684 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4685 {
4686 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004687 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004688 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004689 NULL, 0 ) );
4690 }
Gilles Peskine59685592018-09-18 12:11:34 +02004691
Gilles Peskinebf491972018-10-25 22:36:12 +02004692 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004693 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004694 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004695 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004696
Gilles Peskinebf491972018-10-25 22:36:12 +02004697 /* Test the actual capacity by reading the output. */
4698 while( actual_capacity > sizeof( output ) )
4699 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004700 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004701 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004702 actual_capacity -= sizeof( output );
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 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004706 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004707 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004708
Gilles Peskine59685592018-09-18 12:11:34 +02004709exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004710 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004711 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004712 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004713}
4714/* END_CASE */
4715
4716/* BEGIN_CASE */
4717void key_agreement_output( int alg_arg,
4718 int our_key_type_arg, data_t *our_key_data,
4719 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004720 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004721{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004722 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004723 psa_algorithm_t alg = alg_arg;
4724 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004725 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004726 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004727 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004728
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004729 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4730 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004731
Gilles Peskine8817f612018-12-18 00:18:46 +01004732 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004733
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004734 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4735 psa_set_key_algorithm( &attributes, alg );
4736 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004737 PSA_ASSERT( psa_import_key( &attributes,
4738 our_key_data->x, our_key_data->len,
4739 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004740
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004741 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004742 PSA_ASSERT( psa_key_derivation_key_agreement(
4743 &operation,
4744 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4745 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004746 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4747 {
4748 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004749 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004750 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004751 NULL, 0 ) );
4752 }
Gilles Peskine59685592018-09-18 12:11:34 +02004753
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004754 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004755 actual_output,
4756 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004757 ASSERT_COMPARE( actual_output, expected_output1->len,
4758 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004759 if( expected_output2->len != 0 )
4760 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004761 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004762 actual_output,
4763 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004764 ASSERT_COMPARE( actual_output, expected_output2->len,
4765 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004766 }
Gilles Peskine59685592018-09-18 12:11:34 +02004767
4768exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004769 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004770 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004771 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004772 mbedtls_free( actual_output );
4773}
4774/* END_CASE */
4775
4776/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004777void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004778{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004779 size_t bytes = bytes_arg;
4780 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004781 unsigned char *output = NULL;
4782 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004783 size_t i;
4784 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004785
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004786 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4787 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004788 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004789
Gilles Peskine8817f612018-12-18 00:18:46 +01004790 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004791
Gilles Peskinea50d7392018-06-21 10:22:13 +02004792 /* Run several times, to ensure that every output byte will be
4793 * nonzero at least once with overwhelming probability
4794 * (2^(-8*number_of_runs)). */
4795 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004796 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004797 if( bytes != 0 )
4798 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004799 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004800
4801 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004802 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4803 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004804
4805 for( i = 0; i < bytes; i++ )
4806 {
4807 if( output[i] != 0 )
4808 ++changed[i];
4809 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004810 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004811
4812 /* Check that every byte was changed to nonzero at least once. This
4813 * validates that psa_generate_random is overwriting every byte of
4814 * the output buffer. */
4815 for( i = 0; i < bytes; i++ )
4816 {
4817 TEST_ASSERT( changed[i] != 0 );
4818 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004819
4820exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004821 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004822 mbedtls_free( output );
4823 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004824}
4825/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004826
4827/* BEGIN_CASE */
4828void generate_key( int type_arg,
4829 int bits_arg,
4830 int usage_arg,
4831 int alg_arg,
4832 int expected_status_arg )
4833{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004834 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004835 psa_key_type_t type = type_arg;
4836 psa_key_usage_t usage = usage_arg;
4837 size_t bits = bits_arg;
4838 psa_algorithm_t alg = alg_arg;
4839 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004840 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004841 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004842
Gilles Peskine8817f612018-12-18 00:18:46 +01004843 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004844
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004845 psa_set_key_usage_flags( &attributes, usage );
4846 psa_set_key_algorithm( &attributes, alg );
4847 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004848 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004849
4850 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004851 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004852 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004853 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004854
4855 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004856 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4857 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4858 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004859
Gilles Peskine818ca122018-06-20 18:16:48 +02004860 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004861 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004862 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004863
4864exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004865 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004866 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004867 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004868}
4869/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004870
Gilles Peskinee56e8782019-04-26 17:34:02 +02004871/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4872void generate_key_rsa( int bits_arg,
4873 data_t *e_arg,
4874 int expected_status_arg )
4875{
4876 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02004877 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02004878 size_t bits = bits_arg;
4879 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4880 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4881 psa_status_t expected_status = expected_status_arg;
4882 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4883 uint8_t *exported = NULL;
4884 size_t exported_size =
4885 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4886 size_t exported_length = SIZE_MAX;
4887 uint8_t *e_read_buffer = NULL;
4888 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004889 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004890 size_t e_read_length = SIZE_MAX;
4891
4892 if( e_arg->len == 0 ||
4893 ( e_arg->len == 3 &&
4894 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4895 {
4896 is_default_public_exponent = 1;
4897 e_read_size = 0;
4898 }
4899 ASSERT_ALLOC( e_read_buffer, e_read_size );
4900 ASSERT_ALLOC( exported, exported_size );
4901
4902 PSA_ASSERT( psa_crypto_init( ) );
4903
4904 psa_set_key_usage_flags( &attributes, usage );
4905 psa_set_key_algorithm( &attributes, alg );
4906 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4907 e_arg->x, e_arg->len ) );
4908 psa_set_key_bits( &attributes, bits );
4909
4910 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004911 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004912 if( expected_status != PSA_SUCCESS )
4913 goto exit;
4914
4915 /* Test the key information */
4916 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4917 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4918 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4919 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4920 e_read_buffer, e_read_size,
4921 &e_read_length ) );
4922 if( is_default_public_exponent )
4923 TEST_EQUAL( e_read_length, 0 );
4924 else
4925 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4926
4927 /* Do something with the key according to its type and permitted usage. */
4928 if( ! exercise_key( handle, usage, alg ) )
4929 goto exit;
4930
4931 /* Export the key and check the public exponent. */
4932 PSA_ASSERT( psa_export_public_key( handle,
4933 exported, exported_size,
4934 &exported_length ) );
4935 {
4936 uint8_t *p = exported;
4937 uint8_t *end = exported + exported_length;
4938 size_t len;
4939 /* RSAPublicKey ::= SEQUENCE {
4940 * modulus INTEGER, -- n
4941 * publicExponent INTEGER } -- e
4942 */
4943 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004944 MBEDTLS_ASN1_SEQUENCE |
4945 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004946 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4947 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4948 MBEDTLS_ASN1_INTEGER ) );
4949 if( len >= 1 && p[0] == 0 )
4950 {
4951 ++p;
4952 --len;
4953 }
4954 if( e_arg->len == 0 )
4955 {
4956 TEST_EQUAL( len, 3 );
4957 TEST_EQUAL( p[0], 1 );
4958 TEST_EQUAL( p[1], 0 );
4959 TEST_EQUAL( p[2], 1 );
4960 }
4961 else
4962 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4963 }
4964
4965exit:
4966 psa_reset_key_attributes( &attributes );
4967 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004968 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004969 mbedtls_free( e_read_buffer );
4970 mbedtls_free( exported );
4971}
4972/* END_CASE */
4973
Darryl Greend49a4992018-06-18 17:27:26 +01004974/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004975void persistent_key_load_key_from_storage( data_t *data,
4976 int type_arg, int bits_arg,
4977 int usage_flags_arg, int alg_arg,
4978 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004979{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004980 psa_key_id_t key_id = 1;
4981 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004982 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004983 psa_key_handle_t base_key = 0;
4984 psa_key_type_t type = type_arg;
4985 size_t bits = bits_arg;
4986 psa_key_usage_t usage_flags = usage_flags_arg;
4987 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004988 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004989 unsigned char *first_export = NULL;
4990 unsigned char *second_export = NULL;
4991 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4992 size_t first_exported_length;
4993 size_t second_exported_length;
4994
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004995 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4996 {
4997 ASSERT_ALLOC( first_export, export_size );
4998 ASSERT_ALLOC( second_export, export_size );
4999 }
Darryl Greend49a4992018-06-18 17:27:26 +01005000
Gilles Peskine8817f612018-12-18 00:18:46 +01005001 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005002
Gilles Peskinec87af662019-05-15 16:12:22 +02005003 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005004 psa_set_key_usage_flags( &attributes, usage_flags );
5005 psa_set_key_algorithm( &attributes, alg );
5006 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005007 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01005008
Darryl Green0c6575a2018-11-07 16:05:30 +00005009 switch( generation_method )
5010 {
5011 case IMPORT_KEY:
5012 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02005013 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
5014 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005015 break;
Darryl Greend49a4992018-06-18 17:27:26 +01005016
Darryl Green0c6575a2018-11-07 16:05:30 +00005017 case GENERATE_KEY:
5018 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005019 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005020 break;
5021
5022 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005023 {
5024 /* Create base key */
5025 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
5026 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5027 psa_set_key_usage_flags( &base_attributes,
5028 PSA_KEY_USAGE_DERIVE );
5029 psa_set_key_algorithm( &base_attributes, derive_alg );
5030 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005031 PSA_ASSERT( psa_import_key( &base_attributes,
5032 data->x, data->len,
5033 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005034 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005035 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005036 PSA_ASSERT( psa_key_derivation_input_key(
5037 &operation,
5038 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005039 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005040 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005041 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005042 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5043 &operation,
5044 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005045 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005046 PSA_ASSERT( psa_destroy_key( base_key ) );
5047 base_key = 0;
5048 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005049 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005050 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005051 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005052
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005053 /* Export the key if permitted by the key policy. */
5054 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5055 {
5056 PSA_ASSERT( psa_export_key( handle,
5057 first_export, export_size,
5058 &first_exported_length ) );
5059 if( generation_method == IMPORT_KEY )
5060 ASSERT_COMPARE( data->x, data->len,
5061 first_export, first_exported_length );
5062 }
Darryl Greend49a4992018-06-18 17:27:26 +01005063
5064 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005065 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005066 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005067 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005068
Darryl Greend49a4992018-06-18 17:27:26 +01005069 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005070 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005071 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5072 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5073 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5074 PSA_KEY_LIFETIME_PERSISTENT );
5075 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5076 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5077 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5078 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005079
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005080 /* Export the key again if permitted by the key policy. */
5081 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005082 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005083 PSA_ASSERT( psa_export_key( handle,
5084 second_export, export_size,
5085 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005086 ASSERT_COMPARE( first_export, first_exported_length,
5087 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005088 }
5089
5090 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005091 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005092 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005093
5094exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005095 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005096 mbedtls_free( first_export );
5097 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005098 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005099 psa_destroy_key( base_key );
5100 if( handle == 0 )
5101 {
5102 /* In case there was a test failure after creating the persistent key
5103 * but while it was not open, try to re-open the persistent key
5104 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005105 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005106 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005107 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005108 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005109}
5110/* END_CASE */