blob: 9efee51e3b5859e924de6e3089484ee7ed091f43 [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
Janos Follathf2815ea2019-07-03 12:41:36 +0100520static int setup_key_derivation_wrap( psa_key_derivation_operation_t* operation,
521 psa_key_handle_t handle,
522 psa_algorithm_t alg,
523 unsigned char* input1, size_t input1_length,
524 unsigned char* input2, size_t input2_length,
525 size_t capacity )
526{
527 PSA_ASSERT( psa_key_derivation_setup( operation, alg ) );
528 if( PSA_ALG_IS_HKDF( alg ) )
529 {
530 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
531 PSA_KEY_DERIVATION_INPUT_SALT,
532 input1, input1_length ) );
533 PSA_ASSERT( psa_key_derivation_input_key( operation,
534 PSA_KEY_DERIVATION_INPUT_SECRET,
535 handle ) );
536 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
537 PSA_KEY_DERIVATION_INPUT_INFO,
538 input2,
539 input2_length ) );
540 }
541 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
542 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
543 {
544 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
545 PSA_KEY_DERIVATION_INPUT_SEED,
546 input1, input1_length ) );
547 PSA_ASSERT( psa_key_derivation_input_key( operation,
548 PSA_KEY_DERIVATION_INPUT_SECRET,
549 handle ) );
550 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
551 PSA_KEY_DERIVATION_INPUT_LABEL,
552 input2, input2_length ) );
553 }
554 else
555 {
556 TEST_ASSERT( ! "Key derivation algorithm not supported" );
557 }
558
559 PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
560
561 return( 1 );
562
563exit:
564 return( 0 );
565}
566
567
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100568static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200569 psa_key_usage_t usage,
570 psa_algorithm_t alg )
571{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200572 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathf2815ea2019-07-03 12:41:36 +0100573 unsigned char input1[] = "Input 1";
574 size_t input1_length = sizeof( input1 );
575 unsigned char input2[] = "Input 2";
576 size_t input2_length = sizeof( input2 );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200577 unsigned char output[1];
Janos Follathf2815ea2019-07-03 12:41:36 +0100578 size_t capacity = sizeof( output );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200579
580 if( usage & PSA_KEY_USAGE_DERIVE )
581 {
Janos Follathf2815ea2019-07-03 12:41:36 +0100582 if( !setup_key_derivation_wrap( &operation, handle, alg,
583 input1, input1_length,
584 input2, input2_length, capacity ) )
585 goto exit;
Gilles Peskine7607cd62019-05-29 17:35:00 +0200586
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200587 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200588 output,
Janos Follathf2815ea2019-07-03 12:41:36 +0100589 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200590 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200591 }
592
593 return( 1 );
594
595exit:
596 return( 0 );
597}
598
Gilles Peskinec7998b72018-11-07 18:45:02 +0100599/* We need two keys to exercise key agreement. Exercise the
600 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200601static psa_status_t key_agreement_with_self(
602 psa_key_derivation_operation_t *operation,
603 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100604{
605 psa_key_type_t private_key_type;
606 psa_key_type_t public_key_type;
607 size_t key_bits;
608 uint8_t *public_key = NULL;
609 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200610 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200611 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
612 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200613 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200614 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100615
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200616 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
617 private_key_type = psa_get_key_type( &attributes );
618 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200619 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100620 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
621 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100622 PSA_ASSERT( psa_export_public_key( handle,
623 public_key, public_key_length,
624 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100625
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200626 status = psa_key_derivation_key_agreement(
627 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
628 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100629exit:
630 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200631 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100632 return( status );
633}
634
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200635/* We need two keys to exercise key agreement. Exercise the
636 * private key against its own public key. */
637static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
638 psa_key_handle_t handle )
639{
640 psa_key_type_t private_key_type;
641 psa_key_type_t public_key_type;
642 size_t key_bits;
643 uint8_t *public_key = NULL;
644 size_t public_key_length;
645 uint8_t output[1024];
646 size_t output_length;
647 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200648 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
649 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200650 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200651 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200652
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200653 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
654 private_key_type = psa_get_key_type( &attributes );
655 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200656 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200657 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
658 ASSERT_ALLOC( public_key, public_key_length );
659 PSA_ASSERT( psa_export_public_key( handle,
660 public_key, public_key_length,
661 &public_key_length ) );
662
Gilles Peskinebe697d82019-05-16 18:00:41 +0200663 status = psa_raw_key_agreement( alg, handle,
664 public_key, public_key_length,
665 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200666exit:
667 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200668 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200669 return( status );
670}
671
672static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
673 psa_key_usage_t usage,
674 psa_algorithm_t alg )
675{
676 int ok = 0;
677
678 if( usage & PSA_KEY_USAGE_DERIVE )
679 {
680 /* We need two keys to exercise key agreement. Exercise the
681 * private key against its own public key. */
682 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
683 }
684 ok = 1;
685
686exit:
687 return( ok );
688}
689
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100690static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200691 psa_key_usage_t usage,
692 psa_algorithm_t alg )
693{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200694 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200695 unsigned char output[1];
696 int ok = 0;
697
698 if( usage & PSA_KEY_USAGE_DERIVE )
699 {
700 /* We need two keys to exercise key agreement. Exercise the
701 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200702 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
703 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
704 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200705 output,
706 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200707 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200708 }
709 ok = 1;
710
711exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200712 return( ok );
713}
714
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200715static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
716 size_t min_bits, size_t max_bits,
717 int must_be_odd )
718{
719 size_t len;
720 size_t actual_bits;
721 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100722 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100723 MBEDTLS_ASN1_INTEGER ),
724 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200725 /* Tolerate a slight departure from DER encoding:
726 * - 0 may be represented by an empty string or a 1-byte string.
727 * - The sign bit may be used as a value bit. */
728 if( ( len == 1 && ( *p )[0] == 0 ) ||
729 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
730 {
731 ++( *p );
732 --len;
733 }
734 if( min_bits == 0 && len == 0 )
735 return( 1 );
736 msb = ( *p )[0];
737 TEST_ASSERT( msb != 0 );
738 actual_bits = 8 * ( len - 1 );
739 while( msb != 0 )
740 {
741 msb >>= 1;
742 ++actual_bits;
743 }
744 TEST_ASSERT( actual_bits >= min_bits );
745 TEST_ASSERT( actual_bits <= max_bits );
746 if( must_be_odd )
747 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
748 *p += len;
749 return( 1 );
750exit:
751 return( 0 );
752}
753
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200754static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
755 uint8_t *exported, size_t exported_length )
756{
757 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100758 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200759 else
760 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200761
762#if defined(MBEDTLS_DES_C)
763 if( type == PSA_KEY_TYPE_DES )
764 {
765 /* Check the parity bits. */
766 unsigned i;
767 for( i = 0; i < bits / 8; i++ )
768 {
769 unsigned bit_count = 0;
770 unsigned m;
771 for( m = 1; m <= 0x100; m <<= 1 )
772 {
773 if( exported[i] & m )
774 ++bit_count;
775 }
776 TEST_ASSERT( bit_count % 2 != 0 );
777 }
778 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200779 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200780#endif
781
782#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200783 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200784 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200785 uint8_t *p = exported;
786 uint8_t *end = exported + exported_length;
787 size_t len;
788 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200789 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200790 * modulus INTEGER, -- n
791 * publicExponent INTEGER, -- e
792 * privateExponent INTEGER, -- d
793 * prime1 INTEGER, -- p
794 * prime2 INTEGER, -- q
795 * exponent1 INTEGER, -- d mod (p-1)
796 * exponent2 INTEGER, -- d mod (q-1)
797 * coefficient INTEGER, -- (inverse of q) mod p
798 * }
799 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100800 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
801 MBEDTLS_ASN1_SEQUENCE |
802 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
803 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200804 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
805 goto exit;
806 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
807 goto exit;
808 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
809 goto exit;
810 /* Require d to be at least half the size of n. */
811 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
812 goto exit;
813 /* Require p and q to be at most half the size of n, rounded up. */
814 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
815 goto exit;
816 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
817 goto exit;
818 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
819 goto exit;
820 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
821 goto exit;
822 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
823 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100824 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100825 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200826 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200827#endif /* MBEDTLS_RSA_C */
828
829#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200830 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200831 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100832 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100833 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100834 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200835 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200836#endif /* MBEDTLS_ECP_C */
837
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200838 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
839 {
840 uint8_t *p = exported;
841 uint8_t *end = exported + exported_length;
842 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200843#if defined(MBEDTLS_RSA_C)
844 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
845 {
846 /* RSAPublicKey ::= SEQUENCE {
847 * modulus INTEGER, -- n
848 * publicExponent INTEGER } -- e
849 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100850 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
851 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100852 MBEDTLS_ASN1_CONSTRUCTED ),
853 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100854 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200855 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
856 goto exit;
857 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
858 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100859 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200860 }
861 else
862#endif /* MBEDTLS_RSA_C */
863#if defined(MBEDTLS_ECP_C)
864 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
865 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000866 /* The representation of an ECC public key is:
867 * - The byte 0x04;
868 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
869 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
870 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000871 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100872 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
873 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200874 }
875 else
876#endif /* MBEDTLS_ECP_C */
877 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100878 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200879 mbedtls_snprintf( message, sizeof( message ),
880 "No sanity check for public key type=0x%08lx",
881 (unsigned long) type );
882 test_fail( message, __LINE__, __FILE__ );
883 return( 0 );
884 }
885 }
886 else
887
888 {
889 /* No sanity checks for other types */
890 }
891
892 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200893
894exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200895 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200896}
897
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100898static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200899 psa_key_usage_t usage )
900{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200901 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200902 uint8_t *exported = NULL;
903 size_t exported_size = 0;
904 size_t exported_length = 0;
905 int ok = 0;
906
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200907 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200908
909 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200910 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200911 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100912 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
913 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200914 ok = 1;
915 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200916 }
917
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200918 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
919 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200920 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200921
Gilles Peskine8817f612018-12-18 00:18:46 +0100922 PSA_ASSERT( psa_export_key( handle,
923 exported, exported_size,
924 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200925 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
926 psa_get_key_bits( &attributes ),
927 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200928
929exit:
930 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200931 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200932 return( ok );
933}
934
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100935static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200936{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200937 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200938 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200939 uint8_t *exported = NULL;
940 size_t exported_size = 0;
941 size_t exported_length = 0;
942 int ok = 0;
943
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200944 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
945 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200946 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100947 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100948 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200949 return( 1 );
950 }
951
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200952 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200953 psa_get_key_type( &attributes ) );
954 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
955 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200956 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200957
Gilles Peskine8817f612018-12-18 00:18:46 +0100958 PSA_ASSERT( psa_export_public_key( handle,
959 exported, exported_size,
960 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200961 ok = exported_key_sanity_check( public_type,
962 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200963 exported, exported_length );
964
965exit:
966 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200967 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200968 return( ok );
969}
970
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100971/** Do smoke tests on a key.
972 *
973 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
974 * sign/verify, or derivation) that is permitted according to \p usage.
975 * \p usage and \p alg should correspond to the expected policy on the
976 * key.
977 *
978 * Export the key if permitted by \p usage, and check that the output
979 * looks sensible. If \p usage forbids export, check that
980 * \p psa_export_key correctly rejects the attempt. If the key is
981 * asymmetric, also check \p psa_export_public_key.
982 *
983 * If the key fails the tests, this function calls the test framework's
984 * `test_fail` function and returns false. Otherwise this function returns
985 * true. Therefore it should be used as follows:
986 * ```
987 * if( ! exercise_key( ... ) ) goto exit;
988 * ```
989 *
990 * \param handle The key to exercise. It should be capable of performing
991 * \p alg.
992 * \param usage The usage flags to assume.
993 * \param alg The algorithm to exercise.
994 *
995 * \retval 0 The key failed the smoke tests.
996 * \retval 1 The key passed the smoke tests.
997 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100998static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +0200999 psa_key_usage_t usage,
1000 psa_algorithm_t alg )
1001{
1002 int ok;
1003 if( alg == 0 )
1004 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1005 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001006 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001007 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001008 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001009 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001010 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001011 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001012 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001013 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001014 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001015 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001016 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001017 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1018 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001019 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001020 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001021 else
1022 {
1023 char message[40];
1024 mbedtls_snprintf( message, sizeof( message ),
1025 "No code to exercise alg=0x%08lx",
1026 (unsigned long) alg );
1027 test_fail( message, __LINE__, __FILE__ );
1028 ok = 0;
1029 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001030
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001031 ok = ok && exercise_export_key( handle, usage );
1032 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001033
Gilles Peskine02b75072018-07-01 22:31:34 +02001034 return( ok );
1035}
1036
Gilles Peskine10df3412018-10-25 22:35:43 +02001037static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1038 psa_algorithm_t alg )
1039{
1040 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1041 {
1042 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1043 PSA_KEY_USAGE_VERIFY :
1044 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1045 }
1046 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1047 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1048 {
1049 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1050 PSA_KEY_USAGE_ENCRYPT :
1051 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1052 }
1053 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1054 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1055 {
1056 return( PSA_KEY_USAGE_DERIVE );
1057 }
1058 else
1059 {
1060 return( 0 );
1061 }
1062
1063}
Darryl Green0c6575a2018-11-07 16:05:30 +00001064
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001065static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1066{
1067 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1068 uint8_t buffer[1];
1069 size_t length;
1070 int ok = 0;
1071
Gilles Peskinec87af662019-05-15 16:12:22 +02001072 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001073 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1074 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1075 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1076 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1077 PSA_ERROR_INVALID_HANDLE );
1078 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001079 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001080 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1081 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1082 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1083 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1084
1085 TEST_EQUAL( psa_export_key( handle,
1086 buffer, sizeof( buffer ), &length ),
1087 PSA_ERROR_INVALID_HANDLE );
1088 TEST_EQUAL( psa_export_public_key( handle,
1089 buffer, sizeof( buffer ), &length ),
1090 PSA_ERROR_INVALID_HANDLE );
1091
1092 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1093 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1094
1095 ok = 1;
1096
1097exit:
1098 psa_reset_key_attributes( &attributes );
1099 return( ok );
1100}
1101
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001102/* An overapproximation of the amount of storage needed for a key of the
1103 * given type and with the given content. The API doesn't make it easy
1104 * to find a good value for the size. The current implementation doesn't
1105 * care about the value anyway. */
1106#define KEY_BITS_FROM_DATA( type, data ) \
1107 ( data )->len
1108
Darryl Green0c6575a2018-11-07 16:05:30 +00001109typedef enum {
1110 IMPORT_KEY = 0,
1111 GENERATE_KEY = 1,
1112 DERIVE_KEY = 2
1113} generate_method;
1114
Gilles Peskinee59236f2018-01-27 23:32:46 +01001115/* END_HEADER */
1116
1117/* BEGIN_DEPENDENCIES
1118 * depends_on:MBEDTLS_PSA_CRYPTO_C
1119 * END_DEPENDENCIES
1120 */
1121
1122/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001123void static_checks( )
1124{
1125 size_t max_truncated_mac_size =
1126 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1127
1128 /* Check that the length for a truncated MAC always fits in the algorithm
1129 * encoding. The shifted mask is the maximum truncated value. The
1130 * untruncated algorithm may be one byte larger. */
1131 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1132}
1133/* END_CASE */
1134
1135/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001136void attributes_set_get( int id_arg, int lifetime_arg,
1137 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001138 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001139{
Gilles Peskine4747d192019-04-17 15:05:45 +02001140 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001141 psa_key_id_t id = id_arg;
1142 psa_key_lifetime_t lifetime = lifetime_arg;
1143 psa_key_usage_t usage_flags = usage_flags_arg;
1144 psa_algorithm_t alg = alg_arg;
1145 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001146 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001147
1148 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1149 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1150 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1151 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1152 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001153 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001154
Gilles Peskinec87af662019-05-15 16:12:22 +02001155 psa_set_key_id( &attributes, id );
1156 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001157 psa_set_key_usage_flags( &attributes, usage_flags );
1158 psa_set_key_algorithm( &attributes, alg );
1159 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001160 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001161
1162 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1163 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1164 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1165 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1166 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001167 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001168
1169 psa_reset_key_attributes( &attributes );
1170
1171 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1172 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1173 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1174 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1175 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001176 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001177}
1178/* END_CASE */
1179
1180/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001181void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1182 int expected_id_arg, int expected_lifetime_arg )
1183{
1184 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1185 psa_key_id_t id1 = id1_arg;
1186 psa_key_lifetime_t lifetime = lifetime_arg;
1187 psa_key_id_t id2 = id2_arg;
1188 psa_key_id_t expected_id = expected_id_arg;
1189 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1190
1191 if( id1_arg != -1 )
1192 psa_set_key_id( &attributes, id1 );
1193 if( lifetime_arg != -1 )
1194 psa_set_key_lifetime( &attributes, lifetime );
1195 if( id2_arg != -1 )
1196 psa_set_key_id( &attributes, id2 );
1197
1198 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1199 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1200}
1201/* END_CASE */
1202
1203/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001204void import( data_t *data, int type_arg,
1205 int attr_bits_arg,
1206 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001207{
1208 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1209 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001210 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001211 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001212 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001213 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001214 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001215
Gilles Peskine8817f612018-12-18 00:18:46 +01001216 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001217
Gilles Peskine4747d192019-04-17 15:05:45 +02001218 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001219 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001220 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001221 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001222 if( status != PSA_SUCCESS )
1223 goto exit;
1224
1225 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1226 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001227 if( attr_bits != 0 )
1228 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001229
1230 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001231 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001232
1233exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001234 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001235 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001236 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001237}
1238/* END_CASE */
1239
1240/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001241void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1242{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001243 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001244 size_t bits = bits_arg;
1245 psa_status_t expected_status = expected_status_arg;
1246 psa_status_t status;
1247 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001248 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001249 size_t buffer_size = /* Slight overapproximations */
1250 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001251 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001252 unsigned char *p;
1253 int ret;
1254 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001255 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001256
Gilles Peskine8817f612018-12-18 00:18:46 +01001257 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001258 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001259
1260 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1261 bits, keypair ) ) >= 0 );
1262 length = ret;
1263
1264 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001265 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001266 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001267 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001268
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001269 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001270 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001271
1272exit:
1273 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001274 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001275}
1276/* END_CASE */
1277
1278/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001279void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001280 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001281 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001282 int expected_bits,
1283 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001284 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001285 int canonical_input )
1286{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001287 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001288 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001289 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001290 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001291 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001292 unsigned char *exported = NULL;
1293 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001294 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001295 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001296 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001297 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001298 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001299
Moran Pekercb088e72018-07-17 17:36:59 +03001300 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001301 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001302 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001303 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001304 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001305
Gilles Peskine4747d192019-04-17 15:05:45 +02001306 psa_set_key_usage_flags( &attributes, usage_arg );
1307 psa_set_key_algorithm( &attributes, alg );
1308 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001309
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001310 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001311 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001312
1313 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001314 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1315 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1316 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317
1318 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001319 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001320 exported, export_size,
1321 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001322 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001323
1324 /* The exported length must be set by psa_export_key() to a value between 0
1325 * and export_size. On errors, the exported length must be 0. */
1326 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1327 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1328 TEST_ASSERT( exported_length <= export_size );
1329
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001330 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001331 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001332 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001333 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001334 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001335 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001336 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001337
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001338 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001339 goto exit;
1340
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001341 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001342 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001343 else
1344 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001345 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001346 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1347 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001348 PSA_ASSERT( psa_export_key( handle2,
1349 reexported,
1350 export_size,
1351 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001352 ASSERT_COMPARE( exported, exported_length,
1353 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001354 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001355 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001356 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001357
1358destroy:
1359 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001360 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001361 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001362
1363exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001364 mbedtls_free( exported );
1365 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001366 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001367 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001368}
1369/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001370
Moran Pekerf709f4a2018-06-06 17:26:04 +03001371/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001372void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001373{
Gilles Peskine8817f612018-12-18 00:18:46 +01001374 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001375 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001376
1377exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001378 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001379}
1380/* END_CASE */
1381
1382/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001383void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001384 int type_arg,
1385 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001386 int export_size_delta,
1387 int expected_export_status_arg,
1388 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001389{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001390 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001391 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001392 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001393 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001394 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001395 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001396 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001397 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001398 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001399
Gilles Peskine8817f612018-12-18 00:18:46 +01001400 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001401
Gilles Peskine4747d192019-04-17 15:05:45 +02001402 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1403 psa_set_key_algorithm( &attributes, alg );
1404 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001405
1406 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001407 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001408
Gilles Peskine49c25912018-10-29 15:15:31 +01001409 /* Export the public key */
1410 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001411 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001412 exported, export_size,
1413 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001414 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001415 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001416 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001417 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001418 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001419 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1420 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001421 TEST_ASSERT( expected_public_key->len <=
1422 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001423 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1424 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001425 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001426
1427exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001428 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001429 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001430 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001431 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001432}
1433/* END_CASE */
1434
Gilles Peskine20035e32018-02-03 22:44:14 +01001435/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001436void import_and_exercise_key( data_t *data,
1437 int type_arg,
1438 int bits_arg,
1439 int alg_arg )
1440{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001441 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001442 psa_key_type_t type = type_arg;
1443 size_t bits = bits_arg;
1444 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001445 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001446 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001447 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001448
Gilles Peskine8817f612018-12-18 00:18:46 +01001449 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001450
Gilles Peskine4747d192019-04-17 15:05:45 +02001451 psa_set_key_usage_flags( &attributes, usage );
1452 psa_set_key_algorithm( &attributes, alg );
1453 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001454
1455 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001456 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001457
1458 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001459 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1460 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1461 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001462
1463 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001464 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001465 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001466
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001467 PSA_ASSERT( psa_destroy_key( handle ) );
1468 test_operations_on_invalid_handle( handle );
1469
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001470exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001471 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001472 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001473 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001474}
1475/* END_CASE */
1476
1477/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001478void key_policy( int usage_arg, int alg_arg )
1479{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001480 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001481 psa_algorithm_t alg = alg_arg;
1482 psa_key_usage_t usage = usage_arg;
1483 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1484 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001485 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001486
1487 memset( key, 0x2a, sizeof( key ) );
1488
Gilles Peskine8817f612018-12-18 00:18:46 +01001489 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001490
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001491 psa_set_key_usage_flags( &attributes, usage );
1492 psa_set_key_algorithm( &attributes, alg );
1493 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001494
Gilles Peskine73676cb2019-05-15 20:15:10 +02001495 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001496
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001497 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1498 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1499 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1500 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001501
1502exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001503 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001504 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001505 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001506}
1507/* END_CASE */
1508
1509/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001510void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001511{
1512 /* Test each valid way of initializing the object, except for `= {0}`, as
1513 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1514 * though it's OK by the C standard. We could test for this, but we'd need
1515 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001516 psa_key_attributes_t func = psa_key_attributes_init( );
1517 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1518 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001519
1520 memset( &zero, 0, sizeof( zero ) );
1521
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001522 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1523 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1524 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001525
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001526 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1527 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1528 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1529
1530 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1531 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1532 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1533
1534 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1535 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1536 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1537
1538 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1539 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1540 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001541}
1542/* END_CASE */
1543
1544/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001545void mac_key_policy( int policy_usage,
1546 int policy_alg,
1547 int key_type,
1548 data_t *key_data,
1549 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001550{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001551 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001552 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001553 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001554 psa_status_t status;
1555 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001556
Gilles Peskine8817f612018-12-18 00:18:46 +01001557 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001558
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001559 psa_set_key_usage_flags( &attributes, policy_usage );
1560 psa_set_key_algorithm( &attributes, policy_alg );
1561 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001562
Gilles Peskine049c7532019-05-15 20:22:09 +02001563 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1564 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001565
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001566 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001567 if( policy_alg == exercise_alg &&
1568 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001569 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001570 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001571 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001572 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001573
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001574 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001575 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001576 if( policy_alg == exercise_alg &&
1577 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001578 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001579 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001580 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001581
1582exit:
1583 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001584 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001585 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001586}
1587/* END_CASE */
1588
1589/* BEGIN_CASE */
1590void cipher_key_policy( int policy_usage,
1591 int policy_alg,
1592 int key_type,
1593 data_t *key_data,
1594 int exercise_alg )
1595{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001596 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001597 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001598 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001599 psa_status_t status;
1600
Gilles Peskine8817f612018-12-18 00:18:46 +01001601 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001602
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001603 psa_set_key_usage_flags( &attributes, policy_usage );
1604 psa_set_key_algorithm( &attributes, policy_alg );
1605 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001606
Gilles Peskine049c7532019-05-15 20:22:09 +02001607 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1608 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001609
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001610 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001611 if( policy_alg == exercise_alg &&
1612 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001613 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001614 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001615 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001616 psa_cipher_abort( &operation );
1617
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001618 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001619 if( policy_alg == exercise_alg &&
1620 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001621 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001622 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001623 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001624
1625exit:
1626 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001627 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001628 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001629}
1630/* END_CASE */
1631
1632/* BEGIN_CASE */
1633void aead_key_policy( int policy_usage,
1634 int policy_alg,
1635 int key_type,
1636 data_t *key_data,
1637 int nonce_length_arg,
1638 int tag_length_arg,
1639 int exercise_alg )
1640{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001641 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001642 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001643 psa_status_t status;
1644 unsigned char nonce[16] = {0};
1645 size_t nonce_length = nonce_length_arg;
1646 unsigned char tag[16];
1647 size_t tag_length = tag_length_arg;
1648 size_t output_length;
1649
1650 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1651 TEST_ASSERT( tag_length <= sizeof( tag ) );
1652
Gilles Peskine8817f612018-12-18 00:18:46 +01001653 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001655 psa_set_key_usage_flags( &attributes, policy_usage );
1656 psa_set_key_algorithm( &attributes, policy_alg );
1657 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001658
Gilles Peskine049c7532019-05-15 20:22:09 +02001659 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1660 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001661
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001662 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001663 nonce, nonce_length,
1664 NULL, 0,
1665 NULL, 0,
1666 tag, tag_length,
1667 &output_length );
1668 if( policy_alg == exercise_alg &&
1669 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001670 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001671 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001672 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001673
1674 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001675 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001676 nonce, nonce_length,
1677 NULL, 0,
1678 tag, tag_length,
1679 NULL, 0,
1680 &output_length );
1681 if( policy_alg == exercise_alg &&
1682 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001683 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001684 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001685 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001686
1687exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001688 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001689 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001690}
1691/* END_CASE */
1692
1693/* BEGIN_CASE */
1694void asymmetric_encryption_key_policy( int policy_usage,
1695 int policy_alg,
1696 int key_type,
1697 data_t *key_data,
1698 int exercise_alg )
1699{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001700 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001701 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001702 psa_status_t status;
1703 size_t key_bits;
1704 size_t buffer_length;
1705 unsigned char *buffer = NULL;
1706 size_t output_length;
1707
Gilles Peskine8817f612018-12-18 00:18:46 +01001708 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001709
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001710 psa_set_key_usage_flags( &attributes, policy_usage );
1711 psa_set_key_algorithm( &attributes, policy_alg );
1712 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001713
Gilles Peskine049c7532019-05-15 20:22:09 +02001714 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1715 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001717 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1718 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001719 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1720 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001721 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001722
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001723 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001724 NULL, 0,
1725 NULL, 0,
1726 buffer, buffer_length,
1727 &output_length );
1728 if( policy_alg == exercise_alg &&
1729 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001730 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001731 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001732 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001733
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001734 if( buffer_length != 0 )
1735 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001736 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001737 buffer, buffer_length,
1738 NULL, 0,
1739 buffer, buffer_length,
1740 &output_length );
1741 if( policy_alg == exercise_alg &&
1742 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001743 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001744 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001745 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001746
1747exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001748 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001749 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001750 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751 mbedtls_free( buffer );
1752}
1753/* END_CASE */
1754
1755/* BEGIN_CASE */
1756void asymmetric_signature_key_policy( int policy_usage,
1757 int policy_alg,
1758 int key_type,
1759 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001760 int exercise_alg,
1761 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001763 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001764 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001765 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001766 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1767 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1768 * compatible with the policy and `payload_length_arg` is supposed to be
1769 * a valid input length to sign. If `payload_length_arg <= 0`,
1770 * `exercise_alg` is supposed to be forbidden by the policy. */
1771 int compatible_alg = payload_length_arg > 0;
1772 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001773 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1774 size_t signature_length;
1775
Gilles Peskine8817f612018-12-18 00:18:46 +01001776 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001777
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001778 psa_set_key_usage_flags( &attributes, policy_usage );
1779 psa_set_key_algorithm( &attributes, policy_alg );
1780 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001781
Gilles Peskine049c7532019-05-15 20:22:09 +02001782 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1783 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001784
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001785 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001786 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001787 signature, sizeof( signature ),
1788 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001789 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001790 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001791 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001792 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001793
1794 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001795 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001797 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001798 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001799 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001800 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001801 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001802
1803exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001804 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001805 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001806}
1807/* END_CASE */
1808
Janos Follathba3fab92019-06-11 14:50:16 +01001809/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001810void derive_key_policy( int policy_usage,
1811 int policy_alg,
1812 int key_type,
1813 data_t *key_data,
1814 int exercise_alg )
1815{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001816 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001817 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001818 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001819 psa_status_t status;
1820
Gilles Peskine8817f612018-12-18 00:18:46 +01001821 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001822
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001823 psa_set_key_usage_flags( &attributes, policy_usage );
1824 psa_set_key_algorithm( &attributes, policy_alg );
1825 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001826
Gilles Peskine049c7532019-05-15 20:22:09 +02001827 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1828 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001829
Janos Follathba3fab92019-06-11 14:50:16 +01001830 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1831
1832 if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
1833 PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
Janos Follath0c1ed842019-06-28 13:35:36 +01001834 {
Janos Follathba3fab92019-06-11 14:50:16 +01001835 PSA_ASSERT( psa_key_derivation_input_bytes(
1836 &operation,
1837 PSA_KEY_DERIVATION_INPUT_SEED,
1838 (const uint8_t*) "", 0) );
Janos Follath0c1ed842019-06-28 13:35:36 +01001839 }
Janos Follathba3fab92019-06-11 14:50:16 +01001840
1841 status = psa_key_derivation_input_key( &operation,
1842 PSA_KEY_DERIVATION_INPUT_SECRET,
1843 handle );
1844
Gilles Peskineea0fb492018-07-12 17:17:20 +02001845 if( policy_alg == exercise_alg &&
1846 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001847 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001848 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001849 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001850
1851exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001852 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001853 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001854 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001855}
1856/* END_CASE */
1857
1858/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001859void agreement_key_policy( int policy_usage,
1860 int policy_alg,
1861 int key_type_arg,
1862 data_t *key_data,
1863 int exercise_alg )
1864{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001865 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001866 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001867 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001868 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001869 psa_status_t status;
1870
Gilles Peskine8817f612018-12-18 00:18:46 +01001871 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001872
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001873 psa_set_key_usage_flags( &attributes, policy_usage );
1874 psa_set_key_algorithm( &attributes, policy_alg );
1875 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001876
Gilles Peskine049c7532019-05-15 20:22:09 +02001877 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1878 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001879
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001880 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1881 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001882
Gilles Peskine01d718c2018-09-18 12:01:02 +02001883 if( policy_alg == exercise_alg &&
1884 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001885 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001886 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001887 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001888
1889exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001890 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001891 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001892 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001893}
1894/* END_CASE */
1895
1896/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001897void key_policy_alg2( int key_type_arg, data_t *key_data,
1898 int usage_arg, int alg_arg, int alg2_arg )
1899{
1900 psa_key_handle_t handle = 0;
1901 psa_key_type_t key_type = key_type_arg;
1902 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1903 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1904 psa_key_usage_t usage = usage_arg;
1905 psa_algorithm_t alg = alg_arg;
1906 psa_algorithm_t alg2 = alg2_arg;
1907
1908 PSA_ASSERT( psa_crypto_init( ) );
1909
1910 psa_set_key_usage_flags( &attributes, usage );
1911 psa_set_key_algorithm( &attributes, alg );
1912 psa_set_key_enrollment_algorithm( &attributes, alg2 );
1913 psa_set_key_type( &attributes, key_type );
1914 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1915 &handle ) );
1916
1917 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1918 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1919 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1920 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
1921
1922 if( ! exercise_key( handle, usage, alg ) )
1923 goto exit;
1924 if( ! exercise_key( handle, usage, alg2 ) )
1925 goto exit;
1926
1927exit:
1928 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001929 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001930}
1931/* END_CASE */
1932
1933/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001934void raw_agreement_key_policy( int policy_usage,
1935 int policy_alg,
1936 int key_type_arg,
1937 data_t *key_data,
1938 int exercise_alg )
1939{
1940 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001941 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001942 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001943 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001944 psa_status_t status;
1945
1946 PSA_ASSERT( psa_crypto_init( ) );
1947
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001948 psa_set_key_usage_flags( &attributes, policy_usage );
1949 psa_set_key_algorithm( &attributes, policy_alg );
1950 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001951
Gilles Peskine049c7532019-05-15 20:22:09 +02001952 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1953 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001954
1955 status = raw_key_agreement_with_self( exercise_alg, handle );
1956
1957 if( policy_alg == exercise_alg &&
1958 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1959 PSA_ASSERT( status );
1960 else
1961 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1962
1963exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001964 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001965 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001966 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001967}
1968/* END_CASE */
1969
1970/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001971void copy_success( int source_usage_arg,
1972 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02001973 int type_arg, data_t *material,
1974 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001975 int target_usage_arg,
1976 int target_alg_arg, int target_alg2_arg,
1977 int expected_usage_arg,
1978 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001979{
Gilles Peskineca25db92019-04-19 11:43:08 +02001980 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1981 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001982 psa_key_usage_t expected_usage = expected_usage_arg;
1983 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001984 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001985 psa_key_handle_t source_handle = 0;
1986 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001987 uint8_t *export_buffer = NULL;
1988
Gilles Peskine57ab7212019-01-28 13:03:09 +01001989 PSA_ASSERT( psa_crypto_init( ) );
1990
Gilles Peskineca25db92019-04-19 11:43:08 +02001991 /* Prepare the source key. */
1992 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1993 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001994 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02001995 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02001996 PSA_ASSERT( psa_import_key( &source_attributes,
1997 material->x, material->len,
1998 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001999 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002000
Gilles Peskineca25db92019-04-19 11:43:08 +02002001 /* Prepare the target attributes. */
2002 if( copy_attributes )
2003 target_attributes = source_attributes;
2004 if( target_usage_arg != -1 )
2005 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2006 if( target_alg_arg != -1 )
2007 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002008 if( target_alg2_arg != -1 )
2009 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002010
2011 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002012 PSA_ASSERT( psa_copy_key( source_handle,
2013 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002014
2015 /* Destroy the source to ensure that this doesn't affect the target. */
2016 PSA_ASSERT( psa_destroy_key( source_handle ) );
2017
2018 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002019 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2020 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2021 psa_get_key_type( &target_attributes ) );
2022 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2023 psa_get_key_bits( &target_attributes ) );
2024 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2025 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002026 TEST_EQUAL( expected_alg2,
2027 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002028 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2029 {
2030 size_t length;
2031 ASSERT_ALLOC( export_buffer, material->len );
2032 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2033 material->len, &length ) );
2034 ASSERT_COMPARE( material->x, material->len,
2035 export_buffer, length );
2036 }
2037 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2038 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002039 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2040 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002041
2042 PSA_ASSERT( psa_close_key( target_handle ) );
2043
2044exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002045 psa_reset_key_attributes( &source_attributes );
2046 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002047 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002048 mbedtls_free( export_buffer );
2049}
2050/* END_CASE */
2051
2052/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002053void copy_fail( int source_usage_arg,
2054 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002055 int type_arg, data_t *material,
2056 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002057 int target_usage_arg,
2058 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002059 int expected_status_arg )
2060{
2061 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2062 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2063 psa_key_handle_t source_handle = 0;
2064 psa_key_handle_t target_handle = 0;
2065
2066 PSA_ASSERT( psa_crypto_init( ) );
2067
2068 /* Prepare the source key. */
2069 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2070 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002071 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002072 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002073 PSA_ASSERT( psa_import_key( &source_attributes,
2074 material->x, material->len,
2075 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002076
2077 /* Prepare the target attributes. */
2078 psa_set_key_type( &target_attributes, target_type_arg );
2079 psa_set_key_bits( &target_attributes, target_bits_arg );
2080 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2081 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002082 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002083
2084 /* Try to copy the key. */
2085 TEST_EQUAL( psa_copy_key( source_handle,
2086 &target_attributes, &target_handle ),
2087 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002088
2089 PSA_ASSERT( psa_destroy_key( source_handle ) );
2090
Gilles Peskine4a644642019-05-03 17:14:08 +02002091exit:
2092 psa_reset_key_attributes( &source_attributes );
2093 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002094 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002095}
2096/* END_CASE */
2097
2098/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002099void hash_operation_init( )
2100{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002101 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002102 /* Test each valid way of initializing the object, except for `= {0}`, as
2103 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2104 * though it's OK by the C standard. We could test for this, but we'd need
2105 * to supress the Clang warning for the test. */
2106 psa_hash_operation_t func = psa_hash_operation_init( );
2107 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2108 psa_hash_operation_t zero;
2109
2110 memset( &zero, 0, sizeof( zero ) );
2111
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002112 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002113 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2114 PSA_ERROR_BAD_STATE );
2115 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2116 PSA_ERROR_BAD_STATE );
2117 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2118 PSA_ERROR_BAD_STATE );
2119
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002120 /* A default hash operation should be abortable without error. */
2121 PSA_ASSERT( psa_hash_abort( &func ) );
2122 PSA_ASSERT( psa_hash_abort( &init ) );
2123 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002124}
2125/* END_CASE */
2126
2127/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002128void hash_setup( int alg_arg,
2129 int expected_status_arg )
2130{
2131 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002132 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002133 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002134 psa_status_t status;
2135
Gilles Peskine8817f612018-12-18 00:18:46 +01002136 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002137
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002138 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002139 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002140
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002141 /* Whether setup succeeded or failed, abort must succeed. */
2142 PSA_ASSERT( psa_hash_abort( &operation ) );
2143
2144 /* If setup failed, reproduce the failure, so as to
2145 * test the resulting state of the operation object. */
2146 if( status != PSA_SUCCESS )
2147 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2148
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002149 /* Now the operation object should be reusable. */
2150#if defined(KNOWN_SUPPORTED_HASH_ALG)
2151 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2152 PSA_ASSERT( psa_hash_abort( &operation ) );
2153#endif
2154
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002155exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002156 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002157}
2158/* END_CASE */
2159
2160/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002161void hash_bad_order( )
2162{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002163 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002164 unsigned char input[] = "";
2165 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002166 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002167 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2168 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2169 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002170 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002171 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002172 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002173
Gilles Peskine8817f612018-12-18 00:18:46 +01002174 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002175
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002176 /* Call setup twice in a row. */
2177 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2178 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2179 PSA_ERROR_BAD_STATE );
2180 PSA_ASSERT( psa_hash_abort( &operation ) );
2181
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002182 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002183 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002184 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002185 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002186
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002187 /* Call update after finish. */
2188 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2189 PSA_ASSERT( psa_hash_finish( &operation,
2190 hash, sizeof( hash ), &hash_len ) );
2191 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002192 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002193 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002194
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002195 /* Call verify without calling setup beforehand. */
2196 TEST_EQUAL( psa_hash_verify( &operation,
2197 valid_hash, sizeof( valid_hash ) ),
2198 PSA_ERROR_BAD_STATE );
2199 PSA_ASSERT( psa_hash_abort( &operation ) );
2200
2201 /* Call verify after finish. */
2202 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2203 PSA_ASSERT( psa_hash_finish( &operation,
2204 hash, sizeof( hash ), &hash_len ) );
2205 TEST_EQUAL( psa_hash_verify( &operation,
2206 valid_hash, sizeof( valid_hash ) ),
2207 PSA_ERROR_BAD_STATE );
2208 PSA_ASSERT( psa_hash_abort( &operation ) );
2209
2210 /* Call verify twice in a row. */
2211 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2212 PSA_ASSERT( psa_hash_verify( &operation,
2213 valid_hash, sizeof( valid_hash ) ) );
2214 TEST_EQUAL( psa_hash_verify( &operation,
2215 valid_hash, sizeof( valid_hash ) ),
2216 PSA_ERROR_BAD_STATE );
2217 PSA_ASSERT( psa_hash_abort( &operation ) );
2218
2219 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002220 TEST_EQUAL( psa_hash_finish( &operation,
2221 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002222 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002223 PSA_ASSERT( psa_hash_abort( &operation ) );
2224
2225 /* Call finish twice in a row. */
2226 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2227 PSA_ASSERT( psa_hash_finish( &operation,
2228 hash, sizeof( hash ), &hash_len ) );
2229 TEST_EQUAL( psa_hash_finish( &operation,
2230 hash, sizeof( hash ), &hash_len ),
2231 PSA_ERROR_BAD_STATE );
2232 PSA_ASSERT( psa_hash_abort( &operation ) );
2233
2234 /* Call finish after calling verify. */
2235 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2236 PSA_ASSERT( psa_hash_verify( &operation,
2237 valid_hash, sizeof( valid_hash ) ) );
2238 TEST_EQUAL( psa_hash_finish( &operation,
2239 hash, sizeof( hash ), &hash_len ),
2240 PSA_ERROR_BAD_STATE );
2241 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002242
2243exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002244 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002245}
2246/* END_CASE */
2247
itayzafrir27e69452018-11-01 14:26:34 +02002248/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2249void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002250{
2251 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002252 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2253 * appended to it */
2254 unsigned char hash[] = {
2255 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2256 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2257 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002258 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002259 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002260
Gilles Peskine8817f612018-12-18 00:18:46 +01002261 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002262
itayzafrir27e69452018-11-01 14:26:34 +02002263 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002264 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002265 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002266 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002267
itayzafrir27e69452018-11-01 14:26:34 +02002268 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002269 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002270 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002271 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002272
itayzafrir27e69452018-11-01 14:26:34 +02002273 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002274 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002275 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002276 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002277
itayzafrirec93d302018-10-18 18:01:10 +03002278exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002279 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002280}
2281/* END_CASE */
2282
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002283/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2284void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002285{
2286 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002287 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002288 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002289 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002290 size_t hash_len;
2291
Gilles Peskine8817f612018-12-18 00:18:46 +01002292 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002293
itayzafrir58028322018-10-25 10:22:01 +03002294 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002295 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002296 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002297 hash, expected_size - 1, &hash_len ),
2298 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002299
2300exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002301 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002302}
2303/* END_CASE */
2304
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002305/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2306void hash_clone_source_state( )
2307{
2308 psa_algorithm_t alg = PSA_ALG_SHA_256;
2309 unsigned char hash[PSA_HASH_MAX_SIZE];
2310 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2311 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2312 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2313 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2314 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2315 size_t hash_len;
2316
2317 PSA_ASSERT( psa_crypto_init( ) );
2318 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2319
2320 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2321 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2322 PSA_ASSERT( psa_hash_finish( &op_finished,
2323 hash, sizeof( hash ), &hash_len ) );
2324 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2325 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2326
2327 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2328 PSA_ERROR_BAD_STATE );
2329
2330 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2331 PSA_ASSERT( psa_hash_finish( &op_init,
2332 hash, sizeof( hash ), &hash_len ) );
2333 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2334 PSA_ASSERT( psa_hash_finish( &op_finished,
2335 hash, sizeof( hash ), &hash_len ) );
2336 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2337 PSA_ASSERT( psa_hash_finish( &op_aborted,
2338 hash, sizeof( hash ), &hash_len ) );
2339
2340exit:
2341 psa_hash_abort( &op_source );
2342 psa_hash_abort( &op_init );
2343 psa_hash_abort( &op_setup );
2344 psa_hash_abort( &op_finished );
2345 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002346 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002347}
2348/* END_CASE */
2349
2350/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2351void hash_clone_target_state( )
2352{
2353 psa_algorithm_t alg = PSA_ALG_SHA_256;
2354 unsigned char hash[PSA_HASH_MAX_SIZE];
2355 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2356 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2357 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2358 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2359 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2360 size_t hash_len;
2361
2362 PSA_ASSERT( psa_crypto_init( ) );
2363
2364 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2365 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2366 PSA_ASSERT( psa_hash_finish( &op_finished,
2367 hash, sizeof( hash ), &hash_len ) );
2368 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2369 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2370
2371 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2372 PSA_ASSERT( psa_hash_finish( &op_target,
2373 hash, sizeof( hash ), &hash_len ) );
2374
2375 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2376 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2377 PSA_ERROR_BAD_STATE );
2378 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2379 PSA_ERROR_BAD_STATE );
2380
2381exit:
2382 psa_hash_abort( &op_target );
2383 psa_hash_abort( &op_init );
2384 psa_hash_abort( &op_setup );
2385 psa_hash_abort( &op_finished );
2386 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002387 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002388}
2389/* END_CASE */
2390
itayzafrir58028322018-10-25 10:22:01 +03002391/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002392void mac_operation_init( )
2393{
Jaeden Amero252ef282019-02-15 14:05:35 +00002394 const uint8_t input[1] = { 0 };
2395
Jaeden Amero769ce272019-01-04 11:48:03 +00002396 /* Test each valid way of initializing the object, except for `= {0}`, as
2397 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2398 * though it's OK by the C standard. We could test for this, but we'd need
2399 * to supress the Clang warning for the test. */
2400 psa_mac_operation_t func = psa_mac_operation_init( );
2401 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2402 psa_mac_operation_t zero;
2403
2404 memset( &zero, 0, sizeof( zero ) );
2405
Jaeden Amero252ef282019-02-15 14:05:35 +00002406 /* A freshly-initialized MAC operation should not be usable. */
2407 TEST_EQUAL( psa_mac_update( &func,
2408 input, sizeof( input ) ),
2409 PSA_ERROR_BAD_STATE );
2410 TEST_EQUAL( psa_mac_update( &init,
2411 input, sizeof( input ) ),
2412 PSA_ERROR_BAD_STATE );
2413 TEST_EQUAL( psa_mac_update( &zero,
2414 input, sizeof( input ) ),
2415 PSA_ERROR_BAD_STATE );
2416
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002417 /* A default MAC operation should be abortable without error. */
2418 PSA_ASSERT( psa_mac_abort( &func ) );
2419 PSA_ASSERT( psa_mac_abort( &init ) );
2420 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002421}
2422/* END_CASE */
2423
2424/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002425void mac_setup( int key_type_arg,
2426 data_t *key,
2427 int alg_arg,
2428 int expected_status_arg )
2429{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002430 psa_key_type_t key_type = key_type_arg;
2431 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002432 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002433 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002434 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2435#if defined(KNOWN_SUPPORTED_MAC_ALG)
2436 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2437#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002438
Gilles Peskine8817f612018-12-18 00:18:46 +01002439 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002440
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002441 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2442 &operation, &status ) )
2443 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002444 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002445
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002446 /* The operation object should be reusable. */
2447#if defined(KNOWN_SUPPORTED_MAC_ALG)
2448 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2449 smoke_test_key_data,
2450 sizeof( smoke_test_key_data ),
2451 KNOWN_SUPPORTED_MAC_ALG,
2452 &operation, &status ) )
2453 goto exit;
2454 TEST_EQUAL( status, PSA_SUCCESS );
2455#endif
2456
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002457exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002458 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002459}
2460/* END_CASE */
2461
2462/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002463void mac_bad_order( )
2464{
2465 psa_key_handle_t handle = 0;
2466 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2467 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2468 const uint8_t key[] = {
2469 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2470 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2471 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002472 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002473 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2474 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2475 size_t sign_mac_length = 0;
2476 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2477 const uint8_t verify_mac[] = {
2478 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2479 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2480 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2481
2482 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002483 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2484 psa_set_key_algorithm( &attributes, alg );
2485 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002486
Gilles Peskine73676cb2019-05-15 20:15:10 +02002487 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002488
Jaeden Amero252ef282019-02-15 14:05:35 +00002489 /* Call update without calling setup beforehand. */
2490 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2491 PSA_ERROR_BAD_STATE );
2492 PSA_ASSERT( psa_mac_abort( &operation ) );
2493
2494 /* Call sign finish without calling setup beforehand. */
2495 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2496 &sign_mac_length),
2497 PSA_ERROR_BAD_STATE );
2498 PSA_ASSERT( psa_mac_abort( &operation ) );
2499
2500 /* Call verify finish without calling setup beforehand. */
2501 TEST_EQUAL( psa_mac_verify_finish( &operation,
2502 verify_mac, sizeof( verify_mac ) ),
2503 PSA_ERROR_BAD_STATE );
2504 PSA_ASSERT( psa_mac_abort( &operation ) );
2505
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002506 /* Call setup twice in a row. */
2507 PSA_ASSERT( psa_mac_sign_setup( &operation,
2508 handle, alg ) );
2509 TEST_EQUAL( psa_mac_sign_setup( &operation,
2510 handle, alg ),
2511 PSA_ERROR_BAD_STATE );
2512 PSA_ASSERT( psa_mac_abort( &operation ) );
2513
Jaeden Amero252ef282019-02-15 14:05:35 +00002514 /* Call update after sign finish. */
2515 PSA_ASSERT( psa_mac_sign_setup( &operation,
2516 handle, alg ) );
2517 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2518 PSA_ASSERT( psa_mac_sign_finish( &operation,
2519 sign_mac, sizeof( sign_mac ),
2520 &sign_mac_length ) );
2521 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2522 PSA_ERROR_BAD_STATE );
2523 PSA_ASSERT( psa_mac_abort( &operation ) );
2524
2525 /* Call update after verify finish. */
2526 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002527 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002528 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2529 PSA_ASSERT( psa_mac_verify_finish( &operation,
2530 verify_mac, sizeof( verify_mac ) ) );
2531 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2532 PSA_ERROR_BAD_STATE );
2533 PSA_ASSERT( psa_mac_abort( &operation ) );
2534
2535 /* Call sign finish twice in a row. */
2536 PSA_ASSERT( psa_mac_sign_setup( &operation,
2537 handle, alg ) );
2538 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2539 PSA_ASSERT( psa_mac_sign_finish( &operation,
2540 sign_mac, sizeof( sign_mac ),
2541 &sign_mac_length ) );
2542 TEST_EQUAL( psa_mac_sign_finish( &operation,
2543 sign_mac, sizeof( sign_mac ),
2544 &sign_mac_length ),
2545 PSA_ERROR_BAD_STATE );
2546 PSA_ASSERT( psa_mac_abort( &operation ) );
2547
2548 /* Call verify finish twice in a row. */
2549 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002550 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002551 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2552 PSA_ASSERT( psa_mac_verify_finish( &operation,
2553 verify_mac, sizeof( verify_mac ) ) );
2554 TEST_EQUAL( psa_mac_verify_finish( &operation,
2555 verify_mac, sizeof( verify_mac ) ),
2556 PSA_ERROR_BAD_STATE );
2557 PSA_ASSERT( psa_mac_abort( &operation ) );
2558
2559 /* Setup sign but try verify. */
2560 PSA_ASSERT( psa_mac_sign_setup( &operation,
2561 handle, alg ) );
2562 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2563 TEST_EQUAL( psa_mac_verify_finish( &operation,
2564 verify_mac, sizeof( verify_mac ) ),
2565 PSA_ERROR_BAD_STATE );
2566 PSA_ASSERT( psa_mac_abort( &operation ) );
2567
2568 /* Setup verify but try sign. */
2569 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002570 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002571 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2572 TEST_EQUAL( psa_mac_sign_finish( &operation,
2573 sign_mac, sizeof( sign_mac ),
2574 &sign_mac_length ),
2575 PSA_ERROR_BAD_STATE );
2576 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002577
Gilles Peskine76b29a72019-05-28 14:08:50 +02002578 PSA_ASSERT( psa_destroy_key( handle ) );
2579
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002580exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002581 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002582}
2583/* END_CASE */
2584
2585/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002586void mac_sign( int key_type_arg,
2587 data_t *key,
2588 int alg_arg,
2589 data_t *input,
2590 data_t *expected_mac )
2591{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002592 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002593 psa_key_type_t key_type = key_type_arg;
2594 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002595 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002596 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002597 /* Leave a little extra room in the output buffer. At the end of the
2598 * test, we'll check that the implementation didn't overwrite onto
2599 * this extra room. */
2600 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2601 size_t mac_buffer_size =
2602 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2603 size_t mac_length = 0;
2604
2605 memset( actual_mac, '+', sizeof( actual_mac ) );
2606 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2607 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2608
Gilles Peskine8817f612018-12-18 00:18:46 +01002609 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002610
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002611 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2612 psa_set_key_algorithm( &attributes, alg );
2613 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002614
Gilles Peskine73676cb2019-05-15 20:15:10 +02002615 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002616
2617 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002618 PSA_ASSERT( psa_mac_sign_setup( &operation,
2619 handle, alg ) );
2620 PSA_ASSERT( psa_mac_update( &operation,
2621 input->x, input->len ) );
2622 PSA_ASSERT( psa_mac_sign_finish( &operation,
2623 actual_mac, mac_buffer_size,
2624 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002625
2626 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002627 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2628 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002629
2630 /* Verify that the end of the buffer is untouched. */
2631 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2632 sizeof( actual_mac ) - mac_length ) );
2633
2634exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002635 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002636 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002637}
2638/* END_CASE */
2639
2640/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002641void mac_verify( int key_type_arg,
2642 data_t *key,
2643 int alg_arg,
2644 data_t *input,
2645 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002646{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002647 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002648 psa_key_type_t key_type = key_type_arg;
2649 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002650 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002651 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002652
Gilles Peskine69c12672018-06-28 00:07:19 +02002653 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2654
Gilles Peskine8817f612018-12-18 00:18:46 +01002655 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002656
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002657 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2658 psa_set_key_algorithm( &attributes, alg );
2659 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002660
Gilles Peskine73676cb2019-05-15 20:15:10 +02002661 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002662
Gilles Peskine8817f612018-12-18 00:18:46 +01002663 PSA_ASSERT( psa_mac_verify_setup( &operation,
2664 handle, alg ) );
2665 PSA_ASSERT( psa_destroy_key( handle ) );
2666 PSA_ASSERT( psa_mac_update( &operation,
2667 input->x, input->len ) );
2668 PSA_ASSERT( psa_mac_verify_finish( &operation,
2669 expected_mac->x,
2670 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002671
2672exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002673 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002674 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002675}
2676/* END_CASE */
2677
2678/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002679void cipher_operation_init( )
2680{
Jaeden Ameroab439972019-02-15 14:12:05 +00002681 const uint8_t input[1] = { 0 };
2682 unsigned char output[1] = { 0 };
2683 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002684 /* Test each valid way of initializing the object, except for `= {0}`, as
2685 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2686 * though it's OK by the C standard. We could test for this, but we'd need
2687 * to supress the Clang warning for the test. */
2688 psa_cipher_operation_t func = psa_cipher_operation_init( );
2689 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2690 psa_cipher_operation_t zero;
2691
2692 memset( &zero, 0, sizeof( zero ) );
2693
Jaeden Ameroab439972019-02-15 14:12:05 +00002694 /* A freshly-initialized cipher operation should not be usable. */
2695 TEST_EQUAL( psa_cipher_update( &func,
2696 input, sizeof( input ),
2697 output, sizeof( output ),
2698 &output_length ),
2699 PSA_ERROR_BAD_STATE );
2700 TEST_EQUAL( psa_cipher_update( &init,
2701 input, sizeof( input ),
2702 output, sizeof( output ),
2703 &output_length ),
2704 PSA_ERROR_BAD_STATE );
2705 TEST_EQUAL( psa_cipher_update( &zero,
2706 input, sizeof( input ),
2707 output, sizeof( output ),
2708 &output_length ),
2709 PSA_ERROR_BAD_STATE );
2710
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002711 /* A default cipher operation should be abortable without error. */
2712 PSA_ASSERT( psa_cipher_abort( &func ) );
2713 PSA_ASSERT( psa_cipher_abort( &init ) );
2714 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002715}
2716/* END_CASE */
2717
2718/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002719void cipher_setup( int key_type_arg,
2720 data_t *key,
2721 int alg_arg,
2722 int expected_status_arg )
2723{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002724 psa_key_type_t key_type = key_type_arg;
2725 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002726 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002727 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002728 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002729#if defined(KNOWN_SUPPORTED_MAC_ALG)
2730 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2731#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002732
Gilles Peskine8817f612018-12-18 00:18:46 +01002733 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002734
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002735 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2736 &operation, &status ) )
2737 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002738 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002739
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002740 /* The operation object should be reusable. */
2741#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2742 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2743 smoke_test_key_data,
2744 sizeof( smoke_test_key_data ),
2745 KNOWN_SUPPORTED_CIPHER_ALG,
2746 &operation, &status ) )
2747 goto exit;
2748 TEST_EQUAL( status, PSA_SUCCESS );
2749#endif
2750
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002751exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002752 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002753}
2754/* END_CASE */
2755
2756/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002757void cipher_bad_order( )
2758{
2759 psa_key_handle_t handle = 0;
2760 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2761 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002762 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002763 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2764 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2765 const uint8_t key[] = {
2766 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2767 0xaa, 0xaa, 0xaa, 0xaa };
2768 const uint8_t text[] = {
2769 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2770 0xbb, 0xbb, 0xbb, 0xbb };
2771 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2772 size_t length = 0;
2773
2774 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002775 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2776 psa_set_key_algorithm( &attributes, alg );
2777 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002778 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002779
2780
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002781 /* Call encrypt setup twice in a row. */
2782 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2783 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2784 PSA_ERROR_BAD_STATE );
2785 PSA_ASSERT( psa_cipher_abort( &operation ) );
2786
2787 /* Call decrypt setup twice in a row. */
2788 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2789 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2790 PSA_ERROR_BAD_STATE );
2791 PSA_ASSERT( psa_cipher_abort( &operation ) );
2792
Jaeden Ameroab439972019-02-15 14:12:05 +00002793 /* Generate an IV without calling setup beforehand. */
2794 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2795 buffer, sizeof( buffer ),
2796 &length ),
2797 PSA_ERROR_BAD_STATE );
2798 PSA_ASSERT( psa_cipher_abort( &operation ) );
2799
2800 /* Generate an IV twice in a row. */
2801 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2802 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2803 buffer, sizeof( buffer ),
2804 &length ) );
2805 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2806 buffer, sizeof( buffer ),
2807 &length ),
2808 PSA_ERROR_BAD_STATE );
2809 PSA_ASSERT( psa_cipher_abort( &operation ) );
2810
2811 /* Generate an IV after it's already set. */
2812 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2813 PSA_ASSERT( psa_cipher_set_iv( &operation,
2814 iv, sizeof( iv ) ) );
2815 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2816 buffer, sizeof( buffer ),
2817 &length ),
2818 PSA_ERROR_BAD_STATE );
2819 PSA_ASSERT( psa_cipher_abort( &operation ) );
2820
2821 /* Set an IV without calling setup beforehand. */
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 /* Set an IV after it's already set. */
2828 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2829 PSA_ASSERT( psa_cipher_set_iv( &operation,
2830 iv, sizeof( iv ) ) );
2831 TEST_EQUAL( psa_cipher_set_iv( &operation,
2832 iv, sizeof( iv ) ),
2833 PSA_ERROR_BAD_STATE );
2834 PSA_ASSERT( psa_cipher_abort( &operation ) );
2835
2836 /* Set an IV after it's already generated. */
2837 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2838 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2839 buffer, sizeof( buffer ),
2840 &length ) );
2841 TEST_EQUAL( psa_cipher_set_iv( &operation,
2842 iv, sizeof( iv ) ),
2843 PSA_ERROR_BAD_STATE );
2844 PSA_ASSERT( psa_cipher_abort( &operation ) );
2845
2846 /* Call update without calling setup beforehand. */
2847 TEST_EQUAL( psa_cipher_update( &operation,
2848 text, sizeof( text ),
2849 buffer, sizeof( buffer ),
2850 &length ),
2851 PSA_ERROR_BAD_STATE );
2852 PSA_ASSERT( psa_cipher_abort( &operation ) );
2853
2854 /* Call update without an IV where an IV is required. */
2855 TEST_EQUAL( psa_cipher_update( &operation,
2856 text, sizeof( text ),
2857 buffer, sizeof( buffer ),
2858 &length ),
2859 PSA_ERROR_BAD_STATE );
2860 PSA_ASSERT( psa_cipher_abort( &operation ) );
2861
2862 /* Call update after finish. */
2863 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2864 PSA_ASSERT( psa_cipher_set_iv( &operation,
2865 iv, sizeof( iv ) ) );
2866 PSA_ASSERT( psa_cipher_finish( &operation,
2867 buffer, sizeof( buffer ), &length ) );
2868 TEST_EQUAL( psa_cipher_update( &operation,
2869 text, sizeof( text ),
2870 buffer, sizeof( buffer ),
2871 &length ),
2872 PSA_ERROR_BAD_STATE );
2873 PSA_ASSERT( psa_cipher_abort( &operation ) );
2874
2875 /* Call finish without calling setup beforehand. */
2876 TEST_EQUAL( psa_cipher_finish( &operation,
2877 buffer, sizeof( buffer ), &length ),
2878 PSA_ERROR_BAD_STATE );
2879 PSA_ASSERT( psa_cipher_abort( &operation ) );
2880
2881 /* Call finish without an IV where an IV is required. */
2882 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2883 /* Not calling update means we are encrypting an empty buffer, which is OK
2884 * for cipher modes with padding. */
2885 TEST_EQUAL( psa_cipher_finish( &operation,
2886 buffer, sizeof( buffer ), &length ),
2887 PSA_ERROR_BAD_STATE );
2888 PSA_ASSERT( psa_cipher_abort( &operation ) );
2889
2890 /* Call finish twice in a row. */
2891 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2892 PSA_ASSERT( psa_cipher_set_iv( &operation,
2893 iv, sizeof( iv ) ) );
2894 PSA_ASSERT( psa_cipher_finish( &operation,
2895 buffer, sizeof( buffer ), &length ) );
2896 TEST_EQUAL( psa_cipher_finish( &operation,
2897 buffer, sizeof( buffer ), &length ),
2898 PSA_ERROR_BAD_STATE );
2899 PSA_ASSERT( psa_cipher_abort( &operation ) );
2900
Gilles Peskine76b29a72019-05-28 14:08:50 +02002901 PSA_ASSERT( psa_destroy_key( handle ) );
2902
Jaeden Ameroab439972019-02-15 14:12:05 +00002903exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002904 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002905}
2906/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002907
Gilles Peskine50e586b2018-06-08 14:28:46 +02002908/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002909void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002910 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002911 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002912 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002913{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002914 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002915 psa_status_t status;
2916 psa_key_type_t key_type = key_type_arg;
2917 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002918 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002919 unsigned char *output = NULL;
2920 size_t output_buffer_size = 0;
2921 size_t function_output_length = 0;
2922 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002923 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002924 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002925
Gilles Peskine8817f612018-12-18 00:18:46 +01002926 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002927
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002928 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2929 psa_set_key_algorithm( &attributes, alg );
2930 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002931
Gilles Peskine73676cb2019-05-15 20:15:10 +02002932 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933
Gilles Peskine8817f612018-12-18 00:18:46 +01002934 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2935 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002936
Gilles Peskine423005e2019-05-06 15:22:57 +02002937 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002938 output_buffer_size = ( (size_t) input->len +
2939 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002940 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002941
Gilles Peskine8817f612018-12-18 00:18:46 +01002942 PSA_ASSERT( psa_cipher_update( &operation,
2943 input->x, input->len,
2944 output, output_buffer_size,
2945 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002946 total_output_length += function_output_length;
2947 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002948 output + total_output_length,
2949 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002950 &function_output_length );
2951 total_output_length += function_output_length;
2952
Gilles Peskinefe11b722018-12-18 00:24:04 +01002953 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002954 if( expected_status == PSA_SUCCESS )
2955 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002956 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002957 ASSERT_COMPARE( expected_output->x, expected_output->len,
2958 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002959 }
2960
2961exit:
2962 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002963 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002964 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002965}
2966/* END_CASE */
2967
2968/* BEGIN_CASE */
2969void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002970 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002971 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002972 int first_part_size_arg,
2973 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002974 data_t *expected_output )
2975{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002976 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002977 psa_key_type_t key_type = key_type_arg;
2978 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002979 size_t first_part_size = first_part_size_arg;
2980 size_t output1_length = output1_length_arg;
2981 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002982 unsigned char *output = NULL;
2983 size_t output_buffer_size = 0;
2984 size_t function_output_length = 0;
2985 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002986 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002987 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002988
Gilles Peskine8817f612018-12-18 00:18:46 +01002989 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002990
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002991 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2992 psa_set_key_algorithm( &attributes, alg );
2993 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002994
Gilles Peskine73676cb2019-05-15 20:15:10 +02002995 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002996
Gilles Peskine8817f612018-12-18 00:18:46 +01002997 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2998 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002999
Gilles Peskine423005e2019-05-06 15:22:57 +02003000 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003001 output_buffer_size = ( (size_t) input->len +
3002 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003003 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003004
Gilles Peskinee0866522019-02-19 19:44:00 +01003005 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003006 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3007 output, output_buffer_size,
3008 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003009 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003010 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003011 PSA_ASSERT( psa_cipher_update( &operation,
3012 input->x + first_part_size,
3013 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003014 output + total_output_length,
3015 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003016 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003017 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003018 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003019 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003020 output + total_output_length,
3021 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003022 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003023 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003024 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003025
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003026 ASSERT_COMPARE( expected_output->x, expected_output->len,
3027 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003028
3029exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003030 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003031 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003032 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003033}
3034/* END_CASE */
3035
3036/* BEGIN_CASE */
3037void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003038 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003039 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003040 int first_part_size_arg,
3041 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003042 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003043{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003044 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003045
3046 psa_key_type_t key_type = key_type_arg;
3047 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003048 size_t first_part_size = first_part_size_arg;
3049 size_t output1_length = output1_length_arg;
3050 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003051 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003052 size_t output_buffer_size = 0;
3053 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003054 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003055 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003056 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003057
Gilles Peskine8817f612018-12-18 00:18:46 +01003058 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003059
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003060 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3061 psa_set_key_algorithm( &attributes, alg );
3062 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003063
Gilles Peskine73676cb2019-05-15 20:15:10 +02003064 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065
Gilles Peskine8817f612018-12-18 00:18:46 +01003066 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3067 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003068
Gilles Peskine423005e2019-05-06 15:22:57 +02003069 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003070
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003071 output_buffer_size = ( (size_t) input->len +
3072 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003073 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074
Gilles Peskinee0866522019-02-19 19:44:00 +01003075 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003076 PSA_ASSERT( psa_cipher_update( &operation,
3077 input->x, first_part_size,
3078 output, output_buffer_size,
3079 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003080 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003081 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003082 PSA_ASSERT( psa_cipher_update( &operation,
3083 input->x + first_part_size,
3084 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003085 output + total_output_length,
3086 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003087 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003088 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003089 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003090 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003091 output + total_output_length,
3092 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003093 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003094 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003095 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003096
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003097 ASSERT_COMPARE( expected_output->x, expected_output->len,
3098 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003099
3100exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003101 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003102 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003103 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003104}
3105/* END_CASE */
3106
Gilles Peskine50e586b2018-06-08 14:28:46 +02003107/* BEGIN_CASE */
3108void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003109 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003110 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003111 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003112{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003113 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003114 psa_status_t status;
3115 psa_key_type_t key_type = key_type_arg;
3116 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003117 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003118 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003119 size_t output_buffer_size = 0;
3120 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003121 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003122 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003123 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003124
Gilles Peskine8817f612018-12-18 00:18:46 +01003125 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003126
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003127 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3128 psa_set_key_algorithm( &attributes, alg );
3129 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003130
Gilles Peskine73676cb2019-05-15 20:15:10 +02003131 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003132
Gilles Peskine8817f612018-12-18 00:18:46 +01003133 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3134 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003135
Gilles Peskine423005e2019-05-06 15:22:57 +02003136 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003137
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003138 output_buffer_size = ( (size_t) input->len +
3139 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003140 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003141
Gilles Peskine8817f612018-12-18 00:18:46 +01003142 PSA_ASSERT( psa_cipher_update( &operation,
3143 input->x, input->len,
3144 output, output_buffer_size,
3145 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003146 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003147 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003148 output + total_output_length,
3149 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003150 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003151 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003152 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003153
3154 if( expected_status == PSA_SUCCESS )
3155 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003156 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003157 ASSERT_COMPARE( expected_output->x, expected_output->len,
3158 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003159 }
3160
Gilles Peskine50e586b2018-06-08 14:28:46 +02003161exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003162 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003163 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003164 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003165}
3166/* END_CASE */
3167
Gilles Peskine50e586b2018-06-08 14:28:46 +02003168/* BEGIN_CASE */
3169void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003170 data_t *key,
3171 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003172{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003173 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003174 psa_key_type_t key_type = key_type_arg;
3175 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003176 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003177 size_t iv_size = 16;
3178 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003179 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003180 size_t output1_size = 0;
3181 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003182 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003183 size_t output2_size = 0;
3184 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003185 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003186 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3187 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003188 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003189
Gilles Peskine8817f612018-12-18 00:18:46 +01003190 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003191
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003192 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3193 psa_set_key_algorithm( &attributes, alg );
3194 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003195
Gilles Peskine73676cb2019-05-15 20:15:10 +02003196 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003197
Gilles Peskine8817f612018-12-18 00:18:46 +01003198 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3199 handle, alg ) );
3200 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3201 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003202
Gilles Peskine8817f612018-12-18 00:18:46 +01003203 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3204 iv, iv_size,
3205 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003206 output1_size = ( (size_t) input->len +
3207 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003208 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003209
Gilles Peskine8817f612018-12-18 00:18:46 +01003210 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3211 output1, output1_size,
3212 &output1_length ) );
3213 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003214 output1 + output1_length,
3215 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003216 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003217
Gilles Peskine048b7f02018-06-08 14:20:49 +02003218 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003219
Gilles Peskine8817f612018-12-18 00:18:46 +01003220 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003221
3222 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003223 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003224
Gilles Peskine8817f612018-12-18 00:18:46 +01003225 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3226 iv, iv_length ) );
3227 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3228 output2, output2_size,
3229 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003230 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003231 PSA_ASSERT( psa_cipher_finish( &operation2,
3232 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003233 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003234 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003235
Gilles Peskine048b7f02018-06-08 14:20:49 +02003236 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003237
Gilles Peskine8817f612018-12-18 00:18:46 +01003238 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003239
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003240 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003241
3242exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003243 mbedtls_free( output1 );
3244 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003245 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003246 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003247}
3248/* END_CASE */
3249
3250/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003251void cipher_verify_output_multipart( int alg_arg,
3252 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003253 data_t *key,
3254 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003255 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003256{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003257 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003258 psa_key_type_t key_type = key_type_arg;
3259 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003260 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003261 unsigned char iv[16] = {0};
3262 size_t iv_size = 16;
3263 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003264 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003265 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003266 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003267 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003268 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003269 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003270 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003271 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3272 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003273 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003274
Gilles Peskine8817f612018-12-18 00:18:46 +01003275 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003276
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003277 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3278 psa_set_key_algorithm( &attributes, alg );
3279 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003280
Gilles Peskine73676cb2019-05-15 20:15:10 +02003281 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003282
Gilles Peskine8817f612018-12-18 00:18:46 +01003283 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3284 handle, alg ) );
3285 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3286 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003287
Gilles Peskine8817f612018-12-18 00:18:46 +01003288 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3289 iv, iv_size,
3290 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003291 output1_buffer_size = ( (size_t) input->len +
3292 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003293 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003294
Gilles Peskinee0866522019-02-19 19:44:00 +01003295 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003296
Gilles Peskine8817f612018-12-18 00:18:46 +01003297 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3298 output1, output1_buffer_size,
3299 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003300 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003301
Gilles Peskine8817f612018-12-18 00:18:46 +01003302 PSA_ASSERT( psa_cipher_update( &operation1,
3303 input->x + first_part_size,
3304 input->len - first_part_size,
3305 output1, output1_buffer_size,
3306 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003307 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003308
Gilles Peskine8817f612018-12-18 00:18:46 +01003309 PSA_ASSERT( psa_cipher_finish( &operation1,
3310 output1 + output1_length,
3311 output1_buffer_size - output1_length,
3312 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003313 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003314
Gilles Peskine8817f612018-12-18 00:18:46 +01003315 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003316
Gilles Peskine048b7f02018-06-08 14:20:49 +02003317 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003318 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003319
Gilles Peskine8817f612018-12-18 00:18:46 +01003320 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3321 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003322
Gilles Peskine8817f612018-12-18 00:18:46 +01003323 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3324 output2, output2_buffer_size,
3325 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003326 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003327
Gilles Peskine8817f612018-12-18 00:18:46 +01003328 PSA_ASSERT( psa_cipher_update( &operation2,
3329 output1 + first_part_size,
3330 output1_length - first_part_size,
3331 output2, output2_buffer_size,
3332 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003333 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003334
Gilles Peskine8817f612018-12-18 00:18:46 +01003335 PSA_ASSERT( psa_cipher_finish( &operation2,
3336 output2 + output2_length,
3337 output2_buffer_size - output2_length,
3338 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003339 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003340
Gilles Peskine8817f612018-12-18 00:18:46 +01003341 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003342
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003343 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003344
3345exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003346 mbedtls_free( output1 );
3347 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003348 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003349 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003350}
3351/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003352
Gilles Peskine20035e32018-02-03 22:44:14 +01003353/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003354void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003355 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003356 data_t *nonce,
3357 data_t *additional_data,
3358 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003359 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003360{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003361 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003362 psa_key_type_t key_type = key_type_arg;
3363 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003364 unsigned char *output_data = NULL;
3365 size_t output_size = 0;
3366 size_t output_length = 0;
3367 unsigned char *output_data2 = NULL;
3368 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003369 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003370 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003371 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003372
Gilles Peskine4abf7412018-06-18 16:35:34 +02003373 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003374 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3375 * should be exact. */
3376 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3377 TEST_EQUAL( output_size,
3378 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003379 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003380
Gilles Peskine8817f612018-12-18 00:18:46 +01003381 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003382
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003383 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3384 psa_set_key_algorithm( &attributes, alg );
3385 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003386
Gilles Peskine049c7532019-05-15 20:22:09 +02003387 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3388 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003389
Gilles Peskinefe11b722018-12-18 00:24:04 +01003390 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3391 nonce->x, nonce->len,
3392 additional_data->x,
3393 additional_data->len,
3394 input_data->x, input_data->len,
3395 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003396 &output_length ),
3397 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398
3399 if( PSA_SUCCESS == expected_result )
3400 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003401 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003402
Gilles Peskine003a4a92019-05-14 16:09:40 +02003403 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3404 * should be exact. */
3405 TEST_EQUAL( input_data->len,
3406 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3407
Gilles Peskinefe11b722018-12-18 00:24:04 +01003408 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3409 nonce->x, nonce->len,
3410 additional_data->x,
3411 additional_data->len,
3412 output_data, output_length,
3413 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003414 &output_length2 ),
3415 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003416
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003417 ASSERT_COMPARE( input_data->x, input_data->len,
3418 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003419 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003420
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003422 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003423 mbedtls_free( output_data );
3424 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003425 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003426}
3427/* END_CASE */
3428
3429/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003430void aead_encrypt( int key_type_arg, data_t *key_data,
3431 int alg_arg,
3432 data_t *nonce,
3433 data_t *additional_data,
3434 data_t *input_data,
3435 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003436{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003437 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003438 psa_key_type_t key_type = key_type_arg;
3439 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003440 unsigned char *output_data = NULL;
3441 size_t output_size = 0;
3442 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003443 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003444 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003445
Gilles Peskine4abf7412018-06-18 16:35:34 +02003446 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003447 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3448 * should be exact. */
3449 TEST_EQUAL( output_size,
3450 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003451 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003452
Gilles Peskine8817f612018-12-18 00:18:46 +01003453 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003454
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003455 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3456 psa_set_key_algorithm( &attributes, alg );
3457 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003458
Gilles Peskine049c7532019-05-15 20:22:09 +02003459 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3460 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003461
Gilles Peskine8817f612018-12-18 00:18:46 +01003462 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3463 nonce->x, nonce->len,
3464 additional_data->x, additional_data->len,
3465 input_data->x, input_data->len,
3466 output_data, output_size,
3467 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003468
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003469 ASSERT_COMPARE( expected_result->x, expected_result->len,
3470 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003471
Gilles Peskinea1cac842018-06-11 19:33:02 +02003472exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003473 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003474 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003475 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003476}
3477/* END_CASE */
3478
3479/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003480void aead_decrypt( int key_type_arg, data_t *key_data,
3481 int alg_arg,
3482 data_t *nonce,
3483 data_t *additional_data,
3484 data_t *input_data,
3485 data_t *expected_data,
3486 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003487{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003488 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003489 psa_key_type_t key_type = key_type_arg;
3490 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003491 unsigned char *output_data = NULL;
3492 size_t output_size = 0;
3493 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003494 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003495 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003496 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003497
Gilles Peskine003a4a92019-05-14 16:09:40 +02003498 output_size = input_data->len - tag_length;
3499 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3500 * should be exact. */
3501 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3502 TEST_EQUAL( output_size,
3503 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003504 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003505
Gilles Peskine8817f612018-12-18 00:18:46 +01003506 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003507
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003508 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3509 psa_set_key_algorithm( &attributes, alg );
3510 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003511
Gilles Peskine049c7532019-05-15 20:22:09 +02003512 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3513 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003514
Gilles Peskinefe11b722018-12-18 00:24:04 +01003515 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3516 nonce->x, nonce->len,
3517 additional_data->x,
3518 additional_data->len,
3519 input_data->x, input_data->len,
3520 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003521 &output_length ),
3522 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003523
Gilles Peskine2d277862018-06-18 15:41:12 +02003524 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003525 ASSERT_COMPARE( expected_data->x, expected_data->len,
3526 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003527
Gilles Peskinea1cac842018-06-11 19:33:02 +02003528exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003529 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003530 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003531 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003532}
3533/* END_CASE */
3534
3535/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003536void signature_size( int type_arg,
3537 int bits,
3538 int alg_arg,
3539 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003540{
3541 psa_key_type_t type = type_arg;
3542 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003543 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003544 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003545exit:
3546 ;
3547}
3548/* END_CASE */
3549
3550/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003551void sign_deterministic( int key_type_arg, data_t *key_data,
3552 int alg_arg, data_t *input_data,
3553 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003554{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003555 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003556 psa_key_type_t key_type = key_type_arg;
3557 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003558 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003559 unsigned char *signature = NULL;
3560 size_t signature_size;
3561 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003562 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003563
Gilles Peskine8817f612018-12-18 00:18:46 +01003564 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003565
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003566 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3567 psa_set_key_algorithm( &attributes, alg );
3568 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003569
Gilles Peskine049c7532019-05-15 20:22:09 +02003570 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3571 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003572 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3573 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003574
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003575 /* Allocate a buffer which has the size advertized by the
3576 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003577 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3578 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003579 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003580 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003581 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003582
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003583 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003584 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3585 input_data->x, input_data->len,
3586 signature, signature_size,
3587 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003588 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003589 ASSERT_COMPARE( output_data->x, output_data->len,
3590 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003591
3592exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003593 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003594 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003595 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003596 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003597}
3598/* END_CASE */
3599
3600/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003601void sign_fail( int key_type_arg, data_t *key_data,
3602 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003603 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003604{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003605 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003606 psa_key_type_t key_type = key_type_arg;
3607 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003608 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003609 psa_status_t actual_status;
3610 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003611 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003612 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003613 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003614
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003615 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003616
Gilles Peskine8817f612018-12-18 00:18:46 +01003617 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003618
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003619 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3620 psa_set_key_algorithm( &attributes, alg );
3621 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003622
Gilles Peskine049c7532019-05-15 20:22:09 +02003623 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3624 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003625
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003626 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003627 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003628 signature, signature_size,
3629 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003630 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003631 /* The value of *signature_length is unspecified on error, but
3632 * whatever it is, it should be less than signature_size, so that
3633 * if the caller tries to read *signature_length bytes without
3634 * checking the error code then they don't overflow a buffer. */
3635 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003636
3637exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003638 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003639 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003640 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003641 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003642}
3643/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003644
3645/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003646void sign_verify( int key_type_arg, data_t *key_data,
3647 int alg_arg, data_t *input_data )
3648{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003649 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003650 psa_key_type_t key_type = key_type_arg;
3651 psa_algorithm_t alg = alg_arg;
3652 size_t key_bits;
3653 unsigned char *signature = NULL;
3654 size_t signature_size;
3655 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003656 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003657
Gilles Peskine8817f612018-12-18 00:18:46 +01003658 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003659
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003660 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3661 psa_set_key_algorithm( &attributes, alg );
3662 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003663
Gilles Peskine049c7532019-05-15 20:22:09 +02003664 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3665 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003666 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3667 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003668
3669 /* Allocate a buffer which has the size advertized by the
3670 * library. */
3671 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3672 key_bits, alg );
3673 TEST_ASSERT( signature_size != 0 );
3674 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003675 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003676
3677 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003678 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3679 input_data->x, input_data->len,
3680 signature, signature_size,
3681 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003682 /* Check that the signature length looks sensible. */
3683 TEST_ASSERT( signature_length <= signature_size );
3684 TEST_ASSERT( signature_length > 0 );
3685
3686 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003687 PSA_ASSERT( psa_asymmetric_verify(
3688 handle, alg,
3689 input_data->x, input_data->len,
3690 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003691
3692 if( input_data->len != 0 )
3693 {
3694 /* Flip a bit in the input and verify that the signature is now
3695 * detected as invalid. Flip a bit at the beginning, not at the end,
3696 * because ECDSA may ignore the last few bits of the input. */
3697 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003698 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3699 input_data->x, input_data->len,
3700 signature, signature_length ),
3701 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003702 }
3703
3704exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003705 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003706 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003707 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003708 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003709}
3710/* END_CASE */
3711
3712/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003713void asymmetric_verify( int key_type_arg, data_t *key_data,
3714 int alg_arg, data_t *hash_data,
3715 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003716{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003717 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003718 psa_key_type_t key_type = key_type_arg;
3719 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003720 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003721
Gilles Peskine69c12672018-06-28 00:07:19 +02003722 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3723
Gilles Peskine8817f612018-12-18 00:18:46 +01003724 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003725
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003726 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3727 psa_set_key_algorithm( &attributes, alg );
3728 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003729
Gilles Peskine049c7532019-05-15 20:22:09 +02003730 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3731 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003732
Gilles Peskine8817f612018-12-18 00:18:46 +01003733 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3734 hash_data->x, hash_data->len,
3735 signature_data->x,
3736 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003737exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003738 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003739 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003740 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003741}
3742/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003743
3744/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003745void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3746 int alg_arg, data_t *hash_data,
3747 data_t *signature_data,
3748 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003749{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003750 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003751 psa_key_type_t key_type = key_type_arg;
3752 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003753 psa_status_t actual_status;
3754 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003755 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003756
Gilles Peskine8817f612018-12-18 00:18:46 +01003757 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003758
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003759 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3760 psa_set_key_algorithm( &attributes, alg );
3761 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003762
Gilles Peskine049c7532019-05-15 20:22:09 +02003763 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3764 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003765
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003766 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003767 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003768 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003769 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003770
Gilles Peskinefe11b722018-12-18 00:24:04 +01003771 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003772
3773exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003774 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003775 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003776 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003777}
3778/* END_CASE */
3779
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003780/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003781void asymmetric_encrypt( int key_type_arg,
3782 data_t *key_data,
3783 int alg_arg,
3784 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003785 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003786 int expected_output_length_arg,
3787 int expected_status_arg )
3788{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003789 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003790 psa_key_type_t key_type = key_type_arg;
3791 psa_algorithm_t alg = alg_arg;
3792 size_t expected_output_length = expected_output_length_arg;
3793 size_t key_bits;
3794 unsigned char *output = NULL;
3795 size_t output_size;
3796 size_t output_length = ~0;
3797 psa_status_t actual_status;
3798 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003799 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003800
Gilles Peskine8817f612018-12-18 00:18:46 +01003801 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003802
Gilles Peskine656896e2018-06-29 19:12:28 +02003803 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003804 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3805 psa_set_key_algorithm( &attributes, alg );
3806 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003807 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3808 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003809
3810 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003811 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3812 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003813 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003814 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003815
3816 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003817 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003818 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003819 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003820 output, output_size,
3821 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003822 TEST_EQUAL( actual_status, expected_status );
3823 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003824
Gilles Peskine68428122018-06-30 18:42:41 +02003825 /* If the label is empty, the test framework puts a non-null pointer
3826 * in label->x. Test that a null pointer works as well. */
3827 if( label->len == 0 )
3828 {
3829 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003830 if( output_size != 0 )
3831 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003832 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003833 input_data->x, input_data->len,
3834 NULL, label->len,
3835 output, output_size,
3836 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003837 TEST_EQUAL( actual_status, expected_status );
3838 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003839 }
3840
Gilles Peskine656896e2018-06-29 19:12:28 +02003841exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003842 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003843 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003844 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003845 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02003846}
3847/* END_CASE */
3848
3849/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003850void asymmetric_encrypt_decrypt( int key_type_arg,
3851 data_t *key_data,
3852 int alg_arg,
3853 data_t *input_data,
3854 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003855{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003856 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003857 psa_key_type_t key_type = key_type_arg;
3858 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003859 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003860 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003861 size_t output_size;
3862 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003863 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003864 size_t output2_size;
3865 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003866 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003867
Gilles Peskine8817f612018-12-18 00:18:46 +01003868 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003869
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003870 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3871 psa_set_key_algorithm( &attributes, alg );
3872 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003873
Gilles Peskine049c7532019-05-15 20:22:09 +02003874 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3875 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003876
3877 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003878 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3879 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003880 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003881 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003882 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003883 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003884
Gilles Peskineeebd7382018-06-08 18:11:54 +02003885 /* We test encryption by checking that encrypt-then-decrypt gives back
3886 * the original plaintext because of the non-optional random
3887 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003888 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3889 input_data->x, input_data->len,
3890 label->x, label->len,
3891 output, output_size,
3892 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003893 /* We don't know what ciphertext length to expect, but check that
3894 * it looks sensible. */
3895 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003896
Gilles Peskine8817f612018-12-18 00:18:46 +01003897 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3898 output, output_length,
3899 label->x, label->len,
3900 output2, output2_size,
3901 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003902 ASSERT_COMPARE( input_data->x, input_data->len,
3903 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003904
3905exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003906 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003907 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003908 mbedtls_free( output );
3909 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003910 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003911}
3912/* END_CASE */
3913
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003914/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003915void asymmetric_decrypt( int key_type_arg,
3916 data_t *key_data,
3917 int alg_arg,
3918 data_t *input_data,
3919 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003920 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003921{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003922 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003923 psa_key_type_t key_type = key_type_arg;
3924 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003925 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003926 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003927 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003928 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003929
Jaeden Amero412654a2019-02-06 12:57:46 +00003930 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003931 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003932
Gilles Peskine8817f612018-12-18 00:18:46 +01003933 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003934
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003935 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3936 psa_set_key_algorithm( &attributes, alg );
3937 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003938
Gilles Peskine049c7532019-05-15 20:22:09 +02003939 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3940 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003941
Gilles Peskine8817f612018-12-18 00:18:46 +01003942 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3943 input_data->x, input_data->len,
3944 label->x, label->len,
3945 output,
3946 output_size,
3947 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003948 ASSERT_COMPARE( expected_data->x, expected_data->len,
3949 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003950
Gilles Peskine68428122018-06-30 18:42:41 +02003951 /* If the label is empty, the test framework puts a non-null pointer
3952 * in label->x. Test that a null pointer works as well. */
3953 if( label->len == 0 )
3954 {
3955 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003956 if( output_size != 0 )
3957 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003958 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3959 input_data->x, input_data->len,
3960 NULL, label->len,
3961 output,
3962 output_size,
3963 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003964 ASSERT_COMPARE( expected_data->x, expected_data->len,
3965 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003966 }
3967
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003968exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003969 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003970 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003971 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003972 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003973}
3974/* END_CASE */
3975
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003976/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003977void asymmetric_decrypt_fail( int key_type_arg,
3978 data_t *key_data,
3979 int alg_arg,
3980 data_t *input_data,
3981 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003982 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003983 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003984{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003985 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003986 psa_key_type_t key_type = key_type_arg;
3987 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003988 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003989 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003990 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003991 psa_status_t actual_status;
3992 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003993 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003994
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003995 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003996
Gilles Peskine8817f612018-12-18 00:18:46 +01003997 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003998
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003999 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4000 psa_set_key_algorithm( &attributes, alg );
4001 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004002
Gilles Peskine049c7532019-05-15 20:22:09 +02004003 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4004 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004005
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004006 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004007 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004008 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004009 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004010 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004011 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004012 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004013
Gilles Peskine68428122018-06-30 18:42:41 +02004014 /* If the label is empty, the test framework puts a non-null pointer
4015 * in label->x. Test that a null pointer works as well. */
4016 if( label->len == 0 )
4017 {
4018 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004019 if( output_size != 0 )
4020 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004021 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004022 input_data->x, input_data->len,
4023 NULL, label->len,
4024 output, output_size,
4025 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004026 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004027 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004028 }
4029
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004030exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004031 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004032 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004033 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004034 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004035}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004036/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004037
4038/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004039void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004040{
4041 /* Test each valid way of initializing the object, except for `= {0}`, as
4042 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4043 * though it's OK by the C standard. We could test for this, but we'd need
4044 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004045 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004046 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4047 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4048 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004049
4050 memset( &zero, 0, sizeof( zero ) );
4051
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004052 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004053 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004054 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004055 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004056 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004057 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004058 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004059
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004060 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004061 PSA_ASSERT( psa_key_derivation_abort(&func) );
4062 PSA_ASSERT( psa_key_derivation_abort(&init) );
4063 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004064}
4065/* END_CASE */
4066
Janos Follath16de4a42019-06-13 16:32:24 +01004067/* BEGIN_CASE */
4068void derive_setup( int alg_arg, int expected_status_arg )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004069{
Gilles Peskineea0fb492018-07-12 17:17:20 +02004070 psa_algorithm_t alg = alg_arg;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004071 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004072 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004073
Gilles Peskine8817f612018-12-18 00:18:46 +01004074 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004075
Janos Follath16de4a42019-06-13 16:32:24 +01004076 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004077 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004078
4079exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004080 psa_key_derivation_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004081 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004082}
4083/* END_CASE */
4084
Janos Follathaf3c2a02019-06-12 12:34:34 +01004085/* BEGIN_CASE */
Janos Follatha27c9272019-06-14 09:59:36 +01004086void derive_set_capacity( int alg_arg, int capacity_arg,
4087 int expected_status_arg )
4088{
4089 psa_algorithm_t alg = alg_arg;
4090 size_t capacity = capacity_arg;
4091 psa_status_t expected_status = expected_status_arg;
4092 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4093
4094 PSA_ASSERT( psa_crypto_init( ) );
4095
4096 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4097
4098 TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
4099 expected_status );
4100
4101exit:
4102 psa_key_derivation_abort( &operation );
4103 PSA_DONE( );
4104}
4105/* END_CASE */
4106
4107/* BEGIN_CASE */
Janos Follathaf3c2a02019-06-12 12:34:34 +01004108void derive_input( int alg_arg,
4109 int key_type_arg,
4110 int step1_arg, data_t *input1,
4111 int step2_arg, data_t *input2,
4112 int step3_arg, data_t *input3,
4113 int expected_status_arg1,
4114 int expected_status_arg2,
4115 int expected_status_arg3 )
4116{
4117 psa_algorithm_t alg = alg_arg;
4118 size_t key_type = key_type_arg;
4119 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4120 psa_status_t expected_statuses[] = {expected_status_arg1,
4121 expected_status_arg2,
4122 expected_status_arg3};
4123 data_t *inputs[] = {input1, input2, input3};
4124 psa_key_handle_t handles[] = {0, 0, 0};
4125 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4126 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4127 size_t i;
4128
4129 PSA_ASSERT( psa_crypto_init( ) );
4130
4131 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4132 psa_set_key_algorithm( &attributes, alg );
4133 psa_set_key_type( &attributes, key_type );
4134
4135 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4136
4137 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
4138 {
4139 switch( steps[i] )
4140 {
4141 case PSA_KEY_DERIVATION_INPUT_SECRET:
4142 PSA_ASSERT( psa_import_key( &attributes,
4143 inputs[i]->x, inputs[i]->len,
4144 &handles[i] ) );
4145 TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
4146 handles[i] ),
4147 expected_statuses[i] );
4148 break;
4149 default:
4150 TEST_EQUAL( psa_key_derivation_input_bytes(
4151 &operation, steps[i],
4152 inputs[i]->x, inputs[i]->len ),
4153 expected_statuses[i] );
4154 break;
4155 }
4156 }
4157
4158exit:
4159 psa_key_derivation_abort( &operation );
4160 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4161 psa_destroy_key( handles[i] );
4162 PSA_DONE( );
4163}
4164/* END_CASE */
4165
Janos Follath71a4c912019-06-11 09:14:47 +01004166/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004167void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004168{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004169 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004170 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004171 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004172 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004173 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004174 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004175 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4176 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4177 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004178 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004179
Gilles Peskine8817f612018-12-18 00:18:46 +01004180 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004181
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004182 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4183 psa_set_key_algorithm( &attributes, alg );
4184 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004185
Gilles Peskine73676cb2019-05-15 20:15:10 +02004186 PSA_ASSERT( psa_import_key( &attributes,
4187 key_data, sizeof( key_data ),
4188 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004189
4190 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004191 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004192 NULL, 0,
4193 NULL, 0,
4194 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004195
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004196 /* state of operation shouldn't allow additional generation */
4197 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004198 NULL, 0,
4199 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004200 capacity ),
4201 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004202
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004203 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004204
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004205 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004206 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004207
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004208exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004209 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004210 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004211 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004212}
4213/* END_CASE */
4214
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004215/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004216void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004217{
4218 uint8_t output_buffer[16];
4219 size_t buffer_size = 16;
4220 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004221 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004222
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004223 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4224 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004225 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004226
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004227 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004228 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004229
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004230 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004231
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004232 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4233 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004234 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004235
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004236 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004237 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004238
4239exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004240 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004241}
4242/* END_CASE */
4243
4244/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004245void derive_output( int alg_arg,
Gilles Peskine1468da72019-05-29 17:35:49 +02004246 int step1_arg, data_t *input1,
4247 int step2_arg, data_t *input2,
4248 int step3_arg, data_t *input3,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004249 int requested_capacity_arg,
4250 data_t *expected_output1,
4251 data_t *expected_output2 )
4252{
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004253 psa_algorithm_t alg = alg_arg;
Gilles Peskine1468da72019-05-29 17:35:49 +02004254 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4255 data_t *inputs[] = {input1, input2, input3};
4256 psa_key_handle_t handles[] = {0, 0, 0};
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004257 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004258 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004259 uint8_t *expected_outputs[2] =
4260 {expected_output1->x, expected_output2->x};
4261 size_t output_sizes[2] =
4262 {expected_output1->len, expected_output2->len};
4263 size_t output_buffer_size = 0;
4264 uint8_t *output_buffer = NULL;
4265 size_t expected_capacity;
4266 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004267 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004268 psa_status_t status;
Gilles Peskine1468da72019-05-29 17:35:49 +02004269 size_t i;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004270
4271 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4272 {
4273 if( output_sizes[i] > output_buffer_size )
4274 output_buffer_size = output_sizes[i];
4275 if( output_sizes[i] == 0 )
4276 expected_outputs[i] = NULL;
4277 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004278 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004279 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004280
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004281 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4282 psa_set_key_algorithm( &attributes, alg );
4283 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004284
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004285 /* Extraction phase. */
Gilles Peskine1468da72019-05-29 17:35:49 +02004286 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4287 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4288 requested_capacity ) );
4289 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004290 {
Gilles Peskine1468da72019-05-29 17:35:49 +02004291 switch( steps[i] )
4292 {
4293 case 0:
4294 break;
4295 case PSA_KEY_DERIVATION_INPUT_SECRET:
4296 PSA_ASSERT( psa_import_key( &attributes,
4297 inputs[i]->x, inputs[i]->len,
4298 &handles[i] ) );
4299 PSA_ASSERT( psa_key_derivation_input_key(
4300 &operation, steps[i],
4301 handles[i] ) );
4302 break;
4303 default:
4304 PSA_ASSERT( psa_key_derivation_input_bytes(
4305 &operation, steps[i],
4306 inputs[i]->x, inputs[i]->len ) );
4307 break;
4308 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004309 }
Gilles Peskine1468da72019-05-29 17:35:49 +02004310
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004311 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004312 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004313 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004314 expected_capacity = requested_capacity;
4315
4316 /* Expansion phase. */
4317 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4318 {
4319 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004320 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004321 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004322 if( expected_capacity == 0 && output_sizes[i] == 0 )
4323 {
4324 /* Reading 0 bytes when 0 bytes are available can go either way. */
4325 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004326 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004327 continue;
4328 }
4329 else if( expected_capacity == 0 ||
4330 output_sizes[i] > expected_capacity )
4331 {
4332 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004333 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004334 expected_capacity = 0;
4335 continue;
4336 }
4337 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004338 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004339 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004340 ASSERT_COMPARE( output_buffer, output_sizes[i],
4341 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004342 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004343 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004344 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004345 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004346 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004347 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004348 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004349
4350exit:
4351 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004352 psa_key_derivation_abort( &operation );
Gilles Peskine1468da72019-05-29 17:35:49 +02004353 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4354 psa_destroy_key( handles[i] );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004355 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004356}
4357/* END_CASE */
4358
4359/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004360void derive_full( int alg_arg,
4361 data_t *key_data,
Janos Follath47f27ed2019-06-25 13:24:52 +01004362 data_t *input1,
4363 data_t *input2,
Gilles Peskined54931c2018-07-17 21:06:59 +02004364 int requested_capacity_arg )
4365{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004366 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004367 psa_algorithm_t alg = alg_arg;
4368 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004369 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004370 unsigned char output_buffer[16];
4371 size_t expected_capacity = requested_capacity;
4372 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004373 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004374
Gilles Peskine8817f612018-12-18 00:18:46 +01004375 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004376
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004377 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4378 psa_set_key_algorithm( &attributes, alg );
4379 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004380
Gilles Peskine049c7532019-05-15 20:22:09 +02004381 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4382 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004383
Janos Follathf2815ea2019-07-03 12:41:36 +01004384 if( !setup_key_derivation_wrap( &operation, handle, alg,
4385 input1->x, input1->len,
4386 input2->x, input2->len,
4387 requested_capacity ) )
4388 goto exit;
Janos Follath47f27ed2019-06-25 13:24:52 +01004389
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004390 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004391 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004392 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004393
4394 /* Expansion phase. */
4395 while( current_capacity > 0 )
4396 {
4397 size_t read_size = sizeof( output_buffer );
4398 if( read_size > current_capacity )
4399 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004400 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004401 output_buffer,
4402 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004403 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004404 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004405 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004406 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004407 }
4408
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004409 /* Check that the operation refuses to go over capacity. */
4410 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004411 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004412
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004413 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004414
4415exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004416 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004417 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004418 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004419}
4420/* END_CASE */
4421
Janos Follath71a4c912019-06-11 09:14:47 +01004422/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004423void derive_key_exercise( int alg_arg,
4424 data_t *key_data,
4425 data_t *salt,
4426 data_t *label,
4427 int derived_type_arg,
4428 int derived_bits_arg,
4429 int derived_usage_arg,
4430 int derived_alg_arg )
4431{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004432 psa_key_handle_t base_handle = 0;
4433 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004434 psa_algorithm_t alg = alg_arg;
4435 psa_key_type_t derived_type = derived_type_arg;
4436 size_t derived_bits = derived_bits_arg;
4437 psa_key_usage_t derived_usage = derived_usage_arg;
4438 psa_algorithm_t derived_alg = derived_alg_arg;
4439 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004440 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004441 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004442 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004443
Gilles Peskine8817f612018-12-18 00:18:46 +01004444 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004445
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004446 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4447 psa_set_key_algorithm( &attributes, alg );
4448 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004449 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4450 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004451
4452 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004453 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004454 salt->x, salt->len,
4455 label->x, label->len,
4456 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004457 psa_set_key_usage_flags( &attributes, derived_usage );
4458 psa_set_key_algorithm( &attributes, derived_alg );
4459 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004460 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004461 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004462 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004463
4464 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004465 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4466 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4467 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004468
4469 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004470 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004471 goto exit;
4472
4473exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004474 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004475 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004476 psa_destroy_key( base_handle );
4477 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004478 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004479}
4480/* END_CASE */
4481
Janos Follath71a4c912019-06-11 09:14:47 +01004482/* BEGIN_CASE depends_on:PSA_PRE_1_0_KEY_DERIVATION */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004483void derive_key_export( int alg_arg,
4484 data_t *key_data,
4485 data_t *salt,
4486 data_t *label,
4487 int bytes1_arg,
4488 int bytes2_arg )
4489{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004490 psa_key_handle_t base_handle = 0;
4491 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004492 psa_algorithm_t alg = alg_arg;
4493 size_t bytes1 = bytes1_arg;
4494 size_t bytes2 = bytes2_arg;
4495 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004496 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004497 uint8_t *output_buffer = NULL;
4498 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004499 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4500 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004501 size_t length;
4502
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004503 ASSERT_ALLOC( output_buffer, capacity );
4504 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004505 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004506
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004507 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4508 psa_set_key_algorithm( &base_attributes, alg );
4509 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004510 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4511 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004512
4513 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004514 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004515 salt->x, salt->len,
4516 label->x, label->len,
4517 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004518 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004519 output_buffer,
4520 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004521 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004522
4523 /* Derive the same output again, but this time store it in key objects. */
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 Peskineff5f0e72019-04-18 12:53:30 +02004528 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4529 psa_set_key_algorithm( &derived_attributes, 0 );
4530 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004531 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004532 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004533 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004534 PSA_ASSERT( psa_export_key( derived_handle,
4535 export_buffer, bytes1,
4536 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004537 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004538 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004539 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004540 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004541 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004542 PSA_ASSERT( psa_export_key( derived_handle,
4543 export_buffer + bytes1, bytes2,
4544 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004545 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004546
4547 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004548 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4549 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004550
4551exit:
4552 mbedtls_free( output_buffer );
4553 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004554 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004555 psa_destroy_key( base_handle );
4556 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004557 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004558}
4559/* END_CASE */
4560
4561/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004562void key_agreement_setup( int alg_arg,
4563 int our_key_type_arg, data_t *our_key_data,
4564 data_t *peer_key_data,
4565 int expected_status_arg )
4566{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004567 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004568 psa_algorithm_t alg = alg_arg;
4569 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004570 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004571 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004572 psa_status_t expected_status = expected_status_arg;
4573 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004574
Gilles Peskine8817f612018-12-18 00:18:46 +01004575 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004576
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004577 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4578 psa_set_key_algorithm( &attributes, alg );
4579 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004580 PSA_ASSERT( psa_import_key( &attributes,
4581 our_key_data->x, our_key_data->len,
4582 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004583
Gilles Peskine77f40d82019-04-11 21:27:06 +02004584 /* The tests currently include inputs that should fail at either step.
4585 * Test cases that fail at the setup step should be changed to call
4586 * key_derivation_setup instead, and this function should be renamed
4587 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004588 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004589 if( status == PSA_SUCCESS )
4590 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004591 TEST_EQUAL( psa_key_derivation_key_agreement(
4592 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4593 our_key,
4594 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004595 expected_status );
4596 }
4597 else
4598 {
4599 TEST_ASSERT( status == expected_status );
4600 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004601
4602exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004603 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004604 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004605 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004606}
4607/* END_CASE */
4608
4609/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004610void raw_key_agreement( int alg_arg,
4611 int our_key_type_arg, data_t *our_key_data,
4612 data_t *peer_key_data,
4613 data_t *expected_output )
4614{
4615 psa_key_handle_t our_key = 0;
4616 psa_algorithm_t alg = alg_arg;
4617 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004618 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004619 unsigned char *output = NULL;
4620 size_t output_length = ~0;
4621
4622 ASSERT_ALLOC( output, expected_output->len );
4623 PSA_ASSERT( psa_crypto_init( ) );
4624
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004625 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4626 psa_set_key_algorithm( &attributes, alg );
4627 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004628 PSA_ASSERT( psa_import_key( &attributes,
4629 our_key_data->x, our_key_data->len,
4630 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004631
Gilles Peskinebe697d82019-05-16 18:00:41 +02004632 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4633 peer_key_data->x, peer_key_data->len,
4634 output, expected_output->len,
4635 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004636 ASSERT_COMPARE( output, output_length,
4637 expected_output->x, expected_output->len );
4638
4639exit:
4640 mbedtls_free( output );
4641 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004642 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004643}
4644/* END_CASE */
4645
4646/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004647void key_agreement_capacity( int alg_arg,
4648 int our_key_type_arg, data_t *our_key_data,
4649 data_t *peer_key_data,
4650 int expected_capacity_arg )
4651{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004652 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004653 psa_algorithm_t alg = alg_arg;
4654 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004655 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004656 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004657 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004658 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004659
Gilles Peskine8817f612018-12-18 00:18:46 +01004660 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004661
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004662 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4663 psa_set_key_algorithm( &attributes, alg );
4664 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004665 PSA_ASSERT( psa_import_key( &attributes,
4666 our_key_data->x, our_key_data->len,
4667 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004668
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004669 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004670 PSA_ASSERT( psa_key_derivation_key_agreement(
4671 &operation,
4672 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4673 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004674 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4675 {
4676 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004677 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004678 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004679 NULL, 0 ) );
4680 }
Gilles Peskine59685592018-09-18 12:11:34 +02004681
Gilles Peskinebf491972018-10-25 22:36:12 +02004682 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004683 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004684 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004685 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004686
Gilles Peskinebf491972018-10-25 22:36:12 +02004687 /* Test the actual capacity by reading the output. */
4688 while( actual_capacity > sizeof( output ) )
4689 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004690 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004691 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004692 actual_capacity -= sizeof( output );
4693 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004694 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004695 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004696 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004697 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004698
Gilles Peskine59685592018-09-18 12:11:34 +02004699exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004700 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004701 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004702 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004703}
4704/* END_CASE */
4705
4706/* BEGIN_CASE */
4707void key_agreement_output( int alg_arg,
4708 int our_key_type_arg, data_t *our_key_data,
4709 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004710 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004711{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004712 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004713 psa_algorithm_t alg = alg_arg;
4714 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004715 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004716 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004717 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004718
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004719 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4720 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004721
Gilles Peskine8817f612018-12-18 00:18:46 +01004722 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004723
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004724 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4725 psa_set_key_algorithm( &attributes, alg );
4726 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004727 PSA_ASSERT( psa_import_key( &attributes,
4728 our_key_data->x, our_key_data->len,
4729 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004730
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004731 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004732 PSA_ASSERT( psa_key_derivation_key_agreement(
4733 &operation,
4734 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4735 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004736 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4737 {
4738 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004739 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004740 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004741 NULL, 0 ) );
4742 }
Gilles Peskine59685592018-09-18 12:11:34 +02004743
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004744 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004745 actual_output,
4746 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004747 ASSERT_COMPARE( actual_output, expected_output1->len,
4748 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004749 if( expected_output2->len != 0 )
4750 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004751 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004752 actual_output,
4753 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004754 ASSERT_COMPARE( actual_output, expected_output2->len,
4755 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004756 }
Gilles Peskine59685592018-09-18 12:11:34 +02004757
4758exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004759 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004760 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004761 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004762 mbedtls_free( actual_output );
4763}
4764/* END_CASE */
4765
4766/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004767void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004768{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004769 size_t bytes = bytes_arg;
4770 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004771 unsigned char *output = NULL;
4772 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004773 size_t i;
4774 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004775
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004776 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4777 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004778 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004779
Gilles Peskine8817f612018-12-18 00:18:46 +01004780 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004781
Gilles Peskinea50d7392018-06-21 10:22:13 +02004782 /* Run several times, to ensure that every output byte will be
4783 * nonzero at least once with overwhelming probability
4784 * (2^(-8*number_of_runs)). */
4785 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004786 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004787 if( bytes != 0 )
4788 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004789 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004790
4791 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004792 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4793 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004794
4795 for( i = 0; i < bytes; i++ )
4796 {
4797 if( output[i] != 0 )
4798 ++changed[i];
4799 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004800 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004801
4802 /* Check that every byte was changed to nonzero at least once. This
4803 * validates that psa_generate_random is overwriting every byte of
4804 * the output buffer. */
4805 for( i = 0; i < bytes; i++ )
4806 {
4807 TEST_ASSERT( changed[i] != 0 );
4808 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004809
4810exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004811 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004812 mbedtls_free( output );
4813 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004814}
4815/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004816
4817/* BEGIN_CASE */
4818void generate_key( int type_arg,
4819 int bits_arg,
4820 int usage_arg,
4821 int alg_arg,
4822 int expected_status_arg )
4823{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004824 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004825 psa_key_type_t type = type_arg;
4826 psa_key_usage_t usage = usage_arg;
4827 size_t bits = bits_arg;
4828 psa_algorithm_t alg = alg_arg;
4829 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004830 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004831 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004832
Gilles Peskine8817f612018-12-18 00:18:46 +01004833 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004834
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004835 psa_set_key_usage_flags( &attributes, usage );
4836 psa_set_key_algorithm( &attributes, alg );
4837 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004838 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004839
4840 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004841 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004842 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004843 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004844
4845 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004846 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4847 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4848 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004849
Gilles Peskine818ca122018-06-20 18:16:48 +02004850 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004851 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004852 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004853
4854exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004855 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004856 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004857 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004858}
4859/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004860
Gilles Peskinee56e8782019-04-26 17:34:02 +02004861/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4862void generate_key_rsa( int bits_arg,
4863 data_t *e_arg,
4864 int expected_status_arg )
4865{
4866 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02004867 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02004868 size_t bits = bits_arg;
4869 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4870 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4871 psa_status_t expected_status = expected_status_arg;
4872 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4873 uint8_t *exported = NULL;
4874 size_t exported_size =
4875 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4876 size_t exported_length = SIZE_MAX;
4877 uint8_t *e_read_buffer = NULL;
4878 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004879 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004880 size_t e_read_length = SIZE_MAX;
4881
4882 if( e_arg->len == 0 ||
4883 ( e_arg->len == 3 &&
4884 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4885 {
4886 is_default_public_exponent = 1;
4887 e_read_size = 0;
4888 }
4889 ASSERT_ALLOC( e_read_buffer, e_read_size );
4890 ASSERT_ALLOC( exported, exported_size );
4891
4892 PSA_ASSERT( psa_crypto_init( ) );
4893
4894 psa_set_key_usage_flags( &attributes, usage );
4895 psa_set_key_algorithm( &attributes, alg );
4896 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4897 e_arg->x, e_arg->len ) );
4898 psa_set_key_bits( &attributes, bits );
4899
4900 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004901 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004902 if( expected_status != PSA_SUCCESS )
4903 goto exit;
4904
4905 /* Test the key information */
4906 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4907 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4908 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4909 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4910 e_read_buffer, e_read_size,
4911 &e_read_length ) );
4912 if( is_default_public_exponent )
4913 TEST_EQUAL( e_read_length, 0 );
4914 else
4915 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4916
4917 /* Do something with the key according to its type and permitted usage. */
4918 if( ! exercise_key( handle, usage, alg ) )
4919 goto exit;
4920
4921 /* Export the key and check the public exponent. */
4922 PSA_ASSERT( psa_export_public_key( handle,
4923 exported, exported_size,
4924 &exported_length ) );
4925 {
4926 uint8_t *p = exported;
4927 uint8_t *end = exported + exported_length;
4928 size_t len;
4929 /* RSAPublicKey ::= SEQUENCE {
4930 * modulus INTEGER, -- n
4931 * publicExponent INTEGER } -- e
4932 */
4933 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004934 MBEDTLS_ASN1_SEQUENCE |
4935 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004936 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4937 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4938 MBEDTLS_ASN1_INTEGER ) );
4939 if( len >= 1 && p[0] == 0 )
4940 {
4941 ++p;
4942 --len;
4943 }
4944 if( e_arg->len == 0 )
4945 {
4946 TEST_EQUAL( len, 3 );
4947 TEST_EQUAL( p[0], 1 );
4948 TEST_EQUAL( p[1], 0 );
4949 TEST_EQUAL( p[2], 1 );
4950 }
4951 else
4952 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4953 }
4954
4955exit:
4956 psa_reset_key_attributes( &attributes );
4957 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004958 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004959 mbedtls_free( e_read_buffer );
4960 mbedtls_free( exported );
4961}
4962/* END_CASE */
4963
Darryl Greend49a4992018-06-18 17:27:26 +01004964/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004965void persistent_key_load_key_from_storage( data_t *data,
4966 int type_arg, int bits_arg,
4967 int usage_flags_arg, int alg_arg,
4968 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004969{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004970 psa_key_id_t key_id = 1;
4971 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004972 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004973 psa_key_handle_t base_key = 0;
4974 psa_key_type_t type = type_arg;
4975 size_t bits = bits_arg;
4976 psa_key_usage_t usage_flags = usage_flags_arg;
4977 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004978 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004979 unsigned char *first_export = NULL;
4980 unsigned char *second_export = NULL;
4981 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4982 size_t first_exported_length;
4983 size_t second_exported_length;
4984
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004985 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4986 {
4987 ASSERT_ALLOC( first_export, export_size );
4988 ASSERT_ALLOC( second_export, export_size );
4989 }
Darryl Greend49a4992018-06-18 17:27:26 +01004990
Gilles Peskine8817f612018-12-18 00:18:46 +01004991 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004992
Gilles Peskinec87af662019-05-15 16:12:22 +02004993 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004994 psa_set_key_usage_flags( &attributes, usage_flags );
4995 psa_set_key_algorithm( &attributes, alg );
4996 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004997 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004998
Darryl Green0c6575a2018-11-07 16:05:30 +00004999 switch( generation_method )
5000 {
5001 case IMPORT_KEY:
5002 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02005003 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
5004 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005005 break;
Darryl Greend49a4992018-06-18 17:27:26 +01005006
Darryl Green0c6575a2018-11-07 16:05:30 +00005007 case GENERATE_KEY:
5008 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005009 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005010 break;
5011
5012 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005013 {
5014 /* Create base key */
5015 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
5016 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5017 psa_set_key_usage_flags( &base_attributes,
5018 PSA_KEY_USAGE_DERIVE );
5019 psa_set_key_algorithm( &base_attributes, derive_alg );
5020 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005021 PSA_ASSERT( psa_import_key( &base_attributes,
5022 data->x, data->len,
5023 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005024 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005025 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005026 PSA_ASSERT( psa_key_derivation_input_key(
5027 &operation,
5028 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005029 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005030 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005031 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005032 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5033 &operation,
5034 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005035 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005036 PSA_ASSERT( psa_destroy_key( base_key ) );
5037 base_key = 0;
5038 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005039 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005040 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005041 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005042
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005043 /* Export the key if permitted by the key policy. */
5044 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5045 {
5046 PSA_ASSERT( psa_export_key( handle,
5047 first_export, export_size,
5048 &first_exported_length ) );
5049 if( generation_method == IMPORT_KEY )
5050 ASSERT_COMPARE( data->x, data->len,
5051 first_export, first_exported_length );
5052 }
Darryl Greend49a4992018-06-18 17:27:26 +01005053
5054 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005055 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005056 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005057 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005058
Darryl Greend49a4992018-06-18 17:27:26 +01005059 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005060 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005061 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5062 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5063 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5064 PSA_KEY_LIFETIME_PERSISTENT );
5065 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5066 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5067 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5068 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005069
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005070 /* Export the key again if permitted by the key policy. */
5071 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005072 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005073 PSA_ASSERT( psa_export_key( handle,
5074 second_export, export_size,
5075 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005076 ASSERT_COMPARE( first_export, first_exported_length,
5077 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005078 }
5079
5080 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005081 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005082 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005083
5084exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005085 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005086 mbedtls_free( first_export );
5087 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005088 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005089 psa_destroy_key( base_key );
5090 if( handle == 0 )
5091 {
5092 /* In case there was a test failure after creating the persistent key
5093 * but while it was not open, try to re-open the persistent key
5094 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005095 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005096 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005097 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005098 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005099}
5100/* END_CASE */