blob: 22eec33a24808b60c0f41616821c68dddc8aa764 [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 Peskine952f4092019-05-23 20:25:48 +02008#include "psa_helpers.function"
itayzafrir3e02b3b2018-06-12 17:06:52 +03009
Jaeden Amerof24c7f82018-06-27 17:20:43 +010010/** An invalid export length that will never be set by psa_export_key(). */
11static const size_t INVALID_EXPORT_LENGTH = ~0U;
12
Gilles Peskinef426e0f2019-02-25 17:42:03 +010013/* A hash algorithm that is known to be supported.
14 *
15 * This is used in some smoke tests.
16 */
17#if defined(MBEDTLS_MD2_C)
18#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
19#elif defined(MBEDTLS_MD4_C)
20#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
21#elif defined(MBEDTLS_MD5_C)
22#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
23/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
24 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
25 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
26 * implausible anyway. */
27#elif defined(MBEDTLS_SHA1_C)
28#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
29#elif defined(MBEDTLS_SHA256_C)
30#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
31#elif defined(MBEDTLS_SHA512_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
33#elif defined(MBEDTLS_SHA3_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
35#else
36#undef KNOWN_SUPPORTED_HASH_ALG
37#endif
38
39/* A block cipher that is known to be supported.
40 *
41 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
42 */
43#if defined(MBEDTLS_AES_C)
44#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
45#elif defined(MBEDTLS_ARIA_C)
46#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
47#elif defined(MBEDTLS_CAMELLIA_C)
48#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
49#undef KNOWN_SUPPORTED_BLOCK_CIPHER
50#endif
51
52/* A MAC mode that is known to be supported.
53 *
54 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
55 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
56 *
57 * This is used in some smoke tests.
58 */
59#if defined(KNOWN_SUPPORTED_HASH_ALG)
60#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
61#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
62#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
63#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
64#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
65#else
66#undef KNOWN_SUPPORTED_MAC_ALG
67#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
68#endif
69
70/* A cipher algorithm and key type that are known to be supported.
71 *
72 * This is used in some smoke tests.
73 */
74#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
75#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
76#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
77#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
78#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
79#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
80#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
81#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
82#else
83#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
84#endif
85#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
86#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
87#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
88#elif defined(MBEDTLS_RC4_C)
89#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
90#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
91#else
92#undef KNOWN_SUPPORTED_CIPHER_ALG
93#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
94#endif
95
Gilles Peskinea7aa4422018-08-14 15:17:54 +020096/** Test if a buffer contains a constant byte value.
97 *
98 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +020099 *
100 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200101 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200102 * \param size Size of the buffer in bytes.
103 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200104 * \return 1 if the buffer is all-bits-zero.
105 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200107static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200108{
109 size_t i;
110 for( i = 0; i < size; i++ )
111 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200112 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200113 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200114 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200115 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200116}
Gilles Peskine818ca122018-06-20 18:16:48 +0200117
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200118/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
119static int asn1_write_10x( unsigned char **p,
120 unsigned char *start,
121 size_t bits,
122 unsigned char x )
123{
124 int ret;
125 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200126 if( bits == 0 )
127 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
128 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200129 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300130 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200131 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
132 *p -= len;
133 ( *p )[len-1] = x;
134 if( bits % 8 == 0 )
135 ( *p )[1] |= 1;
136 else
137 ( *p )[0] |= 1 << ( bits % 8 );
138 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
139 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
140 MBEDTLS_ASN1_INTEGER ) );
141 return( len );
142}
143
144static int construct_fake_rsa_key( unsigned char *buffer,
145 size_t buffer_size,
146 unsigned char **p,
147 size_t bits,
148 int keypair )
149{
150 size_t half_bits = ( bits + 1 ) / 2;
151 int ret;
152 int len = 0;
153 /* Construct something that looks like a DER encoding of
154 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
155 * RSAPrivateKey ::= SEQUENCE {
156 * version Version,
157 * modulus INTEGER, -- n
158 * publicExponent INTEGER, -- e
159 * privateExponent INTEGER, -- d
160 * prime1 INTEGER, -- p
161 * prime2 INTEGER, -- q
162 * exponent1 INTEGER, -- d mod (p-1)
163 * exponent2 INTEGER, -- d mod (q-1)
164 * coefficient INTEGER, -- (inverse of q) mod p
165 * otherPrimeInfos OtherPrimeInfos OPTIONAL
166 * }
167 * Or, for a public key, the same structure with only
168 * version, modulus and publicExponent.
169 */
170 *p = buffer + buffer_size;
171 if( keypair )
172 {
173 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
174 asn1_write_10x( p, buffer, half_bits, 1 ) );
175 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
176 asn1_write_10x( p, buffer, half_bits, 1 ) );
177 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
178 asn1_write_10x( p, buffer, half_bits, 1 ) );
179 MBEDTLS_ASN1_CHK_ADD( len, /* q */
180 asn1_write_10x( p, buffer, half_bits, 1 ) );
181 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
182 asn1_write_10x( p, buffer, half_bits, 3 ) );
183 MBEDTLS_ASN1_CHK_ADD( len, /* d */
184 asn1_write_10x( p, buffer, bits, 1 ) );
185 }
186 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
187 asn1_write_10x( p, buffer, 17, 1 ) );
188 MBEDTLS_ASN1_CHK_ADD( len, /* n */
189 asn1_write_10x( p, buffer, bits, 1 ) );
190 if( keypair )
191 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
192 mbedtls_asn1_write_int( p, buffer, 0 ) );
193 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
194 {
195 const unsigned char tag =
196 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
198 }
199 return( len );
200}
201
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100202int exercise_mac_setup( psa_key_type_t key_type,
203 const unsigned char *key_bytes,
204 size_t key_length,
205 psa_algorithm_t alg,
206 psa_mac_operation_t *operation,
207 psa_status_t *status )
208{
209 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200210 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100211
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200212 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
213 psa_set_key_algorithm( &attributes, alg );
214 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200215 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
216 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100217
218 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100219 /* Whether setup succeeded or failed, abort must succeed. */
220 PSA_ASSERT( psa_mac_abort( operation ) );
221 /* If setup failed, reproduce the failure, so that the caller can
222 * test the resulting state of the operation object. */
223 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100224 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100225 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
226 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100227 }
228
229 psa_destroy_key( handle );
230 return( 1 );
231
232exit:
233 psa_destroy_key( handle );
234 return( 0 );
235}
236
237int exercise_cipher_setup( psa_key_type_t key_type,
238 const unsigned char *key_bytes,
239 size_t key_length,
240 psa_algorithm_t alg,
241 psa_cipher_operation_t *operation,
242 psa_status_t *status )
243{
244 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200245 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100246
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200247 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
248 psa_set_key_algorithm( &attributes, alg );
249 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200250 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
251 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100252
253 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100254 /* Whether setup succeeded or failed, abort must succeed. */
255 PSA_ASSERT( psa_cipher_abort( operation ) );
256 /* If setup failed, reproduce the failure, so that the caller can
257 * test the resulting state of the operation object. */
258 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100259 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100260 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
261 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100262 }
263
264 psa_destroy_key( handle );
265 return( 1 );
266
267exit:
268 psa_destroy_key( handle );
269 return( 0 );
270}
271
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100272static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200273 psa_key_usage_t usage,
274 psa_algorithm_t alg )
275{
Jaeden Amero769ce272019-01-04 11:48:03 +0000276 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200277 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200278 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200279 size_t mac_length = sizeof( mac );
280
281 if( usage & PSA_KEY_USAGE_SIGN )
282 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100283 PSA_ASSERT( psa_mac_sign_setup( &operation,
284 handle, alg ) );
285 PSA_ASSERT( psa_mac_update( &operation,
286 input, sizeof( input ) ) );
287 PSA_ASSERT( psa_mac_sign_finish( &operation,
288 mac, sizeof( mac ),
289 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200290 }
291
292 if( usage & PSA_KEY_USAGE_VERIFY )
293 {
294 psa_status_t verify_status =
295 ( usage & PSA_KEY_USAGE_SIGN ?
296 PSA_SUCCESS :
297 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100298 PSA_ASSERT( psa_mac_verify_setup( &operation,
299 handle, alg ) );
300 PSA_ASSERT( psa_mac_update( &operation,
301 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100302 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
303 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200304 }
305
306 return( 1 );
307
308exit:
309 psa_mac_abort( &operation );
310 return( 0 );
311}
312
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100313static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200314 psa_key_usage_t usage,
315 psa_algorithm_t alg )
316{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000317 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200318 unsigned char iv[16] = {0};
319 size_t iv_length = sizeof( iv );
320 const unsigned char plaintext[16] = "Hello, world...";
321 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
322 size_t ciphertext_length = sizeof( ciphertext );
323 unsigned char decrypted[sizeof( ciphertext )];
324 size_t part_length;
325
326 if( usage & PSA_KEY_USAGE_ENCRYPT )
327 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100328 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
329 handle, alg ) );
330 PSA_ASSERT( psa_cipher_generate_iv( &operation,
331 iv, sizeof( iv ),
332 &iv_length ) );
333 PSA_ASSERT( psa_cipher_update( &operation,
334 plaintext, sizeof( plaintext ),
335 ciphertext, sizeof( ciphertext ),
336 &ciphertext_length ) );
337 PSA_ASSERT( psa_cipher_finish( &operation,
338 ciphertext + ciphertext_length,
339 sizeof( ciphertext ) - ciphertext_length,
340 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200341 ciphertext_length += part_length;
342 }
343
344 if( usage & PSA_KEY_USAGE_DECRYPT )
345 {
346 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200347 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200348 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
349 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200350 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
351 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
352 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
353 * have this macro yet. */
354 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
355 psa_get_key_type( &attributes ) );
356 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200357 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100358 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
359 handle, alg ) );
360 PSA_ASSERT( psa_cipher_set_iv( &operation,
361 iv, iv_length ) );
362 PSA_ASSERT( psa_cipher_update( &operation,
363 ciphertext, ciphertext_length,
364 decrypted, sizeof( decrypted ),
365 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200366 status = psa_cipher_finish( &operation,
367 decrypted + part_length,
368 sizeof( decrypted ) - part_length,
369 &part_length );
370 /* For a stream cipher, all inputs are valid. For a block cipher,
371 * if the input is some aribtrary data rather than an actual
372 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200373 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200374 TEST_ASSERT( status == PSA_SUCCESS ||
375 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200376 else
377 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200378 }
379
380 return( 1 );
381
382exit:
383 psa_cipher_abort( &operation );
384 return( 0 );
385}
386
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100387static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200388 psa_key_usage_t usage,
389 psa_algorithm_t alg )
390{
391 unsigned char nonce[16] = {0};
392 size_t nonce_length = sizeof( nonce );
393 unsigned char plaintext[16] = "Hello, world...";
394 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
395 size_t ciphertext_length = sizeof( ciphertext );
396 size_t plaintext_length = sizeof( ciphertext );
397
398 if( usage & PSA_KEY_USAGE_ENCRYPT )
399 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100400 PSA_ASSERT( psa_aead_encrypt( handle, alg,
401 nonce, nonce_length,
402 NULL, 0,
403 plaintext, sizeof( plaintext ),
404 ciphertext, sizeof( ciphertext ),
405 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200406 }
407
408 if( usage & PSA_KEY_USAGE_DECRYPT )
409 {
410 psa_status_t verify_status =
411 ( usage & PSA_KEY_USAGE_ENCRYPT ?
412 PSA_SUCCESS :
413 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100414 TEST_EQUAL( psa_aead_decrypt( handle, alg,
415 nonce, nonce_length,
416 NULL, 0,
417 ciphertext, ciphertext_length,
418 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100419 &plaintext_length ),
420 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200421 }
422
423 return( 1 );
424
425exit:
426 return( 0 );
427}
428
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100429static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200430 psa_key_usage_t usage,
431 psa_algorithm_t alg )
432{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200433 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
434 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200435 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200436 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100437 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
438
439 /* If the policy allows signing with any hash, just pick one. */
440 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
441 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100442#if defined(KNOWN_SUPPORTED_HASH_ALG)
443 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
444 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100445#else
446 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100447 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100448#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100449 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200450
451 if( usage & PSA_KEY_USAGE_SIGN )
452 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200453 /* Some algorithms require the payload to have the size of
454 * the hash encoded in the algorithm. Use this input size
455 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200456 if( hash_alg != 0 )
457 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100458 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
459 payload, payload_length,
460 signature, sizeof( signature ),
461 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200462 }
463
464 if( usage & PSA_KEY_USAGE_VERIFY )
465 {
466 psa_status_t verify_status =
467 ( usage & PSA_KEY_USAGE_SIGN ?
468 PSA_SUCCESS :
469 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100470 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
471 payload, payload_length,
472 signature, signature_length ),
473 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200474 }
475
476 return( 1 );
477
478exit:
479 return( 0 );
480}
481
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100482static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200483 psa_key_usage_t usage,
484 psa_algorithm_t alg )
485{
486 unsigned char plaintext[256] = "Hello, world...";
487 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
488 size_t ciphertext_length = sizeof( ciphertext );
489 size_t plaintext_length = 16;
490
491 if( usage & PSA_KEY_USAGE_ENCRYPT )
492 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100493 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
494 plaintext, plaintext_length,
495 NULL, 0,
496 ciphertext, sizeof( ciphertext ),
497 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200498 }
499
500 if( usage & PSA_KEY_USAGE_DECRYPT )
501 {
502 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100503 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200504 ciphertext, ciphertext_length,
505 NULL, 0,
506 plaintext, sizeof( plaintext ),
507 &plaintext_length );
508 TEST_ASSERT( status == PSA_SUCCESS ||
509 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
510 ( status == PSA_ERROR_INVALID_ARGUMENT ||
511 status == PSA_ERROR_INVALID_PADDING ) ) );
512 }
513
514 return( 1 );
515
516exit:
517 return( 0 );
518}
Gilles Peskine02b75072018-07-01 22:31:34 +0200519
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100520static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200521 psa_key_usage_t usage,
522 psa_algorithm_t alg )
523{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200524 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +0200525 unsigned char label[16] = "This is a label.";
526 size_t label_length = sizeof( label );
527 unsigned char seed[16] = "abcdefghijklmnop";
528 size_t seed_length = sizeof( seed );
529 unsigned char output[1];
530
531 if( usage & PSA_KEY_USAGE_DERIVE )
532 {
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100533 if( PSA_ALG_IS_HKDF( alg ) )
534 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200535 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
536 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200537 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100538 label,
539 label_length ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200540 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200541 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100542 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200543 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200544 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100545 seed,
546 seed_length ) );
547 }
548 else
549 {
550 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200551 PSA_ASSERT( psa_key_derivation( &operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100552 handle, alg,
553 label, label_length,
554 seed, seed_length,
555 sizeof( output ) ) );
556 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200557 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200558 output,
559 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200560 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200561 }
562
563 return( 1 );
564
565exit:
566 return( 0 );
567}
568
Gilles Peskinec7998b72018-11-07 18:45:02 +0100569/* We need two keys to exercise key agreement. Exercise the
570 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200571static psa_status_t key_agreement_with_self(
572 psa_key_derivation_operation_t *operation,
573 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100574{
575 psa_key_type_t private_key_type;
576 psa_key_type_t public_key_type;
577 size_t key_bits;
578 uint8_t *public_key = NULL;
579 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200580 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200581 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
582 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200583 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200584 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100585
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200586 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
587 private_key_type = psa_get_key_type( &attributes );
588 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200589 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100590 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
591 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100592 PSA_ASSERT( psa_export_public_key( handle,
593 public_key, public_key_length,
594 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100595
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200596 status = psa_key_derivation_key_agreement(
597 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
598 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100599exit:
600 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200601 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100602 return( status );
603}
604
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200605/* We need two keys to exercise key agreement. Exercise the
606 * private key against its own public key. */
607static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
608 psa_key_handle_t handle )
609{
610 psa_key_type_t private_key_type;
611 psa_key_type_t public_key_type;
612 size_t key_bits;
613 uint8_t *public_key = NULL;
614 size_t public_key_length;
615 uint8_t output[1024];
616 size_t output_length;
617 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200618 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
619 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200620 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200621 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200622
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200623 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
624 private_key_type = psa_get_key_type( &attributes );
625 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200626 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200627 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
628 ASSERT_ALLOC( public_key, public_key_length );
629 PSA_ASSERT( psa_export_public_key( handle,
630 public_key, public_key_length,
631 &public_key_length ) );
632
Gilles Peskinebe697d82019-05-16 18:00:41 +0200633 status = psa_raw_key_agreement( alg, handle,
634 public_key, public_key_length,
635 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200636exit:
637 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200638 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200639 return( status );
640}
641
642static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
643 psa_key_usage_t usage,
644 psa_algorithm_t alg )
645{
646 int ok = 0;
647
648 if( usage & PSA_KEY_USAGE_DERIVE )
649 {
650 /* We need two keys to exercise key agreement. Exercise the
651 * private key against its own public key. */
652 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
653 }
654 ok = 1;
655
656exit:
657 return( ok );
658}
659
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100660static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200661 psa_key_usage_t usage,
662 psa_algorithm_t alg )
663{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200664 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200665 unsigned char output[1];
666 int ok = 0;
667
668 if( usage & PSA_KEY_USAGE_DERIVE )
669 {
670 /* We need two keys to exercise key agreement. Exercise the
671 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200672 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
673 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
674 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200675 output,
676 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200677 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200678 }
679 ok = 1;
680
681exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200682 return( ok );
683}
684
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200685static int is_oid_of_key_type( psa_key_type_t type,
686 const uint8_t *oid, size_t oid_length )
687{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200688 const uint8_t *expected_oid = NULL;
689 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200690#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200691 if( PSA_KEY_TYPE_IS_RSA( type ) )
692 {
693 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
694 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
695 }
696 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200697#endif /* MBEDTLS_RSA_C */
698#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200699 if( PSA_KEY_TYPE_IS_ECC( type ) )
700 {
701 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
702 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
703 }
704 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200705#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200706 {
707 char message[40];
708 mbedtls_snprintf( message, sizeof( message ),
709 "OID not known for key type=0x%08lx",
710 (unsigned long) type );
711 test_fail( message, __LINE__, __FILE__ );
712 return( 0 );
713 }
714
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200715 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200716 return( 1 );
717
718exit:
719 return( 0 );
720}
721
722static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
723 size_t min_bits, size_t max_bits,
724 int must_be_odd )
725{
726 size_t len;
727 size_t actual_bits;
728 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100729 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100730 MBEDTLS_ASN1_INTEGER ),
731 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200732 /* Tolerate a slight departure from DER encoding:
733 * - 0 may be represented by an empty string or a 1-byte string.
734 * - The sign bit may be used as a value bit. */
735 if( ( len == 1 && ( *p )[0] == 0 ) ||
736 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
737 {
738 ++( *p );
739 --len;
740 }
741 if( min_bits == 0 && len == 0 )
742 return( 1 );
743 msb = ( *p )[0];
744 TEST_ASSERT( msb != 0 );
745 actual_bits = 8 * ( len - 1 );
746 while( msb != 0 )
747 {
748 msb >>= 1;
749 ++actual_bits;
750 }
751 TEST_ASSERT( actual_bits >= min_bits );
752 TEST_ASSERT( actual_bits <= max_bits );
753 if( must_be_odd )
754 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
755 *p += len;
756 return( 1 );
757exit:
758 return( 0 );
759}
760
761static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
762 size_t *len,
763 unsigned char n, unsigned char tag )
764{
765 int ret;
766 ret = mbedtls_asn1_get_tag( p, end, len,
767 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
768 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
769 if( ret != 0 )
770 return( ret );
771 end = *p + *len;
772 ret = mbedtls_asn1_get_tag( p, end, len, tag );
773 if( ret != 0 )
774 return( ret );
775 if( *p + *len != end )
776 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
777 return( 0 );
778}
779
780static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
781 uint8_t *exported, size_t exported_length )
782{
783 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100784 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200785 else
786 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200787
788#if defined(MBEDTLS_DES_C)
789 if( type == PSA_KEY_TYPE_DES )
790 {
791 /* Check the parity bits. */
792 unsigned i;
793 for( i = 0; i < bits / 8; i++ )
794 {
795 unsigned bit_count = 0;
796 unsigned m;
797 for( m = 1; m <= 0x100; m <<= 1 )
798 {
799 if( exported[i] & m )
800 ++bit_count;
801 }
802 TEST_ASSERT( bit_count % 2 != 0 );
803 }
804 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200805 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200806#endif
807
808#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200809 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200810 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200811 uint8_t *p = exported;
812 uint8_t *end = exported + exported_length;
813 size_t len;
814 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200815 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200816 * modulus INTEGER, -- n
817 * publicExponent INTEGER, -- e
818 * privateExponent INTEGER, -- d
819 * prime1 INTEGER, -- p
820 * prime2 INTEGER, -- q
821 * exponent1 INTEGER, -- d mod (p-1)
822 * exponent2 INTEGER, -- d mod (q-1)
823 * coefficient INTEGER, -- (inverse of q) mod p
824 * }
825 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100826 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
827 MBEDTLS_ASN1_SEQUENCE |
828 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
829 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200830 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
831 goto exit;
832 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
833 goto exit;
834 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
835 goto exit;
836 /* Require d to be at least half the size of n. */
837 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
838 goto exit;
839 /* Require p and q to be at most half the size of n, rounded up. */
840 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
841 goto exit;
842 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
843 goto exit;
844 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
845 goto exit;
846 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
847 goto exit;
848 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
849 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100850 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100851 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200852 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200853#endif /* MBEDTLS_RSA_C */
854
855#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200856 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200857 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100858 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100859 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100860 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200861 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200862#endif /* MBEDTLS_ECP_C */
863
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200864 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
865 {
866 uint8_t *p = exported;
867 uint8_t *end = exported + exported_length;
868 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200869#if defined(MBEDTLS_RSA_C)
870 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
871 {
872 /* RSAPublicKey ::= SEQUENCE {
873 * modulus INTEGER, -- n
874 * publicExponent INTEGER } -- e
875 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100876 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
877 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100878 MBEDTLS_ASN1_CONSTRUCTED ),
879 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100880 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200881 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
882 goto exit;
883 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
884 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100885 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200886 }
887 else
888#endif /* MBEDTLS_RSA_C */
889#if defined(MBEDTLS_ECP_C)
890 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
891 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000892 /* The representation of an ECC public key is:
893 * - The byte 0x04;
894 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
895 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
896 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000897 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100898 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
899 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200900 }
901 else
902#endif /* MBEDTLS_ECP_C */
903 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100904 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200905 mbedtls_snprintf( message, sizeof( message ),
906 "No sanity check for public key type=0x%08lx",
907 (unsigned long) type );
908 test_fail( message, __LINE__, __FILE__ );
909 return( 0 );
910 }
911 }
912 else
913
914 {
915 /* No sanity checks for other types */
916 }
917
918 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200919
920exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200921 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200922}
923
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100924static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200925 psa_key_usage_t usage )
926{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200927 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200928 uint8_t *exported = NULL;
929 size_t exported_size = 0;
930 size_t exported_length = 0;
931 int ok = 0;
932
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200933 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200934
935 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200936 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200937 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100938 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
939 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200940 ok = 1;
941 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200942 }
943
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200944 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
945 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200946 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200947
Gilles Peskine8817f612018-12-18 00:18:46 +0100948 PSA_ASSERT( psa_export_key( handle,
949 exported, exported_size,
950 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200951 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
952 psa_get_key_bits( &attributes ),
953 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200954
955exit:
956 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200957 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200958 return( ok );
959}
960
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100961static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200962{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200963 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200964 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200965 uint8_t *exported = NULL;
966 size_t exported_size = 0;
967 size_t exported_length = 0;
968 int ok = 0;
969
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200970 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
971 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200972 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100973 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100974 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200975 return( 1 );
976 }
977
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200978 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200979 psa_get_key_type( &attributes ) );
980 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
981 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200982 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200983
Gilles Peskine8817f612018-12-18 00:18:46 +0100984 PSA_ASSERT( psa_export_public_key( handle,
985 exported, exported_size,
986 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200987 ok = exported_key_sanity_check( public_type,
988 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200989 exported, exported_length );
990
991exit:
992 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200993 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200994 return( ok );
995}
996
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100997/** Do smoke tests on a key.
998 *
999 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1000 * sign/verify, or derivation) that is permitted according to \p usage.
1001 * \p usage and \p alg should correspond to the expected policy on the
1002 * key.
1003 *
1004 * Export the key if permitted by \p usage, and check that the output
1005 * looks sensible. If \p usage forbids export, check that
1006 * \p psa_export_key correctly rejects the attempt. If the key is
1007 * asymmetric, also check \p psa_export_public_key.
1008 *
1009 * If the key fails the tests, this function calls the test framework's
1010 * `test_fail` function and returns false. Otherwise this function returns
1011 * true. Therefore it should be used as follows:
1012 * ```
1013 * if( ! exercise_key( ... ) ) goto exit;
1014 * ```
1015 *
1016 * \param handle The key to exercise. It should be capable of performing
1017 * \p alg.
1018 * \param usage The usage flags to assume.
1019 * \param alg The algorithm to exercise.
1020 *
1021 * \retval 0 The key failed the smoke tests.
1022 * \retval 1 The key passed the smoke tests.
1023 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001024static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001025 psa_key_usage_t usage,
1026 psa_algorithm_t alg )
1027{
1028 int ok;
1029 if( alg == 0 )
1030 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1031 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001032 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001033 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001034 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001035 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001036 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001037 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001038 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001039 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001040 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001041 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001042 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001043 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1044 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001045 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001046 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001047 else
1048 {
1049 char message[40];
1050 mbedtls_snprintf( message, sizeof( message ),
1051 "No code to exercise alg=0x%08lx",
1052 (unsigned long) alg );
1053 test_fail( message, __LINE__, __FILE__ );
1054 ok = 0;
1055 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001056
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001057 ok = ok && exercise_export_key( handle, usage );
1058 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001059
Gilles Peskine02b75072018-07-01 22:31:34 +02001060 return( ok );
1061}
1062
Gilles Peskine10df3412018-10-25 22:35:43 +02001063static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1064 psa_algorithm_t alg )
1065{
1066 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1067 {
1068 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1069 PSA_KEY_USAGE_VERIFY :
1070 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1071 }
1072 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1073 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1074 {
1075 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1076 PSA_KEY_USAGE_ENCRYPT :
1077 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1078 }
1079 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1080 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1081 {
1082 return( PSA_KEY_USAGE_DERIVE );
1083 }
1084 else
1085 {
1086 return( 0 );
1087 }
1088
1089}
Darryl Green0c6575a2018-11-07 16:05:30 +00001090
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001091static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1092{
1093 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1094 uint8_t buffer[1];
1095 size_t length;
1096 int ok = 0;
1097
Gilles Peskinec87af662019-05-15 16:12:22 +02001098 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001099 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1100 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1101 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1102 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1103 PSA_ERROR_INVALID_HANDLE );
1104 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001105 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001106 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1107 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1108 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1109 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1110
1111 TEST_EQUAL( psa_export_key( handle,
1112 buffer, sizeof( buffer ), &length ),
1113 PSA_ERROR_INVALID_HANDLE );
1114 TEST_EQUAL( psa_export_public_key( handle,
1115 buffer, sizeof( buffer ), &length ),
1116 PSA_ERROR_INVALID_HANDLE );
1117
1118 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1119 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1120
1121 ok = 1;
1122
1123exit:
1124 psa_reset_key_attributes( &attributes );
1125 return( ok );
1126}
1127
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001128/* An overapproximation of the amount of storage needed for a key of the
1129 * given type and with the given content. The API doesn't make it easy
1130 * to find a good value for the size. The current implementation doesn't
1131 * care about the value anyway. */
1132#define KEY_BITS_FROM_DATA( type, data ) \
1133 ( data )->len
1134
Darryl Green0c6575a2018-11-07 16:05:30 +00001135typedef enum {
1136 IMPORT_KEY = 0,
1137 GENERATE_KEY = 1,
1138 DERIVE_KEY = 2
1139} generate_method;
1140
Gilles Peskinee59236f2018-01-27 23:32:46 +01001141/* END_HEADER */
1142
1143/* BEGIN_DEPENDENCIES
1144 * depends_on:MBEDTLS_PSA_CRYPTO_C
1145 * END_DEPENDENCIES
1146 */
1147
1148/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001149void static_checks( )
1150{
1151 size_t max_truncated_mac_size =
1152 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1153
1154 /* Check that the length for a truncated MAC always fits in the algorithm
1155 * encoding. The shifted mask is the maximum truncated value. The
1156 * untruncated algorithm may be one byte larger. */
1157 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1158}
1159/* END_CASE */
1160
1161/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001162void attributes_set_get( int id_arg, int lifetime_arg,
1163 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001164 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001165{
Gilles Peskine4747d192019-04-17 15:05:45 +02001166 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001167 psa_key_id_t id = id_arg;
1168 psa_key_lifetime_t lifetime = lifetime_arg;
1169 psa_key_usage_t usage_flags = usage_flags_arg;
1170 psa_algorithm_t alg = alg_arg;
1171 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001172 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001173
1174 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1175 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1176 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1177 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1178 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001179 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001180
Gilles Peskinec87af662019-05-15 16:12:22 +02001181 psa_set_key_id( &attributes, id );
1182 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001183 psa_set_key_usage_flags( &attributes, usage_flags );
1184 psa_set_key_algorithm( &attributes, alg );
1185 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001186 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001187
1188 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1189 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1190 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1191 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1192 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001193 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001194
1195 psa_reset_key_attributes( &attributes );
1196
1197 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1198 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1199 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1200 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1201 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001202 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001203}
1204/* END_CASE */
1205
1206/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001207void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1208 int expected_id_arg, int expected_lifetime_arg )
1209{
1210 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1211 psa_key_id_t id1 = id1_arg;
1212 psa_key_lifetime_t lifetime = lifetime_arg;
1213 psa_key_id_t id2 = id2_arg;
1214 psa_key_id_t expected_id = expected_id_arg;
1215 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1216
1217 if( id1_arg != -1 )
1218 psa_set_key_id( &attributes, id1 );
1219 if( lifetime_arg != -1 )
1220 psa_set_key_lifetime( &attributes, lifetime );
1221 if( id2_arg != -1 )
1222 psa_set_key_id( &attributes, id2 );
1223
1224 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1225 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1226}
1227/* END_CASE */
1228
1229/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001230void import( data_t *data, int type_arg,
1231 int attr_bits_arg,
1232 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001233{
1234 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1235 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001236 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001237 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001238 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001239 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001240 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001241
Gilles Peskine8817f612018-12-18 00:18:46 +01001242 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001243
Gilles Peskine4747d192019-04-17 15:05:45 +02001244 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001245 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001246 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001247 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001248 if( status != PSA_SUCCESS )
1249 goto exit;
1250
1251 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1252 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001253 if( attr_bits != 0 )
1254 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001255
1256 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001257 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001258
1259exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001260 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001261 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001262 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001263}
1264/* END_CASE */
1265
1266/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001267void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1268{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001269 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001270 size_t bits = bits_arg;
1271 psa_status_t expected_status = expected_status_arg;
1272 psa_status_t status;
1273 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001274 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001275 size_t buffer_size = /* Slight overapproximations */
1276 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001277 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001278 unsigned char *p;
1279 int ret;
1280 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001281 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001282
Gilles Peskine8817f612018-12-18 00:18:46 +01001283 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001284 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001285
1286 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1287 bits, keypair ) ) >= 0 );
1288 length = ret;
1289
1290 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001291 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001292 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001293 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001294
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001295 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001296 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001297
1298exit:
1299 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001300 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001301}
1302/* END_CASE */
1303
1304/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001305void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001306 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001307 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001308 int expected_bits,
1309 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001310 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001311 int canonical_input )
1312{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001313 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001314 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001315 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001316 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001318 unsigned char *exported = NULL;
1319 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001320 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001321 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001322 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001323 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001324 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001325
Moran Pekercb088e72018-07-17 17:36:59 +03001326 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001327 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001328 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001329 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001330 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001331
Gilles Peskine4747d192019-04-17 15:05:45 +02001332 psa_set_key_usage_flags( &attributes, usage_arg );
1333 psa_set_key_algorithm( &attributes, alg );
1334 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001335
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001336 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001337 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001338
1339 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001340 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1341 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1342 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001343
1344 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001345 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001346 exported, export_size,
1347 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001348 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001349
1350 /* The exported length must be set by psa_export_key() to a value between 0
1351 * and export_size. On errors, the exported length must be 0. */
1352 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1353 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1354 TEST_ASSERT( exported_length <= export_size );
1355
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001356 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001357 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001358 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001359 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001360 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001361 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001362 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001363
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001364 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001365 goto exit;
1366
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001367 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001368 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001369 else
1370 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001371 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001372 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1373 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001374 PSA_ASSERT( psa_export_key( handle2,
1375 reexported,
1376 export_size,
1377 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001378 ASSERT_COMPARE( exported, exported_length,
1379 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001380 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001381 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001382 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001383
1384destroy:
1385 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001386 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001387 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001388
1389exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001390 mbedtls_free( exported );
1391 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001392 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001393 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001394}
1395/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001396
Moran Pekerf709f4a2018-06-06 17:26:04 +03001397/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001398void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001399{
Gilles Peskine8817f612018-12-18 00:18:46 +01001400 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001401 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001402
1403exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001404 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001405}
1406/* END_CASE */
1407
1408/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001409void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001410 int type_arg,
1411 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001412 int export_size_delta,
1413 int expected_export_status_arg,
1414 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001415{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001416 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001417 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001418 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001419 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001420 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001421 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001422 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001423 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001424 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001425
Gilles Peskine8817f612018-12-18 00:18:46 +01001426 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001427
Gilles Peskine4747d192019-04-17 15:05:45 +02001428 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1429 psa_set_key_algorithm( &attributes, alg );
1430 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001431
1432 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001433 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001434
Gilles Peskine49c25912018-10-29 15:15:31 +01001435 /* Export the public key */
1436 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001437 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001438 exported, export_size,
1439 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001440 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001441 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001442 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001443 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001444 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001445 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1446 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001447 TEST_ASSERT( expected_public_key->len <=
1448 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001449 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1450 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001451 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001452
1453exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001454 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001455 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001456 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001457 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001458}
1459/* END_CASE */
1460
Gilles Peskine20035e32018-02-03 22:44:14 +01001461/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001462void import_and_exercise_key( data_t *data,
1463 int type_arg,
1464 int bits_arg,
1465 int alg_arg )
1466{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001467 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001468 psa_key_type_t type = type_arg;
1469 size_t bits = bits_arg;
1470 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001471 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001472 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001473 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001474
Gilles Peskine8817f612018-12-18 00:18:46 +01001475 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001476
Gilles Peskine4747d192019-04-17 15:05:45 +02001477 psa_set_key_usage_flags( &attributes, usage );
1478 psa_set_key_algorithm( &attributes, alg );
1479 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001480
1481 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001482 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001483
1484 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001485 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1486 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1487 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001488
1489 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001490 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001491 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001492
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001493 PSA_ASSERT( psa_destroy_key( handle ) );
1494 test_operations_on_invalid_handle( handle );
1495
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001496exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001497 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001498 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001499 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001500}
1501/* END_CASE */
1502
1503/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001504void key_policy( int usage_arg, int alg_arg )
1505{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001506 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001507 psa_algorithm_t alg = alg_arg;
1508 psa_key_usage_t usage = usage_arg;
1509 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1510 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001511 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001512
1513 memset( key, 0x2a, sizeof( key ) );
1514
Gilles Peskine8817f612018-12-18 00:18:46 +01001515 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001516
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001517 psa_set_key_usage_flags( &attributes, usage );
1518 psa_set_key_algorithm( &attributes, alg );
1519 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001520
Gilles Peskine73676cb2019-05-15 20:15:10 +02001521 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001522
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001523 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1524 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1525 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1526 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001527
1528exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001529 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001530 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001531 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001532}
1533/* END_CASE */
1534
1535/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001536void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001537{
1538 /* Test each valid way of initializing the object, except for `= {0}`, as
1539 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1540 * though it's OK by the C standard. We could test for this, but we'd need
1541 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001542 psa_key_attributes_t func = psa_key_attributes_init( );
1543 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1544 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001545
1546 memset( &zero, 0, sizeof( zero ) );
1547
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001548 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1549 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1550 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001551
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001552 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1553 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1554 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1555
1556 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1557 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1558 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1559
1560 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1561 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1562 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1563
1564 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1565 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1566 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001567}
1568/* END_CASE */
1569
1570/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001571void mac_key_policy( int policy_usage,
1572 int policy_alg,
1573 int key_type,
1574 data_t *key_data,
1575 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001576{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001577 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001578 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001579 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001580 psa_status_t status;
1581 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001582
Gilles Peskine8817f612018-12-18 00:18:46 +01001583 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001584
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001585 psa_set_key_usage_flags( &attributes, policy_usage );
1586 psa_set_key_algorithm( &attributes, policy_alg );
1587 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001588
Gilles Peskine049c7532019-05-15 20:22:09 +02001589 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1590 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001591
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001592 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001593 if( policy_alg == exercise_alg &&
1594 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001595 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001596 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001597 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001598 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001599
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001600 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001601 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001602 if( policy_alg == exercise_alg &&
1603 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001604 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001605 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001606 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001607
1608exit:
1609 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001610 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001611 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001612}
1613/* END_CASE */
1614
1615/* BEGIN_CASE */
1616void cipher_key_policy( int policy_usage,
1617 int policy_alg,
1618 int key_type,
1619 data_t *key_data,
1620 int exercise_alg )
1621{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001622 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001623 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001624 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001625 psa_status_t status;
1626
Gilles Peskine8817f612018-12-18 00:18:46 +01001627 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001628
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001629 psa_set_key_usage_flags( &attributes, policy_usage );
1630 psa_set_key_algorithm( &attributes, policy_alg );
1631 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001632
Gilles Peskine049c7532019-05-15 20:22:09 +02001633 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1634 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001635
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001636 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001637 if( policy_alg == exercise_alg &&
1638 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001639 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001640 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001641 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001642 psa_cipher_abort( &operation );
1643
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001644 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001645 if( policy_alg == exercise_alg &&
1646 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001647 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001648 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001649 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001650
1651exit:
1652 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001653 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001654 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001655}
1656/* END_CASE */
1657
1658/* BEGIN_CASE */
1659void aead_key_policy( int policy_usage,
1660 int policy_alg,
1661 int key_type,
1662 data_t *key_data,
1663 int nonce_length_arg,
1664 int tag_length_arg,
1665 int exercise_alg )
1666{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001667 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001668 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001669 psa_status_t status;
1670 unsigned char nonce[16] = {0};
1671 size_t nonce_length = nonce_length_arg;
1672 unsigned char tag[16];
1673 size_t tag_length = tag_length_arg;
1674 size_t output_length;
1675
1676 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1677 TEST_ASSERT( tag_length <= sizeof( tag ) );
1678
Gilles Peskine8817f612018-12-18 00:18:46 +01001679 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001680
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001681 psa_set_key_usage_flags( &attributes, policy_usage );
1682 psa_set_key_algorithm( &attributes, policy_alg );
1683 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001684
Gilles Peskine049c7532019-05-15 20:22:09 +02001685 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1686 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001687
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001688 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001689 nonce, nonce_length,
1690 NULL, 0,
1691 NULL, 0,
1692 tag, tag_length,
1693 &output_length );
1694 if( policy_alg == exercise_alg &&
1695 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001696 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001697 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001698 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001699
1700 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001701 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001702 nonce, nonce_length,
1703 NULL, 0,
1704 tag, tag_length,
1705 NULL, 0,
1706 &output_length );
1707 if( policy_alg == exercise_alg &&
1708 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001709 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001710 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001711 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001712
1713exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001714 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001715 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716}
1717/* END_CASE */
1718
1719/* BEGIN_CASE */
1720void asymmetric_encryption_key_policy( int policy_usage,
1721 int policy_alg,
1722 int key_type,
1723 data_t *key_data,
1724 int exercise_alg )
1725{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001726 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001727 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001728 psa_status_t status;
1729 size_t key_bits;
1730 size_t buffer_length;
1731 unsigned char *buffer = NULL;
1732 size_t output_length;
1733
Gilles Peskine8817f612018-12-18 00:18:46 +01001734 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001735
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001736 psa_set_key_usage_flags( &attributes, policy_usage );
1737 psa_set_key_algorithm( &attributes, policy_alg );
1738 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001739
Gilles Peskine049c7532019-05-15 20:22:09 +02001740 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1741 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001742
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001743 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1744 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001745 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1746 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001747 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001749 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001750 NULL, 0,
1751 NULL, 0,
1752 buffer, buffer_length,
1753 &output_length );
1754 if( policy_alg == exercise_alg &&
1755 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001756 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001757 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001758 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001759
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001760 if( buffer_length != 0 )
1761 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001762 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001763 buffer, buffer_length,
1764 NULL, 0,
1765 buffer, buffer_length,
1766 &output_length );
1767 if( policy_alg == exercise_alg &&
1768 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001769 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001770 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001771 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001772
1773exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001774 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001775 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001776 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001777 mbedtls_free( buffer );
1778}
1779/* END_CASE */
1780
1781/* BEGIN_CASE */
1782void asymmetric_signature_key_policy( int policy_usage,
1783 int policy_alg,
1784 int key_type,
1785 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001786 int exercise_alg,
1787 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001788{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001789 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001790 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001791 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001792 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1793 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1794 * compatible with the policy and `payload_length_arg` is supposed to be
1795 * a valid input length to sign. If `payload_length_arg <= 0`,
1796 * `exercise_alg` is supposed to be forbidden by the policy. */
1797 int compatible_alg = payload_length_arg > 0;
1798 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001799 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1800 size_t signature_length;
1801
Gilles Peskine8817f612018-12-18 00:18:46 +01001802 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001803
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001804 psa_set_key_usage_flags( &attributes, policy_usage );
1805 psa_set_key_algorithm( &attributes, policy_alg );
1806 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001807
Gilles Peskine049c7532019-05-15 20:22:09 +02001808 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1809 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001810
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001811 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001812 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001813 signature, sizeof( signature ),
1814 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001815 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001816 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001817 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001818 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001819
1820 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001821 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001823 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001824 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001825 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001826 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001827 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001828
1829exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001830 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001831 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001832}
1833/* END_CASE */
1834
1835/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001836void derive_key_policy( int policy_usage,
1837 int policy_alg,
1838 int key_type,
1839 data_t *key_data,
1840 int exercise_alg )
1841{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001842 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001843 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001844 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001845 psa_status_t status;
1846
Gilles Peskine8817f612018-12-18 00:18:46 +01001847 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001848
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001849 psa_set_key_usage_flags( &attributes, policy_usage );
1850 psa_set_key_algorithm( &attributes, policy_alg );
1851 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001852
Gilles Peskine049c7532019-05-15 20:22:09 +02001853 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1854 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001855
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001856 status = psa_key_derivation( &operation, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001857 exercise_alg,
1858 NULL, 0,
1859 NULL, 0,
1860 1 );
1861 if( policy_alg == exercise_alg &&
1862 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001863 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001864 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001865 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001866
1867exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001868 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001869 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001870 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001871}
1872/* END_CASE */
1873
1874/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001875void agreement_key_policy( int policy_usage,
1876 int policy_alg,
1877 int key_type_arg,
1878 data_t *key_data,
1879 int exercise_alg )
1880{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001881 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001882 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001883 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001884 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001885 psa_status_t status;
1886
Gilles Peskine8817f612018-12-18 00:18:46 +01001887 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001888
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001889 psa_set_key_usage_flags( &attributes, policy_usage );
1890 psa_set_key_algorithm( &attributes, policy_alg );
1891 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001892
Gilles Peskine049c7532019-05-15 20:22:09 +02001893 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1894 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001895
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001896 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1897 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001898
Gilles Peskine01d718c2018-09-18 12:01:02 +02001899 if( policy_alg == exercise_alg &&
1900 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001901 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001902 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001903 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001904
1905exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001906 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001907 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001908 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001909}
1910/* END_CASE */
1911
1912/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001913void key_policy_alg2( int key_type_arg, data_t *key_data,
1914 int usage_arg, int alg_arg, int alg2_arg )
1915{
1916 psa_key_handle_t handle = 0;
1917 psa_key_type_t key_type = key_type_arg;
1918 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1919 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1920 psa_key_usage_t usage = usage_arg;
1921 psa_algorithm_t alg = alg_arg;
1922 psa_algorithm_t alg2 = alg2_arg;
1923
1924 PSA_ASSERT( psa_crypto_init( ) );
1925
1926 psa_set_key_usage_flags( &attributes, usage );
1927 psa_set_key_algorithm( &attributes, alg );
1928 psa_set_key_enrollment_algorithm( &attributes, alg2 );
1929 psa_set_key_type( &attributes, key_type );
1930 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1931 &handle ) );
1932
1933 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1934 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1935 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1936 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
1937
1938 if( ! exercise_key( handle, usage, alg ) )
1939 goto exit;
1940 if( ! exercise_key( handle, usage, alg2 ) )
1941 goto exit;
1942
1943exit:
1944 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001945 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001946}
1947/* END_CASE */
1948
1949/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001950void raw_agreement_key_policy( int policy_usage,
1951 int policy_alg,
1952 int key_type_arg,
1953 data_t *key_data,
1954 int exercise_alg )
1955{
1956 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001957 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001958 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001959 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001960 psa_status_t status;
1961
1962 PSA_ASSERT( psa_crypto_init( ) );
1963
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001964 psa_set_key_usage_flags( &attributes, policy_usage );
1965 psa_set_key_algorithm( &attributes, policy_alg );
1966 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001967
Gilles Peskine049c7532019-05-15 20:22:09 +02001968 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1969 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001970
1971 status = raw_key_agreement_with_self( exercise_alg, handle );
1972
1973 if( policy_alg == exercise_alg &&
1974 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1975 PSA_ASSERT( status );
1976 else
1977 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1978
1979exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001980 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001981 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001982 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001983}
1984/* END_CASE */
1985
1986/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001987void copy_success( int source_usage_arg,
1988 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02001989 int type_arg, data_t *material,
1990 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001991 int target_usage_arg,
1992 int target_alg_arg, int target_alg2_arg,
1993 int expected_usage_arg,
1994 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001995{
Gilles Peskineca25db92019-04-19 11:43:08 +02001996 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1997 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001998 psa_key_usage_t expected_usage = expected_usage_arg;
1999 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002000 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002001 psa_key_handle_t source_handle = 0;
2002 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002003 uint8_t *export_buffer = NULL;
2004
Gilles Peskine57ab7212019-01-28 13:03:09 +01002005 PSA_ASSERT( psa_crypto_init( ) );
2006
Gilles Peskineca25db92019-04-19 11:43:08 +02002007 /* Prepare the source key. */
2008 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2009 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002010 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002011 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002012 PSA_ASSERT( psa_import_key( &source_attributes,
2013 material->x, material->len,
2014 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002015 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002016
Gilles Peskineca25db92019-04-19 11:43:08 +02002017 /* Prepare the target attributes. */
2018 if( copy_attributes )
2019 target_attributes = source_attributes;
2020 if( target_usage_arg != -1 )
2021 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2022 if( target_alg_arg != -1 )
2023 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002024 if( target_alg2_arg != -1 )
2025 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002026
2027 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002028 PSA_ASSERT( psa_copy_key( source_handle,
2029 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002030
2031 /* Destroy the source to ensure that this doesn't affect the target. */
2032 PSA_ASSERT( psa_destroy_key( source_handle ) );
2033
2034 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002035 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2036 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2037 psa_get_key_type( &target_attributes ) );
2038 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2039 psa_get_key_bits( &target_attributes ) );
2040 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2041 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002042 TEST_EQUAL( expected_alg2,
2043 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002044 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2045 {
2046 size_t length;
2047 ASSERT_ALLOC( export_buffer, material->len );
2048 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2049 material->len, &length ) );
2050 ASSERT_COMPARE( material->x, material->len,
2051 export_buffer, length );
2052 }
2053 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2054 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002055 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2056 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002057
2058 PSA_ASSERT( psa_close_key( target_handle ) );
2059
2060exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002061 psa_reset_key_attributes( &source_attributes );
2062 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002063 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002064 mbedtls_free( export_buffer );
2065}
2066/* END_CASE */
2067
2068/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002069void copy_fail( int source_usage_arg,
2070 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002071 int type_arg, data_t *material,
2072 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002073 int target_usage_arg,
2074 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002075 int expected_status_arg )
2076{
2077 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2078 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2079 psa_key_handle_t source_handle = 0;
2080 psa_key_handle_t target_handle = 0;
2081
2082 PSA_ASSERT( psa_crypto_init( ) );
2083
2084 /* Prepare the source key. */
2085 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2086 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002087 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002088 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002089 PSA_ASSERT( psa_import_key( &source_attributes,
2090 material->x, material->len,
2091 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002092
2093 /* Prepare the target attributes. */
2094 psa_set_key_type( &target_attributes, target_type_arg );
2095 psa_set_key_bits( &target_attributes, target_bits_arg );
2096 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2097 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002098 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002099
2100 /* Try to copy the key. */
2101 TEST_EQUAL( psa_copy_key( source_handle,
2102 &target_attributes, &target_handle ),
2103 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002104
2105 PSA_ASSERT( psa_destroy_key( source_handle ) );
2106
Gilles Peskine4a644642019-05-03 17:14:08 +02002107exit:
2108 psa_reset_key_attributes( &source_attributes );
2109 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002110 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002111}
2112/* END_CASE */
2113
2114/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002115void hash_operation_init( )
2116{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002117 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002118 /* Test each valid way of initializing the object, except for `= {0}`, as
2119 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2120 * though it's OK by the C standard. We could test for this, but we'd need
2121 * to supress the Clang warning for the test. */
2122 psa_hash_operation_t func = psa_hash_operation_init( );
2123 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2124 psa_hash_operation_t zero;
2125
2126 memset( &zero, 0, sizeof( zero ) );
2127
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002128 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002129 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2130 PSA_ERROR_BAD_STATE );
2131 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2132 PSA_ERROR_BAD_STATE );
2133 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2134 PSA_ERROR_BAD_STATE );
2135
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002136 /* A default hash operation should be abortable without error. */
2137 PSA_ASSERT( psa_hash_abort( &func ) );
2138 PSA_ASSERT( psa_hash_abort( &init ) );
2139 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002140}
2141/* END_CASE */
2142
2143/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002144void hash_setup( int alg_arg,
2145 int expected_status_arg )
2146{
2147 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002148 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002149 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002150 psa_status_t status;
2151
Gilles Peskine8817f612018-12-18 00:18:46 +01002152 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002153
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002154 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002155 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002156
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002157 /* Whether setup succeeded or failed, abort must succeed. */
2158 PSA_ASSERT( psa_hash_abort( &operation ) );
2159
2160 /* If setup failed, reproduce the failure, so as to
2161 * test the resulting state of the operation object. */
2162 if( status != PSA_SUCCESS )
2163 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2164
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002165 /* Now the operation object should be reusable. */
2166#if defined(KNOWN_SUPPORTED_HASH_ALG)
2167 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2168 PSA_ASSERT( psa_hash_abort( &operation ) );
2169#endif
2170
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002171exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002172 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002173}
2174/* END_CASE */
2175
2176/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002177void hash_bad_order( )
2178{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002179 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002180 unsigned char input[] = "";
2181 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002182 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002183 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2184 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2185 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002186 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002187 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002188 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002189
Gilles Peskine8817f612018-12-18 00:18:46 +01002190 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002191
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002192 /* Call setup twice in a row. */
2193 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2194 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2195 PSA_ERROR_BAD_STATE );
2196 PSA_ASSERT( psa_hash_abort( &operation ) );
2197
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002198 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002199 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002200 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002201 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002202
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002203 /* Call update after finish. */
2204 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2205 PSA_ASSERT( psa_hash_finish( &operation,
2206 hash, sizeof( hash ), &hash_len ) );
2207 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002208 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002209 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002210
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002211 /* Call verify without calling setup beforehand. */
2212 TEST_EQUAL( psa_hash_verify( &operation,
2213 valid_hash, sizeof( valid_hash ) ),
2214 PSA_ERROR_BAD_STATE );
2215 PSA_ASSERT( psa_hash_abort( &operation ) );
2216
2217 /* Call verify after finish. */
2218 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2219 PSA_ASSERT( psa_hash_finish( &operation,
2220 hash, sizeof( hash ), &hash_len ) );
2221 TEST_EQUAL( psa_hash_verify( &operation,
2222 valid_hash, sizeof( valid_hash ) ),
2223 PSA_ERROR_BAD_STATE );
2224 PSA_ASSERT( psa_hash_abort( &operation ) );
2225
2226 /* Call verify twice in a row. */
2227 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2228 PSA_ASSERT( psa_hash_verify( &operation,
2229 valid_hash, sizeof( valid_hash ) ) );
2230 TEST_EQUAL( psa_hash_verify( &operation,
2231 valid_hash, sizeof( valid_hash ) ),
2232 PSA_ERROR_BAD_STATE );
2233 PSA_ASSERT( psa_hash_abort( &operation ) );
2234
2235 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002236 TEST_EQUAL( psa_hash_finish( &operation,
2237 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002238 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002239 PSA_ASSERT( psa_hash_abort( &operation ) );
2240
2241 /* Call finish twice in a row. */
2242 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2243 PSA_ASSERT( psa_hash_finish( &operation,
2244 hash, sizeof( hash ), &hash_len ) );
2245 TEST_EQUAL( psa_hash_finish( &operation,
2246 hash, sizeof( hash ), &hash_len ),
2247 PSA_ERROR_BAD_STATE );
2248 PSA_ASSERT( psa_hash_abort( &operation ) );
2249
2250 /* Call finish after calling verify. */
2251 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2252 PSA_ASSERT( psa_hash_verify( &operation,
2253 valid_hash, sizeof( valid_hash ) ) );
2254 TEST_EQUAL( psa_hash_finish( &operation,
2255 hash, sizeof( hash ), &hash_len ),
2256 PSA_ERROR_BAD_STATE );
2257 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002258
2259exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002260 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002261}
2262/* END_CASE */
2263
itayzafrir27e69452018-11-01 14:26:34 +02002264/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2265void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002266{
2267 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002268 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2269 * appended to it */
2270 unsigned char hash[] = {
2271 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2272 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2273 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002274 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002275 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002276
Gilles Peskine8817f612018-12-18 00:18:46 +01002277 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002278
itayzafrir27e69452018-11-01 14:26:34 +02002279 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002280 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002281 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002282 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002283
itayzafrir27e69452018-11-01 14:26:34 +02002284 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002285 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002286 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002287 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002288
itayzafrir27e69452018-11-01 14:26:34 +02002289 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002290 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002291 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002292 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002293
itayzafrirec93d302018-10-18 18:01:10 +03002294exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002295 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002296}
2297/* END_CASE */
2298
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002299/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2300void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002301{
2302 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002303 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002304 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002305 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002306 size_t hash_len;
2307
Gilles Peskine8817f612018-12-18 00:18:46 +01002308 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002309
itayzafrir58028322018-10-25 10:22:01 +03002310 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002311 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002312 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002313 hash, expected_size - 1, &hash_len ),
2314 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002315
2316exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002317 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002318}
2319/* END_CASE */
2320
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002321/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2322void hash_clone_source_state( )
2323{
2324 psa_algorithm_t alg = PSA_ALG_SHA_256;
2325 unsigned char hash[PSA_HASH_MAX_SIZE];
2326 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2327 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2328 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2329 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2330 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2331 size_t hash_len;
2332
2333 PSA_ASSERT( psa_crypto_init( ) );
2334 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2335
2336 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2337 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2338 PSA_ASSERT( psa_hash_finish( &op_finished,
2339 hash, sizeof( hash ), &hash_len ) );
2340 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2341 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2342
2343 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2344 PSA_ERROR_BAD_STATE );
2345
2346 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2347 PSA_ASSERT( psa_hash_finish( &op_init,
2348 hash, sizeof( hash ), &hash_len ) );
2349 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2350 PSA_ASSERT( psa_hash_finish( &op_finished,
2351 hash, sizeof( hash ), &hash_len ) );
2352 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2353 PSA_ASSERT( psa_hash_finish( &op_aborted,
2354 hash, sizeof( hash ), &hash_len ) );
2355
2356exit:
2357 psa_hash_abort( &op_source );
2358 psa_hash_abort( &op_init );
2359 psa_hash_abort( &op_setup );
2360 psa_hash_abort( &op_finished );
2361 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002362 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002363}
2364/* END_CASE */
2365
2366/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2367void hash_clone_target_state( )
2368{
2369 psa_algorithm_t alg = PSA_ALG_SHA_256;
2370 unsigned char hash[PSA_HASH_MAX_SIZE];
2371 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2372 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2373 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2374 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2375 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2376 size_t hash_len;
2377
2378 PSA_ASSERT( psa_crypto_init( ) );
2379
2380 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2381 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2382 PSA_ASSERT( psa_hash_finish( &op_finished,
2383 hash, sizeof( hash ), &hash_len ) );
2384 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2385 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2386
2387 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2388 PSA_ASSERT( psa_hash_finish( &op_target,
2389 hash, sizeof( hash ), &hash_len ) );
2390
2391 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2392 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2393 PSA_ERROR_BAD_STATE );
2394 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2395 PSA_ERROR_BAD_STATE );
2396
2397exit:
2398 psa_hash_abort( &op_target );
2399 psa_hash_abort( &op_init );
2400 psa_hash_abort( &op_setup );
2401 psa_hash_abort( &op_finished );
2402 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002403 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002404}
2405/* END_CASE */
2406
itayzafrir58028322018-10-25 10:22:01 +03002407/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002408void mac_operation_init( )
2409{
Jaeden Amero252ef282019-02-15 14:05:35 +00002410 const uint8_t input[1] = { 0 };
2411
Jaeden Amero769ce272019-01-04 11:48:03 +00002412 /* Test each valid way of initializing the object, except for `= {0}`, as
2413 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2414 * though it's OK by the C standard. We could test for this, but we'd need
2415 * to supress the Clang warning for the test. */
2416 psa_mac_operation_t func = psa_mac_operation_init( );
2417 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2418 psa_mac_operation_t zero;
2419
2420 memset( &zero, 0, sizeof( zero ) );
2421
Jaeden Amero252ef282019-02-15 14:05:35 +00002422 /* A freshly-initialized MAC operation should not be usable. */
2423 TEST_EQUAL( psa_mac_update( &func,
2424 input, sizeof( input ) ),
2425 PSA_ERROR_BAD_STATE );
2426 TEST_EQUAL( psa_mac_update( &init,
2427 input, sizeof( input ) ),
2428 PSA_ERROR_BAD_STATE );
2429 TEST_EQUAL( psa_mac_update( &zero,
2430 input, sizeof( input ) ),
2431 PSA_ERROR_BAD_STATE );
2432
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002433 /* A default MAC operation should be abortable without error. */
2434 PSA_ASSERT( psa_mac_abort( &func ) );
2435 PSA_ASSERT( psa_mac_abort( &init ) );
2436 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002437}
2438/* END_CASE */
2439
2440/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002441void mac_setup( int key_type_arg,
2442 data_t *key,
2443 int alg_arg,
2444 int expected_status_arg )
2445{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002446 psa_key_type_t key_type = key_type_arg;
2447 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002448 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002449 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002450 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2451#if defined(KNOWN_SUPPORTED_MAC_ALG)
2452 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2453#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002454
Gilles Peskine8817f612018-12-18 00:18:46 +01002455 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002456
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002457 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2458 &operation, &status ) )
2459 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002460 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002461
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002462 /* The operation object should be reusable. */
2463#if defined(KNOWN_SUPPORTED_MAC_ALG)
2464 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2465 smoke_test_key_data,
2466 sizeof( smoke_test_key_data ),
2467 KNOWN_SUPPORTED_MAC_ALG,
2468 &operation, &status ) )
2469 goto exit;
2470 TEST_EQUAL( status, PSA_SUCCESS );
2471#endif
2472
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002473exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002474 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002475}
2476/* END_CASE */
2477
2478/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002479void mac_bad_order( )
2480{
2481 psa_key_handle_t handle = 0;
2482 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2483 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2484 const uint8_t key[] = {
2485 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2486 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2487 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002488 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002489 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2490 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2491 size_t sign_mac_length = 0;
2492 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2493 const uint8_t verify_mac[] = {
2494 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2495 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2496 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2497
2498 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002499 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2500 psa_set_key_algorithm( &attributes, alg );
2501 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002502
Gilles Peskine73676cb2019-05-15 20:15:10 +02002503 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002504
Jaeden Amero252ef282019-02-15 14:05:35 +00002505 /* Call update without calling setup beforehand. */
2506 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2507 PSA_ERROR_BAD_STATE );
2508 PSA_ASSERT( psa_mac_abort( &operation ) );
2509
2510 /* Call sign finish without calling setup beforehand. */
2511 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2512 &sign_mac_length),
2513 PSA_ERROR_BAD_STATE );
2514 PSA_ASSERT( psa_mac_abort( &operation ) );
2515
2516 /* Call verify finish without calling setup beforehand. */
2517 TEST_EQUAL( psa_mac_verify_finish( &operation,
2518 verify_mac, sizeof( verify_mac ) ),
2519 PSA_ERROR_BAD_STATE );
2520 PSA_ASSERT( psa_mac_abort( &operation ) );
2521
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002522 /* Call setup twice in a row. */
2523 PSA_ASSERT( psa_mac_sign_setup( &operation,
2524 handle, alg ) );
2525 TEST_EQUAL( psa_mac_sign_setup( &operation,
2526 handle, alg ),
2527 PSA_ERROR_BAD_STATE );
2528 PSA_ASSERT( psa_mac_abort( &operation ) );
2529
Jaeden Amero252ef282019-02-15 14:05:35 +00002530 /* Call update after sign finish. */
2531 PSA_ASSERT( psa_mac_sign_setup( &operation,
2532 handle, alg ) );
2533 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2534 PSA_ASSERT( psa_mac_sign_finish( &operation,
2535 sign_mac, sizeof( sign_mac ),
2536 &sign_mac_length ) );
2537 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2538 PSA_ERROR_BAD_STATE );
2539 PSA_ASSERT( psa_mac_abort( &operation ) );
2540
2541 /* Call update after verify finish. */
2542 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002543 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002544 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2545 PSA_ASSERT( psa_mac_verify_finish( &operation,
2546 verify_mac, sizeof( verify_mac ) ) );
2547 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2548 PSA_ERROR_BAD_STATE );
2549 PSA_ASSERT( psa_mac_abort( &operation ) );
2550
2551 /* Call sign finish twice in a row. */
2552 PSA_ASSERT( psa_mac_sign_setup( &operation,
2553 handle, alg ) );
2554 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2555 PSA_ASSERT( psa_mac_sign_finish( &operation,
2556 sign_mac, sizeof( sign_mac ),
2557 &sign_mac_length ) );
2558 TEST_EQUAL( psa_mac_sign_finish( &operation,
2559 sign_mac, sizeof( sign_mac ),
2560 &sign_mac_length ),
2561 PSA_ERROR_BAD_STATE );
2562 PSA_ASSERT( psa_mac_abort( &operation ) );
2563
2564 /* Call verify finish twice in a row. */
2565 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002566 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002567 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2568 PSA_ASSERT( psa_mac_verify_finish( &operation,
2569 verify_mac, sizeof( verify_mac ) ) );
2570 TEST_EQUAL( psa_mac_verify_finish( &operation,
2571 verify_mac, sizeof( verify_mac ) ),
2572 PSA_ERROR_BAD_STATE );
2573 PSA_ASSERT( psa_mac_abort( &operation ) );
2574
2575 /* Setup sign but try verify. */
2576 PSA_ASSERT( psa_mac_sign_setup( &operation,
2577 handle, alg ) );
2578 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2579 TEST_EQUAL( psa_mac_verify_finish( &operation,
2580 verify_mac, sizeof( verify_mac ) ),
2581 PSA_ERROR_BAD_STATE );
2582 PSA_ASSERT( psa_mac_abort( &operation ) );
2583
2584 /* Setup verify but try sign. */
2585 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002586 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002587 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2588 TEST_EQUAL( psa_mac_sign_finish( &operation,
2589 sign_mac, sizeof( sign_mac ),
2590 &sign_mac_length ),
2591 PSA_ERROR_BAD_STATE );
2592 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002593
Gilles Peskine76b29a72019-05-28 14:08:50 +02002594 PSA_ASSERT( psa_destroy_key( handle ) );
2595
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002596exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002597 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002598}
2599/* END_CASE */
2600
2601/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002602void mac_sign( int key_type_arg,
2603 data_t *key,
2604 int alg_arg,
2605 data_t *input,
2606 data_t *expected_mac )
2607{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002608 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002609 psa_key_type_t key_type = key_type_arg;
2610 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002611 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002612 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002613 /* Leave a little extra room in the output buffer. At the end of the
2614 * test, we'll check that the implementation didn't overwrite onto
2615 * this extra room. */
2616 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2617 size_t mac_buffer_size =
2618 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2619 size_t mac_length = 0;
2620
2621 memset( actual_mac, '+', sizeof( actual_mac ) );
2622 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2623 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2624
Gilles Peskine8817f612018-12-18 00:18:46 +01002625 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002626
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002627 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2628 psa_set_key_algorithm( &attributes, alg );
2629 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002630
Gilles Peskine73676cb2019-05-15 20:15:10 +02002631 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002632
2633 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002634 PSA_ASSERT( psa_mac_sign_setup( &operation,
2635 handle, alg ) );
2636 PSA_ASSERT( psa_mac_update( &operation,
2637 input->x, input->len ) );
2638 PSA_ASSERT( psa_mac_sign_finish( &operation,
2639 actual_mac, mac_buffer_size,
2640 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002641
2642 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002643 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2644 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002645
2646 /* Verify that the end of the buffer is untouched. */
2647 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2648 sizeof( actual_mac ) - mac_length ) );
2649
2650exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002651 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002652 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002653}
2654/* END_CASE */
2655
2656/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002657void mac_verify( int key_type_arg,
2658 data_t *key,
2659 int alg_arg,
2660 data_t *input,
2661 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002662{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002663 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002664 psa_key_type_t key_type = key_type_arg;
2665 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002666 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002667 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002668
Gilles Peskine69c12672018-06-28 00:07:19 +02002669 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2670
Gilles Peskine8817f612018-12-18 00:18:46 +01002671 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002672
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002673 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2674 psa_set_key_algorithm( &attributes, alg );
2675 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002676
Gilles Peskine73676cb2019-05-15 20:15:10 +02002677 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002678
Gilles Peskine8817f612018-12-18 00:18:46 +01002679 PSA_ASSERT( psa_mac_verify_setup( &operation,
2680 handle, alg ) );
2681 PSA_ASSERT( psa_destroy_key( handle ) );
2682 PSA_ASSERT( psa_mac_update( &operation,
2683 input->x, input->len ) );
2684 PSA_ASSERT( psa_mac_verify_finish( &operation,
2685 expected_mac->x,
2686 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002687
2688exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002689 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002690 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002691}
2692/* END_CASE */
2693
2694/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002695void cipher_operation_init( )
2696{
Jaeden Ameroab439972019-02-15 14:12:05 +00002697 const uint8_t input[1] = { 0 };
2698 unsigned char output[1] = { 0 };
2699 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002700 /* Test each valid way of initializing the object, except for `= {0}`, as
2701 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2702 * though it's OK by the C standard. We could test for this, but we'd need
2703 * to supress the Clang warning for the test. */
2704 psa_cipher_operation_t func = psa_cipher_operation_init( );
2705 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2706 psa_cipher_operation_t zero;
2707
2708 memset( &zero, 0, sizeof( zero ) );
2709
Jaeden Ameroab439972019-02-15 14:12:05 +00002710 /* A freshly-initialized cipher operation should not be usable. */
2711 TEST_EQUAL( psa_cipher_update( &func,
2712 input, sizeof( input ),
2713 output, sizeof( output ),
2714 &output_length ),
2715 PSA_ERROR_BAD_STATE );
2716 TEST_EQUAL( psa_cipher_update( &init,
2717 input, sizeof( input ),
2718 output, sizeof( output ),
2719 &output_length ),
2720 PSA_ERROR_BAD_STATE );
2721 TEST_EQUAL( psa_cipher_update( &zero,
2722 input, sizeof( input ),
2723 output, sizeof( output ),
2724 &output_length ),
2725 PSA_ERROR_BAD_STATE );
2726
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002727 /* A default cipher operation should be abortable without error. */
2728 PSA_ASSERT( psa_cipher_abort( &func ) );
2729 PSA_ASSERT( psa_cipher_abort( &init ) );
2730 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002731}
2732/* END_CASE */
2733
2734/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002735void cipher_setup( int key_type_arg,
2736 data_t *key,
2737 int alg_arg,
2738 int expected_status_arg )
2739{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002740 psa_key_type_t key_type = key_type_arg;
2741 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002742 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002743 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002744 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002745#if defined(KNOWN_SUPPORTED_MAC_ALG)
2746 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2747#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002748
Gilles Peskine8817f612018-12-18 00:18:46 +01002749 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002750
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002751 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2752 &operation, &status ) )
2753 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002754 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002755
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002756 /* The operation object should be reusable. */
2757#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2758 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2759 smoke_test_key_data,
2760 sizeof( smoke_test_key_data ),
2761 KNOWN_SUPPORTED_CIPHER_ALG,
2762 &operation, &status ) )
2763 goto exit;
2764 TEST_EQUAL( status, PSA_SUCCESS );
2765#endif
2766
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002767exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002768 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002769}
2770/* END_CASE */
2771
2772/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002773void cipher_bad_order( )
2774{
2775 psa_key_handle_t handle = 0;
2776 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2777 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002778 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002779 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2780 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2781 const uint8_t key[] = {
2782 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2783 0xaa, 0xaa, 0xaa, 0xaa };
2784 const uint8_t text[] = {
2785 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2786 0xbb, 0xbb, 0xbb, 0xbb };
2787 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2788 size_t length = 0;
2789
2790 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002791 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2792 psa_set_key_algorithm( &attributes, alg );
2793 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002794 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002795
2796
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002797 /* Call encrypt setup twice in a row. */
2798 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2799 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2800 PSA_ERROR_BAD_STATE );
2801 PSA_ASSERT( psa_cipher_abort( &operation ) );
2802
2803 /* Call decrypt setup twice in a row. */
2804 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2805 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2806 PSA_ERROR_BAD_STATE );
2807 PSA_ASSERT( psa_cipher_abort( &operation ) );
2808
Jaeden Ameroab439972019-02-15 14:12:05 +00002809 /* Generate an IV without calling setup beforehand. */
2810 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2811 buffer, sizeof( buffer ),
2812 &length ),
2813 PSA_ERROR_BAD_STATE );
2814 PSA_ASSERT( psa_cipher_abort( &operation ) );
2815
2816 /* Generate an IV twice in a row. */
2817 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2818 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2819 buffer, sizeof( buffer ),
2820 &length ) );
2821 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2822 buffer, sizeof( buffer ),
2823 &length ),
2824 PSA_ERROR_BAD_STATE );
2825 PSA_ASSERT( psa_cipher_abort( &operation ) );
2826
2827 /* Generate 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_generate_iv( &operation,
2832 buffer, sizeof( buffer ),
2833 &length ),
2834 PSA_ERROR_BAD_STATE );
2835 PSA_ASSERT( psa_cipher_abort( &operation ) );
2836
2837 /* Set an IV without calling setup beforehand. */
2838 TEST_EQUAL( psa_cipher_set_iv( &operation,
2839 iv, sizeof( iv ) ),
2840 PSA_ERROR_BAD_STATE );
2841 PSA_ASSERT( psa_cipher_abort( &operation ) );
2842
2843 /* Set an IV after it's already set. */
2844 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2845 PSA_ASSERT( psa_cipher_set_iv( &operation,
2846 iv, sizeof( iv ) ) );
2847 TEST_EQUAL( psa_cipher_set_iv( &operation,
2848 iv, sizeof( iv ) ),
2849 PSA_ERROR_BAD_STATE );
2850 PSA_ASSERT( psa_cipher_abort( &operation ) );
2851
2852 /* Set an IV after it's already generated. */
2853 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2854 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2855 buffer, sizeof( buffer ),
2856 &length ) );
2857 TEST_EQUAL( psa_cipher_set_iv( &operation,
2858 iv, sizeof( iv ) ),
2859 PSA_ERROR_BAD_STATE );
2860 PSA_ASSERT( psa_cipher_abort( &operation ) );
2861
2862 /* Call update without calling setup beforehand. */
2863 TEST_EQUAL( psa_cipher_update( &operation,
2864 text, sizeof( text ),
2865 buffer, sizeof( buffer ),
2866 &length ),
2867 PSA_ERROR_BAD_STATE );
2868 PSA_ASSERT( psa_cipher_abort( &operation ) );
2869
2870 /* Call update without an IV where an IV is required. */
2871 TEST_EQUAL( psa_cipher_update( &operation,
2872 text, sizeof( text ),
2873 buffer, sizeof( buffer ),
2874 &length ),
2875 PSA_ERROR_BAD_STATE );
2876 PSA_ASSERT( psa_cipher_abort( &operation ) );
2877
2878 /* Call update after finish. */
2879 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2880 PSA_ASSERT( psa_cipher_set_iv( &operation,
2881 iv, sizeof( iv ) ) );
2882 PSA_ASSERT( psa_cipher_finish( &operation,
2883 buffer, sizeof( buffer ), &length ) );
2884 TEST_EQUAL( psa_cipher_update( &operation,
2885 text, sizeof( text ),
2886 buffer, sizeof( buffer ),
2887 &length ),
2888 PSA_ERROR_BAD_STATE );
2889 PSA_ASSERT( psa_cipher_abort( &operation ) );
2890
2891 /* Call finish without calling setup beforehand. */
2892 TEST_EQUAL( psa_cipher_finish( &operation,
2893 buffer, sizeof( buffer ), &length ),
2894 PSA_ERROR_BAD_STATE );
2895 PSA_ASSERT( psa_cipher_abort( &operation ) );
2896
2897 /* Call finish without an IV where an IV is required. */
2898 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2899 /* Not calling update means we are encrypting an empty buffer, which is OK
2900 * for cipher modes with padding. */
2901 TEST_EQUAL( psa_cipher_finish( &operation,
2902 buffer, sizeof( buffer ), &length ),
2903 PSA_ERROR_BAD_STATE );
2904 PSA_ASSERT( psa_cipher_abort( &operation ) );
2905
2906 /* Call finish twice in a row. */
2907 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2908 PSA_ASSERT( psa_cipher_set_iv( &operation,
2909 iv, sizeof( iv ) ) );
2910 PSA_ASSERT( psa_cipher_finish( &operation,
2911 buffer, sizeof( buffer ), &length ) );
2912 TEST_EQUAL( psa_cipher_finish( &operation,
2913 buffer, sizeof( buffer ), &length ),
2914 PSA_ERROR_BAD_STATE );
2915 PSA_ASSERT( psa_cipher_abort( &operation ) );
2916
Gilles Peskine76b29a72019-05-28 14:08:50 +02002917 PSA_ASSERT( psa_destroy_key( handle ) );
2918
Jaeden Ameroab439972019-02-15 14:12:05 +00002919exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002920 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002921}
2922/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002923
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002925void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002926 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002927 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002928 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002929{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002930 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002931 psa_status_t status;
2932 psa_key_type_t key_type = key_type_arg;
2933 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002934 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002935 unsigned char *output = NULL;
2936 size_t output_buffer_size = 0;
2937 size_t function_output_length = 0;
2938 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002939 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002940 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002941
Gilles Peskine8817f612018-12-18 00:18:46 +01002942 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002943
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002944 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2945 psa_set_key_algorithm( &attributes, alg );
2946 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002947
Gilles Peskine73676cb2019-05-15 20:15:10 +02002948 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002949
Gilles Peskine8817f612018-12-18 00:18:46 +01002950 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2951 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952
Gilles Peskine423005e2019-05-06 15:22:57 +02002953 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002954 output_buffer_size = ( (size_t) input->len +
2955 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002956 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002957
Gilles Peskine8817f612018-12-18 00:18:46 +01002958 PSA_ASSERT( psa_cipher_update( &operation,
2959 input->x, input->len,
2960 output, output_buffer_size,
2961 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002962 total_output_length += function_output_length;
2963 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002964 output + total_output_length,
2965 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002966 &function_output_length );
2967 total_output_length += function_output_length;
2968
Gilles Peskinefe11b722018-12-18 00:24:04 +01002969 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002970 if( expected_status == PSA_SUCCESS )
2971 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002972 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002973 ASSERT_COMPARE( expected_output->x, expected_output->len,
2974 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002975 }
2976
2977exit:
2978 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002979 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002980 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002981}
2982/* END_CASE */
2983
2984/* BEGIN_CASE */
2985void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002986 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002987 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002988 int first_part_size_arg,
2989 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002990 data_t *expected_output )
2991{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002992 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002993 psa_key_type_t key_type = key_type_arg;
2994 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002995 size_t first_part_size = first_part_size_arg;
2996 size_t output1_length = output1_length_arg;
2997 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002998 unsigned char *output = NULL;
2999 size_t output_buffer_size = 0;
3000 size_t function_output_length = 0;
3001 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003002 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003003 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003004
Gilles Peskine8817f612018-12-18 00:18:46 +01003005 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003006
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003007 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3008 psa_set_key_algorithm( &attributes, alg );
3009 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003010
Gilles Peskine73676cb2019-05-15 20:15:10 +02003011 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012
Gilles Peskine8817f612018-12-18 00:18:46 +01003013 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3014 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003015
Gilles Peskine423005e2019-05-06 15:22:57 +02003016 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003017 output_buffer_size = ( (size_t) input->len +
3018 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003019 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003020
Gilles Peskinee0866522019-02-19 19:44:00 +01003021 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003022 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3023 output, output_buffer_size,
3024 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003025 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003026 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003027 PSA_ASSERT( psa_cipher_update( &operation,
3028 input->x + first_part_size,
3029 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003030 output + total_output_length,
3031 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003032 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003033 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003034 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003035 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003036 output + total_output_length,
3037 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003038 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003039 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003040 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003042 ASSERT_COMPARE( expected_output->x, expected_output->len,
3043 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003044
3045exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003046 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003047 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003048 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003049}
3050/* END_CASE */
3051
3052/* BEGIN_CASE */
3053void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003054 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003055 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003056 int first_part_size_arg,
3057 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003058 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003059{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003060 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003061
3062 psa_key_type_t key_type = key_type_arg;
3063 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003064 size_t first_part_size = first_part_size_arg;
3065 size_t output1_length = output1_length_arg;
3066 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003067 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003068 size_t output_buffer_size = 0;
3069 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003070 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003071 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003072 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003073
Gilles Peskine8817f612018-12-18 00:18:46 +01003074 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003075
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003076 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3077 psa_set_key_algorithm( &attributes, alg );
3078 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003079
Gilles Peskine73676cb2019-05-15 20:15:10 +02003080 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003081
Gilles Peskine8817f612018-12-18 00:18:46 +01003082 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3083 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003084
Gilles Peskine423005e2019-05-06 15:22:57 +02003085 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003087 output_buffer_size = ( (size_t) input->len +
3088 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003089 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003090
Gilles Peskinee0866522019-02-19 19:44:00 +01003091 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003092 PSA_ASSERT( psa_cipher_update( &operation,
3093 input->x, first_part_size,
3094 output, output_buffer_size,
3095 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003096 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003097 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003098 PSA_ASSERT( psa_cipher_update( &operation,
3099 input->x + first_part_size,
3100 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003101 output + total_output_length,
3102 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003103 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003104 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003105 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003106 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003107 output + total_output_length,
3108 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003109 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003110 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003111 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003112
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003113 ASSERT_COMPARE( expected_output->x, expected_output->len,
3114 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003115
3116exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003117 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003118 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003119 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003120}
3121/* END_CASE */
3122
Gilles Peskine50e586b2018-06-08 14:28:46 +02003123/* BEGIN_CASE */
3124void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003125 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003126 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003127 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003128{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003129 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003130 psa_status_t status;
3131 psa_key_type_t key_type = key_type_arg;
3132 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003133 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003134 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003135 size_t output_buffer_size = 0;
3136 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003137 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003138 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003139 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003140
Gilles Peskine8817f612018-12-18 00:18:46 +01003141 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003142
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003143 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3144 psa_set_key_algorithm( &attributes, alg );
3145 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003146
Gilles Peskine73676cb2019-05-15 20:15:10 +02003147 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003148
Gilles Peskine8817f612018-12-18 00:18:46 +01003149 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3150 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003151
Gilles Peskine423005e2019-05-06 15:22:57 +02003152 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003153
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003154 output_buffer_size = ( (size_t) input->len +
3155 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003156 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003157
Gilles Peskine8817f612018-12-18 00:18:46 +01003158 PSA_ASSERT( psa_cipher_update( &operation,
3159 input->x, input->len,
3160 output, output_buffer_size,
3161 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003162 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003163 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003164 output + total_output_length,
3165 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003166 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003167 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003168 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003169
3170 if( expected_status == PSA_SUCCESS )
3171 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003172 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003173 ASSERT_COMPARE( expected_output->x, expected_output->len,
3174 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003175 }
3176
Gilles Peskine50e586b2018-06-08 14:28:46 +02003177exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003178 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003179 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003180 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003181}
3182/* END_CASE */
3183
Gilles Peskine50e586b2018-06-08 14:28:46 +02003184/* BEGIN_CASE */
3185void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003186 data_t *key,
3187 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003188{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003189 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003190 psa_key_type_t key_type = key_type_arg;
3191 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003192 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003193 size_t iv_size = 16;
3194 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003195 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003196 size_t output1_size = 0;
3197 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003198 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003199 size_t output2_size = 0;
3200 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003201 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003202 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3203 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003204 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003205
Gilles Peskine8817f612018-12-18 00:18:46 +01003206 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003207
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003208 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3209 psa_set_key_algorithm( &attributes, alg );
3210 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003211
Gilles Peskine73676cb2019-05-15 20:15:10 +02003212 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003213
Gilles Peskine8817f612018-12-18 00:18:46 +01003214 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3215 handle, alg ) );
3216 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3217 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003218
Gilles Peskine8817f612018-12-18 00:18:46 +01003219 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3220 iv, iv_size,
3221 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003222 output1_size = ( (size_t) input->len +
3223 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003224 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003225
Gilles Peskine8817f612018-12-18 00:18:46 +01003226 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3227 output1, output1_size,
3228 &output1_length ) );
3229 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003230 output1 + output1_length,
3231 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003232 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003233
Gilles Peskine048b7f02018-06-08 14:20:49 +02003234 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003235
Gilles Peskine8817f612018-12-18 00:18:46 +01003236 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003237
3238 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003239 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003240
Gilles Peskine8817f612018-12-18 00:18:46 +01003241 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3242 iv, iv_length ) );
3243 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3244 output2, output2_size,
3245 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003246 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003247 PSA_ASSERT( psa_cipher_finish( &operation2,
3248 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003249 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003250 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003251
Gilles Peskine048b7f02018-06-08 14:20:49 +02003252 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003253
Gilles Peskine8817f612018-12-18 00:18:46 +01003254 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003255
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003256 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003257
3258exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003259 mbedtls_free( output1 );
3260 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003261 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003262 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003263}
3264/* END_CASE */
3265
3266/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003267void cipher_verify_output_multipart( int alg_arg,
3268 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003269 data_t *key,
3270 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003271 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003272{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003273 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003274 psa_key_type_t key_type = key_type_arg;
3275 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003276 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003277 unsigned char iv[16] = {0};
3278 size_t iv_size = 16;
3279 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003280 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003281 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003282 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003283 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003284 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003285 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003286 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003287 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3288 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003289 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003290
Gilles Peskine8817f612018-12-18 00:18:46 +01003291 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003292
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003293 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3294 psa_set_key_algorithm( &attributes, alg );
3295 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003296
Gilles Peskine73676cb2019-05-15 20:15:10 +02003297 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003298
Gilles Peskine8817f612018-12-18 00:18:46 +01003299 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3300 handle, alg ) );
3301 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3302 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003303
Gilles Peskine8817f612018-12-18 00:18:46 +01003304 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3305 iv, iv_size,
3306 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003307 output1_buffer_size = ( (size_t) input->len +
3308 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003309 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003310
Gilles Peskinee0866522019-02-19 19:44:00 +01003311 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003312
Gilles Peskine8817f612018-12-18 00:18:46 +01003313 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3314 output1, output1_buffer_size,
3315 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003316 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003317
Gilles Peskine8817f612018-12-18 00:18:46 +01003318 PSA_ASSERT( psa_cipher_update( &operation1,
3319 input->x + first_part_size,
3320 input->len - first_part_size,
3321 output1, output1_buffer_size,
3322 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003323 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003324
Gilles Peskine8817f612018-12-18 00:18:46 +01003325 PSA_ASSERT( psa_cipher_finish( &operation1,
3326 output1 + output1_length,
3327 output1_buffer_size - output1_length,
3328 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003329 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003330
Gilles Peskine8817f612018-12-18 00:18:46 +01003331 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003332
Gilles Peskine048b7f02018-06-08 14:20:49 +02003333 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003334 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003335
Gilles Peskine8817f612018-12-18 00:18:46 +01003336 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3337 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003338
Gilles Peskine8817f612018-12-18 00:18:46 +01003339 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3340 output2, output2_buffer_size,
3341 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003342 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003343
Gilles Peskine8817f612018-12-18 00:18:46 +01003344 PSA_ASSERT( psa_cipher_update( &operation2,
3345 output1 + first_part_size,
3346 output1_length - first_part_size,
3347 output2, output2_buffer_size,
3348 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003349 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003350
Gilles Peskine8817f612018-12-18 00:18:46 +01003351 PSA_ASSERT( psa_cipher_finish( &operation2,
3352 output2 + output2_length,
3353 output2_buffer_size - output2_length,
3354 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003355 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003356
Gilles Peskine8817f612018-12-18 00:18:46 +01003357 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003358
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003359 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003360
3361exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003362 mbedtls_free( output1 );
3363 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003364 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003365 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003366}
3367/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003368
Gilles Peskine20035e32018-02-03 22:44:14 +01003369/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003370void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003371 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003372 data_t *nonce,
3373 data_t *additional_data,
3374 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003375 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003376{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003377 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003378 psa_key_type_t key_type = key_type_arg;
3379 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003380 unsigned char *output_data = NULL;
3381 size_t output_size = 0;
3382 size_t output_length = 0;
3383 unsigned char *output_data2 = NULL;
3384 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003385 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003386 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003387 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003388
Gilles Peskine4abf7412018-06-18 16:35:34 +02003389 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003390 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3391 * should be exact. */
3392 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3393 TEST_EQUAL( output_size,
3394 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003395 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003396
Gilles Peskine8817f612018-12-18 00:18:46 +01003397 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003399 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3400 psa_set_key_algorithm( &attributes, alg );
3401 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003402
Gilles Peskine049c7532019-05-15 20:22:09 +02003403 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3404 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003405
Gilles Peskinefe11b722018-12-18 00:24:04 +01003406 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3407 nonce->x, nonce->len,
3408 additional_data->x,
3409 additional_data->len,
3410 input_data->x, input_data->len,
3411 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003412 &output_length ),
3413 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003414
3415 if( PSA_SUCCESS == expected_result )
3416 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003417 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418
Gilles Peskine003a4a92019-05-14 16:09:40 +02003419 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3420 * should be exact. */
3421 TEST_EQUAL( input_data->len,
3422 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3423
Gilles Peskinefe11b722018-12-18 00:24:04 +01003424 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3425 nonce->x, nonce->len,
3426 additional_data->x,
3427 additional_data->len,
3428 output_data, output_length,
3429 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003430 &output_length2 ),
3431 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003432
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003433 ASSERT_COMPARE( input_data->x, input_data->len,
3434 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003436
Gilles Peskinea1cac842018-06-11 19:33:02 +02003437exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003438 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003439 mbedtls_free( output_data );
3440 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003441 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003442}
3443/* END_CASE */
3444
3445/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003446void aead_encrypt( int key_type_arg, data_t *key_data,
3447 int alg_arg,
3448 data_t *nonce,
3449 data_t *additional_data,
3450 data_t *input_data,
3451 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003452{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003453 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003454 psa_key_type_t key_type = key_type_arg;
3455 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003456 unsigned char *output_data = NULL;
3457 size_t output_size = 0;
3458 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003459 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003460 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003461
Gilles Peskine4abf7412018-06-18 16:35:34 +02003462 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003463 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3464 * should be exact. */
3465 TEST_EQUAL( output_size,
3466 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003467 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003468
Gilles Peskine8817f612018-12-18 00:18:46 +01003469 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003470
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003471 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3472 psa_set_key_algorithm( &attributes, alg );
3473 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003474
Gilles Peskine049c7532019-05-15 20:22:09 +02003475 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3476 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003477
Gilles Peskine8817f612018-12-18 00:18:46 +01003478 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3479 nonce->x, nonce->len,
3480 additional_data->x, additional_data->len,
3481 input_data->x, input_data->len,
3482 output_data, output_size,
3483 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003484
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003485 ASSERT_COMPARE( expected_result->x, expected_result->len,
3486 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003487
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003489 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003490 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003491 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003492}
3493/* END_CASE */
3494
3495/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003496void aead_decrypt( int key_type_arg, data_t *key_data,
3497 int alg_arg,
3498 data_t *nonce,
3499 data_t *additional_data,
3500 data_t *input_data,
3501 data_t *expected_data,
3502 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003503{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003504 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003505 psa_key_type_t key_type = key_type_arg;
3506 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003507 unsigned char *output_data = NULL;
3508 size_t output_size = 0;
3509 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003510 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003511 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003512 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003513
Gilles Peskine003a4a92019-05-14 16:09:40 +02003514 output_size = input_data->len - tag_length;
3515 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3516 * should be exact. */
3517 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3518 TEST_EQUAL( output_size,
3519 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003520 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003521
Gilles Peskine8817f612018-12-18 00:18:46 +01003522 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003523
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003524 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3525 psa_set_key_algorithm( &attributes, alg );
3526 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003527
Gilles Peskine049c7532019-05-15 20:22:09 +02003528 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3529 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003530
Gilles Peskinefe11b722018-12-18 00:24:04 +01003531 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3532 nonce->x, nonce->len,
3533 additional_data->x,
3534 additional_data->len,
3535 input_data->x, input_data->len,
3536 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003537 &output_length ),
3538 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003539
Gilles Peskine2d277862018-06-18 15:41:12 +02003540 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003541 ASSERT_COMPARE( expected_data->x, expected_data->len,
3542 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003543
Gilles Peskinea1cac842018-06-11 19:33:02 +02003544exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003545 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003546 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003547 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003548}
3549/* END_CASE */
3550
3551/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003552void signature_size( int type_arg,
3553 int bits,
3554 int alg_arg,
3555 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003556{
3557 psa_key_type_t type = type_arg;
3558 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003559 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003560 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003561exit:
3562 ;
3563}
3564/* END_CASE */
3565
3566/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003567void sign_deterministic( int key_type_arg, data_t *key_data,
3568 int alg_arg, data_t *input_data,
3569 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003570{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003571 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003572 psa_key_type_t key_type = key_type_arg;
3573 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003574 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003575 unsigned char *signature = NULL;
3576 size_t signature_size;
3577 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003578 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003579
Gilles Peskine8817f612018-12-18 00:18:46 +01003580 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003581
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003582 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3583 psa_set_key_algorithm( &attributes, alg );
3584 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003585
Gilles Peskine049c7532019-05-15 20:22:09 +02003586 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3587 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003588 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3589 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003590
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003591 /* Allocate a buffer which has the size advertized by the
3592 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003593 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3594 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003595 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003596 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003597 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003598
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003599 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003600 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3601 input_data->x, input_data->len,
3602 signature, signature_size,
3603 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003604 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003605 ASSERT_COMPARE( output_data->x, output_data->len,
3606 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003607
3608exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003609 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003610 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003611 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003612 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003613}
3614/* END_CASE */
3615
3616/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003617void sign_fail( int key_type_arg, data_t *key_data,
3618 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003619 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003620{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003621 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003622 psa_key_type_t key_type = key_type_arg;
3623 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003624 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003625 psa_status_t actual_status;
3626 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003627 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003628 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003629 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003630
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003631 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003632
Gilles Peskine8817f612018-12-18 00:18:46 +01003633 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003634
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003635 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3636 psa_set_key_algorithm( &attributes, alg );
3637 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003638
Gilles Peskine049c7532019-05-15 20:22:09 +02003639 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3640 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003641
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003642 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003643 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003644 signature, signature_size,
3645 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003646 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003647 /* The value of *signature_length is unspecified on error, but
3648 * whatever it is, it should be less than signature_size, so that
3649 * if the caller tries to read *signature_length bytes without
3650 * checking the error code then they don't overflow a buffer. */
3651 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003652
3653exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003654 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003655 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003656 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003657 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003658}
3659/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003660
3661/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003662void sign_verify( int key_type_arg, data_t *key_data,
3663 int alg_arg, data_t *input_data )
3664{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003665 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003666 psa_key_type_t key_type = key_type_arg;
3667 psa_algorithm_t alg = alg_arg;
3668 size_t key_bits;
3669 unsigned char *signature = NULL;
3670 size_t signature_size;
3671 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003672 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003673
Gilles Peskine8817f612018-12-18 00:18:46 +01003674 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003675
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003676 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3677 psa_set_key_algorithm( &attributes, alg );
3678 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003679
Gilles Peskine049c7532019-05-15 20:22:09 +02003680 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3681 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003682 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3683 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003684
3685 /* Allocate a buffer which has the size advertized by the
3686 * library. */
3687 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3688 key_bits, alg );
3689 TEST_ASSERT( signature_size != 0 );
3690 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003691 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003692
3693 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003694 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3695 input_data->x, input_data->len,
3696 signature, signature_size,
3697 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003698 /* Check that the signature length looks sensible. */
3699 TEST_ASSERT( signature_length <= signature_size );
3700 TEST_ASSERT( signature_length > 0 );
3701
3702 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003703 PSA_ASSERT( psa_asymmetric_verify(
3704 handle, alg,
3705 input_data->x, input_data->len,
3706 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003707
3708 if( input_data->len != 0 )
3709 {
3710 /* Flip a bit in the input and verify that the signature is now
3711 * detected as invalid. Flip a bit at the beginning, not at the end,
3712 * because ECDSA may ignore the last few bits of the input. */
3713 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003714 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3715 input_data->x, input_data->len,
3716 signature, signature_length ),
3717 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003718 }
3719
3720exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003721 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003722 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003723 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003724 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003725}
3726/* END_CASE */
3727
3728/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003729void asymmetric_verify( int key_type_arg, data_t *key_data,
3730 int alg_arg, data_t *hash_data,
3731 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003732{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003733 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003734 psa_key_type_t key_type = key_type_arg;
3735 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003736 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003737
Gilles Peskine69c12672018-06-28 00:07:19 +02003738 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3739
Gilles Peskine8817f612018-12-18 00:18:46 +01003740 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003741
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003742 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3743 psa_set_key_algorithm( &attributes, alg );
3744 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003745
Gilles Peskine049c7532019-05-15 20:22:09 +02003746 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3747 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003748
Gilles Peskine8817f612018-12-18 00:18:46 +01003749 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3750 hash_data->x, hash_data->len,
3751 signature_data->x,
3752 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003753exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003754 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003755 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003756 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003757}
3758/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003759
3760/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003761void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3762 int alg_arg, data_t *hash_data,
3763 data_t *signature_data,
3764 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003765{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003766 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003767 psa_key_type_t key_type = key_type_arg;
3768 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003769 psa_status_t actual_status;
3770 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003771 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003772
Gilles Peskine8817f612018-12-18 00:18:46 +01003773 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003774
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003775 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3776 psa_set_key_algorithm( &attributes, alg );
3777 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003778
Gilles Peskine049c7532019-05-15 20:22:09 +02003779 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3780 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003781
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003782 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003783 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003784 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003785 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003786
Gilles Peskinefe11b722018-12-18 00:24:04 +01003787 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003788
3789exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003790 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003791 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003792 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003793}
3794/* END_CASE */
3795
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003796/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003797void asymmetric_encrypt( int key_type_arg,
3798 data_t *key_data,
3799 int alg_arg,
3800 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003801 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003802 int expected_output_length_arg,
3803 int expected_status_arg )
3804{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003805 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003806 psa_key_type_t key_type = key_type_arg;
3807 psa_algorithm_t alg = alg_arg;
3808 size_t expected_output_length = expected_output_length_arg;
3809 size_t key_bits;
3810 unsigned char *output = NULL;
3811 size_t output_size;
3812 size_t output_length = ~0;
3813 psa_status_t actual_status;
3814 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003815 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003816
Gilles Peskine8817f612018-12-18 00:18:46 +01003817 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003818
Gilles Peskine656896e2018-06-29 19:12:28 +02003819 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003820 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3821 psa_set_key_algorithm( &attributes, alg );
3822 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003823 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3824 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003825
3826 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003827 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3828 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003829 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003830 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003831
3832 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003833 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003834 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003835 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003836 output, output_size,
3837 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003838 TEST_EQUAL( actual_status, expected_status );
3839 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003840
Gilles Peskine68428122018-06-30 18:42:41 +02003841 /* If the label is empty, the test framework puts a non-null pointer
3842 * in label->x. Test that a null pointer works as well. */
3843 if( label->len == 0 )
3844 {
3845 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003846 if( output_size != 0 )
3847 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003848 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003849 input_data->x, input_data->len,
3850 NULL, label->len,
3851 output, output_size,
3852 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003853 TEST_EQUAL( actual_status, expected_status );
3854 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003855 }
3856
Gilles Peskine656896e2018-06-29 19:12:28 +02003857exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003858 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003859 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003860 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003861 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02003862}
3863/* END_CASE */
3864
3865/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003866void asymmetric_encrypt_decrypt( int key_type_arg,
3867 data_t *key_data,
3868 int alg_arg,
3869 data_t *input_data,
3870 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003872 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003873 psa_key_type_t key_type = key_type_arg;
3874 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003875 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003877 size_t output_size;
3878 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003879 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003880 size_t output2_size;
3881 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003882 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883
Gilles Peskine8817f612018-12-18 00:18:46 +01003884 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003885
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003886 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3887 psa_set_key_algorithm( &attributes, alg );
3888 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003889
Gilles Peskine049c7532019-05-15 20:22:09 +02003890 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3891 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003892
3893 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003894 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3895 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003896 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003897 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003898 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003899 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003900
Gilles Peskineeebd7382018-06-08 18:11:54 +02003901 /* We test encryption by checking that encrypt-then-decrypt gives back
3902 * the original plaintext because of the non-optional random
3903 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003904 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3905 input_data->x, input_data->len,
3906 label->x, label->len,
3907 output, output_size,
3908 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003909 /* We don't know what ciphertext length to expect, but check that
3910 * it looks sensible. */
3911 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003912
Gilles Peskine8817f612018-12-18 00:18:46 +01003913 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3914 output, output_length,
3915 label->x, label->len,
3916 output2, output2_size,
3917 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003918 ASSERT_COMPARE( input_data->x, input_data->len,
3919 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003920
3921exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003922 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003923 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003924 mbedtls_free( output );
3925 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003926 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003927}
3928/* END_CASE */
3929
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003930/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003931void asymmetric_decrypt( int key_type_arg,
3932 data_t *key_data,
3933 int alg_arg,
3934 data_t *input_data,
3935 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003936 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003937{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003938 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003939 psa_key_type_t key_type = key_type_arg;
3940 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003941 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003942 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003943 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003944 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003945
Jaeden Amero412654a2019-02-06 12:57:46 +00003946 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003947 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003948
Gilles Peskine8817f612018-12-18 00:18:46 +01003949 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003950
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003951 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3952 psa_set_key_algorithm( &attributes, alg );
3953 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003954
Gilles Peskine049c7532019-05-15 20:22:09 +02003955 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3956 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003957
Gilles Peskine8817f612018-12-18 00:18:46 +01003958 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3959 input_data->x, input_data->len,
3960 label->x, 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 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003966
Gilles Peskine68428122018-06-30 18:42:41 +02003967 /* If the label is empty, the test framework puts a non-null pointer
3968 * in label->x. Test that a null pointer works as well. */
3969 if( label->len == 0 )
3970 {
3971 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003972 if( output_size != 0 )
3973 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003974 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3975 input_data->x, input_data->len,
3976 NULL, label->len,
3977 output,
3978 output_size,
3979 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003980 ASSERT_COMPARE( expected_data->x, expected_data->len,
3981 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003982 }
3983
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003984exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003985 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003986 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003987 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003988 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003989}
3990/* END_CASE */
3991
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003992/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003993void asymmetric_decrypt_fail( int key_type_arg,
3994 data_t *key_data,
3995 int alg_arg,
3996 data_t *input_data,
3997 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003998 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003999 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004000{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004001 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004002 psa_key_type_t key_type = key_type_arg;
4003 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004004 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004005 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004006 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004007 psa_status_t actual_status;
4008 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004009 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004010
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004011 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004012
Gilles Peskine8817f612018-12-18 00:18:46 +01004013 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004014
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004015 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4016 psa_set_key_algorithm( &attributes, alg );
4017 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004018
Gilles Peskine049c7532019-05-15 20:22:09 +02004019 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4020 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004021
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004022 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004023 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004024 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004025 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004026 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004027 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004028 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004029
Gilles Peskine68428122018-06-30 18:42:41 +02004030 /* If the label is empty, the test framework puts a non-null pointer
4031 * in label->x. Test that a null pointer works as well. */
4032 if( label->len == 0 )
4033 {
4034 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004035 if( output_size != 0 )
4036 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004037 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004038 input_data->x, input_data->len,
4039 NULL, label->len,
4040 output, output_size,
4041 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004042 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004043 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004044 }
4045
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004046exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004047 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004048 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004049 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004050 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004051}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004052/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004053
4054/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004055void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004056{
4057 /* Test each valid way of initializing the object, except for `= {0}`, as
4058 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4059 * though it's OK by the C standard. We could test for this, but we'd need
4060 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004061 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004062 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4063 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4064 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004065
4066 memset( &zero, 0, sizeof( zero ) );
4067
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004068 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004069 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004070 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004071 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004072 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004073 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004074 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004075
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004076 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004077 PSA_ASSERT( psa_key_derivation_abort(&func) );
4078 PSA_ASSERT( psa_key_derivation_abort(&init) );
4079 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004080}
4081/* END_CASE */
4082
4083/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004084void derive_setup( int key_type_arg,
4085 data_t *key_data,
4086 int alg_arg,
4087 data_t *salt,
4088 data_t *label,
4089 int requested_capacity_arg,
4090 int expected_status_arg )
4091{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004092 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004093 size_t key_type = key_type_arg;
4094 psa_algorithm_t alg = alg_arg;
4095 size_t requested_capacity = requested_capacity_arg;
4096 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004097 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004098 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004099
Gilles Peskine8817f612018-12-18 00:18:46 +01004100 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004101
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004102 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4103 psa_set_key_algorithm( &attributes, alg );
4104 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004105
Gilles Peskine049c7532019-05-15 20:22:09 +02004106 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4107 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004108
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004109 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004110 salt->x, salt->len,
4111 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004112 requested_capacity ),
4113 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004114
4115exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004116 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004117 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004118 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004119}
4120/* END_CASE */
4121
4122/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004123void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004124{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004125 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004126 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004127 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004128 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004129 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004130 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004131 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4132 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4133 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004134 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004135
Gilles Peskine8817f612018-12-18 00:18:46 +01004136 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004137
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004138 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4139 psa_set_key_algorithm( &attributes, alg );
4140 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004141
Gilles Peskine73676cb2019-05-15 20:15:10 +02004142 PSA_ASSERT( psa_import_key( &attributes,
4143 key_data, sizeof( key_data ),
4144 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004145
4146 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004147 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004148 NULL, 0,
4149 NULL, 0,
4150 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004151
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004152 /* state of operation shouldn't allow additional generation */
4153 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004154 NULL, 0,
4155 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004156 capacity ),
4157 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004158
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004159 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004160
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004161 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004162 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004163
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004164exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004165 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004166 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004167 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004168}
4169/* END_CASE */
4170
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004171/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004172void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004173{
4174 uint8_t output_buffer[16];
4175 size_t buffer_size = 16;
4176 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004177 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004178
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004179 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4180 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004181 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004182
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004183 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004184 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004185
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004186 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004187
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004188 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4189 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004190 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004191
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004192 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004193 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004194
4195exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004196 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004197}
4198/* END_CASE */
4199
4200/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004201void derive_output( int alg_arg,
4202 data_t *key_data,
4203 data_t *salt,
4204 data_t *label,
4205 int requested_capacity_arg,
4206 data_t *expected_output1,
4207 data_t *expected_output2 )
4208{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004209 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004210 psa_algorithm_t alg = alg_arg;
4211 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004212 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004213 uint8_t *expected_outputs[2] =
4214 {expected_output1->x, expected_output2->x};
4215 size_t output_sizes[2] =
4216 {expected_output1->len, expected_output2->len};
4217 size_t output_buffer_size = 0;
4218 uint8_t *output_buffer = NULL;
4219 size_t expected_capacity;
4220 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004221 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004222 psa_status_t status;
4223 unsigned i;
4224
4225 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4226 {
4227 if( output_sizes[i] > output_buffer_size )
4228 output_buffer_size = output_sizes[i];
4229 if( output_sizes[i] == 0 )
4230 expected_outputs[i] = NULL;
4231 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004232 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004233 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004234
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004235 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4236 psa_set_key_algorithm( &attributes, alg );
4237 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004238
Gilles Peskine049c7532019-05-15 20:22:09 +02004239 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4240 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004241
4242 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004243 if( PSA_ALG_IS_HKDF( alg ) )
4244 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004245 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4246 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004247 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004248 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004249 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004250 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004251 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004252 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004253 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004254 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004255 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004256 label->x, label->len ) );
4257 }
4258 else
4259 {
4260 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004261 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004262 salt->x, salt->len,
4263 label->x, label->len,
4264 requested_capacity ) );
4265 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004266 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004267 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004268 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004269 expected_capacity = requested_capacity;
4270
4271 /* Expansion phase. */
4272 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4273 {
4274 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004275 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004276 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004277 if( expected_capacity == 0 && output_sizes[i] == 0 )
4278 {
4279 /* Reading 0 bytes when 0 bytes are available can go either way. */
4280 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004281 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004282 continue;
4283 }
4284 else if( expected_capacity == 0 ||
4285 output_sizes[i] > expected_capacity )
4286 {
4287 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004288 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004289 expected_capacity = 0;
4290 continue;
4291 }
4292 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004293 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004294 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004295 ASSERT_COMPARE( output_buffer, output_sizes[i],
4296 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004297 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004298 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004299 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004300 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004301 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004302 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004303 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004304
4305exit:
4306 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004307 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004308 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004309 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004310}
4311/* END_CASE */
4312
4313/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004314void derive_full( int alg_arg,
4315 data_t *key_data,
4316 data_t *salt,
4317 data_t *label,
4318 int requested_capacity_arg )
4319{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004320 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004321 psa_algorithm_t alg = alg_arg;
4322 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004323 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004324 unsigned char output_buffer[16];
4325 size_t expected_capacity = requested_capacity;
4326 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004327 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004328
Gilles Peskine8817f612018-12-18 00:18:46 +01004329 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004330
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004331 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4332 psa_set_key_algorithm( &attributes, alg );
4333 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004334
Gilles Peskine049c7532019-05-15 20:22:09 +02004335 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4336 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004337
4338 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004339 if( PSA_ALG_IS_HKDF( alg ) )
4340 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004341 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4342 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004343 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004344 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004345 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004346 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004347 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004348 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004349 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004350 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004351 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004352 label->x, label->len ) );
4353 }
4354 else
4355 {
4356 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004357 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004358 salt->x, salt->len,
4359 label->x, label->len,
4360 requested_capacity ) );
4361 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004362 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004363 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004364 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004365
4366 /* Expansion phase. */
4367 while( current_capacity > 0 )
4368 {
4369 size_t read_size = sizeof( output_buffer );
4370 if( read_size > current_capacity )
4371 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004372 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004373 output_buffer,
4374 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004375 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004376 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004377 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004378 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004379 }
4380
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004381 /* Check that the operation refuses to go over capacity. */
4382 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004383 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004384
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004385 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004386
4387exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004388 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004389 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004390 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004391}
4392/* END_CASE */
4393
4394/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004395void derive_key_exercise( int alg_arg,
4396 data_t *key_data,
4397 data_t *salt,
4398 data_t *label,
4399 int derived_type_arg,
4400 int derived_bits_arg,
4401 int derived_usage_arg,
4402 int derived_alg_arg )
4403{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004404 psa_key_handle_t base_handle = 0;
4405 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004406 psa_algorithm_t alg = alg_arg;
4407 psa_key_type_t derived_type = derived_type_arg;
4408 size_t derived_bits = derived_bits_arg;
4409 psa_key_usage_t derived_usage = derived_usage_arg;
4410 psa_algorithm_t derived_alg = derived_alg_arg;
4411 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004412 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004413 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004414 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004415
Gilles Peskine8817f612018-12-18 00:18:46 +01004416 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004417
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004418 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4419 psa_set_key_algorithm( &attributes, alg );
4420 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004421 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4422 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004423
4424 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004425 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004426 salt->x, salt->len,
4427 label->x, label->len,
4428 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004429 psa_set_key_usage_flags( &attributes, derived_usage );
4430 psa_set_key_algorithm( &attributes, derived_alg );
4431 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004432 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004433 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004434 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004435
4436 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004437 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4438 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4439 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004440
4441 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004442 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004443 goto exit;
4444
4445exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004446 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004447 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004448 psa_destroy_key( base_handle );
4449 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004450 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004451}
4452/* END_CASE */
4453
4454/* BEGIN_CASE */
4455void derive_key_export( int alg_arg,
4456 data_t *key_data,
4457 data_t *salt,
4458 data_t *label,
4459 int bytes1_arg,
4460 int bytes2_arg )
4461{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004462 psa_key_handle_t base_handle = 0;
4463 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004464 psa_algorithm_t alg = alg_arg;
4465 size_t bytes1 = bytes1_arg;
4466 size_t bytes2 = bytes2_arg;
4467 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004468 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004469 uint8_t *output_buffer = NULL;
4470 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004471 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4472 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004473 size_t length;
4474
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004475 ASSERT_ALLOC( output_buffer, capacity );
4476 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004477 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004478
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004479 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4480 psa_set_key_algorithm( &base_attributes, alg );
4481 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004482 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4483 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004484
4485 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004486 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004487 salt->x, salt->len,
4488 label->x, label->len,
4489 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004490 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004491 output_buffer,
4492 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004493 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004494
4495 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004496 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004497 salt->x, salt->len,
4498 label->x, label->len,
4499 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004500 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4501 psa_set_key_algorithm( &derived_attributes, 0 );
4502 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004503 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004504 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004505 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004506 PSA_ASSERT( psa_export_key( derived_handle,
4507 export_buffer, bytes1,
4508 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004509 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004510 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004511 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004512 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004513 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004514 PSA_ASSERT( psa_export_key( derived_handle,
4515 export_buffer + bytes1, bytes2,
4516 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004517 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004518
4519 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004520 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4521 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004522
4523exit:
4524 mbedtls_free( output_buffer );
4525 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004526 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004527 psa_destroy_key( base_handle );
4528 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004529 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004530}
4531/* END_CASE */
4532
4533/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004534void key_agreement_setup( int alg_arg,
4535 int our_key_type_arg, data_t *our_key_data,
4536 data_t *peer_key_data,
4537 int expected_status_arg )
4538{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004539 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004540 psa_algorithm_t alg = alg_arg;
4541 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004542 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004543 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004544 psa_status_t expected_status = expected_status_arg;
4545 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004546
Gilles Peskine8817f612018-12-18 00:18:46 +01004547 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004548
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004549 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4550 psa_set_key_algorithm( &attributes, alg );
4551 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004552 PSA_ASSERT( psa_import_key( &attributes,
4553 our_key_data->x, our_key_data->len,
4554 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004555
Gilles Peskine77f40d82019-04-11 21:27:06 +02004556 /* The tests currently include inputs that should fail at either step.
4557 * Test cases that fail at the setup step should be changed to call
4558 * key_derivation_setup instead, and this function should be renamed
4559 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004560 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004561 if( status == PSA_SUCCESS )
4562 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004563 TEST_EQUAL( psa_key_derivation_key_agreement(
4564 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4565 our_key,
4566 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004567 expected_status );
4568 }
4569 else
4570 {
4571 TEST_ASSERT( status == expected_status );
4572 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004573
4574exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004575 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004576 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004577 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004578}
4579/* END_CASE */
4580
4581/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004582void raw_key_agreement( int alg_arg,
4583 int our_key_type_arg, data_t *our_key_data,
4584 data_t *peer_key_data,
4585 data_t *expected_output )
4586{
4587 psa_key_handle_t our_key = 0;
4588 psa_algorithm_t alg = alg_arg;
4589 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004590 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004591 unsigned char *output = NULL;
4592 size_t output_length = ~0;
4593
4594 ASSERT_ALLOC( output, expected_output->len );
4595 PSA_ASSERT( psa_crypto_init( ) );
4596
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004597 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4598 psa_set_key_algorithm( &attributes, alg );
4599 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004600 PSA_ASSERT( psa_import_key( &attributes,
4601 our_key_data->x, our_key_data->len,
4602 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004603
Gilles Peskinebe697d82019-05-16 18:00:41 +02004604 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4605 peer_key_data->x, peer_key_data->len,
4606 output, expected_output->len,
4607 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004608 ASSERT_COMPARE( output, output_length,
4609 expected_output->x, expected_output->len );
4610
4611exit:
4612 mbedtls_free( output );
4613 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004614 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004615}
4616/* END_CASE */
4617
4618/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004619void key_agreement_capacity( int alg_arg,
4620 int our_key_type_arg, data_t *our_key_data,
4621 data_t *peer_key_data,
4622 int expected_capacity_arg )
4623{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004624 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004625 psa_algorithm_t alg = alg_arg;
4626 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004627 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004628 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004629 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004630 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004631
Gilles Peskine8817f612018-12-18 00:18:46 +01004632 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004633
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004634 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4635 psa_set_key_algorithm( &attributes, alg );
4636 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004637 PSA_ASSERT( psa_import_key( &attributes,
4638 our_key_data->x, our_key_data->len,
4639 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004640
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004641 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004642 PSA_ASSERT( psa_key_derivation_key_agreement(
4643 &operation,
4644 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4645 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004646 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4647 {
4648 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004649 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004650 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004651 NULL, 0 ) );
4652 }
Gilles Peskine59685592018-09-18 12:11:34 +02004653
Gilles Peskinebf491972018-10-25 22:36:12 +02004654 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004655 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004656 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004657 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004658
Gilles Peskinebf491972018-10-25 22:36:12 +02004659 /* Test the actual capacity by reading the output. */
4660 while( actual_capacity > sizeof( output ) )
4661 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004662 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004663 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004664 actual_capacity -= sizeof( output );
4665 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004666 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004667 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004668 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004669 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004670
Gilles Peskine59685592018-09-18 12:11:34 +02004671exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004672 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004673 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004674 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004675}
4676/* END_CASE */
4677
4678/* BEGIN_CASE */
4679void key_agreement_output( int alg_arg,
4680 int our_key_type_arg, data_t *our_key_data,
4681 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004682 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004683{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004684 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004685 psa_algorithm_t alg = alg_arg;
4686 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004687 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004688 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004689 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004690
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004691 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4692 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004693
Gilles Peskine8817f612018-12-18 00:18:46 +01004694 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004695
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004696 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4697 psa_set_key_algorithm( &attributes, alg );
4698 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004699 PSA_ASSERT( psa_import_key( &attributes,
4700 our_key_data->x, our_key_data->len,
4701 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004702
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004703 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004704 PSA_ASSERT( psa_key_derivation_key_agreement(
4705 &operation,
4706 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4707 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004708 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4709 {
4710 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004711 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004712 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004713 NULL, 0 ) );
4714 }
Gilles Peskine59685592018-09-18 12:11:34 +02004715
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004716 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004717 actual_output,
4718 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004719 ASSERT_COMPARE( actual_output, expected_output1->len,
4720 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004721 if( expected_output2->len != 0 )
4722 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004723 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004724 actual_output,
4725 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004726 ASSERT_COMPARE( actual_output, expected_output2->len,
4727 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004728 }
Gilles Peskine59685592018-09-18 12:11:34 +02004729
4730exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004731 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004732 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004733 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004734 mbedtls_free( actual_output );
4735}
4736/* END_CASE */
4737
4738/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004739void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004740{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004741 size_t bytes = bytes_arg;
4742 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004743 unsigned char *output = NULL;
4744 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004745 size_t i;
4746 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004747
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004748 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4749 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004750 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004751
Gilles Peskine8817f612018-12-18 00:18:46 +01004752 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004753
Gilles Peskinea50d7392018-06-21 10:22:13 +02004754 /* Run several times, to ensure that every output byte will be
4755 * nonzero at least once with overwhelming probability
4756 * (2^(-8*number_of_runs)). */
4757 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004758 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004759 if( bytes != 0 )
4760 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004761 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004762
4763 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004764 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4765 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004766
4767 for( i = 0; i < bytes; i++ )
4768 {
4769 if( output[i] != 0 )
4770 ++changed[i];
4771 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004772 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004773
4774 /* Check that every byte was changed to nonzero at least once. This
4775 * validates that psa_generate_random is overwriting every byte of
4776 * the output buffer. */
4777 for( i = 0; i < bytes; i++ )
4778 {
4779 TEST_ASSERT( changed[i] != 0 );
4780 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004781
4782exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004783 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004784 mbedtls_free( output );
4785 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004786}
4787/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004788
4789/* BEGIN_CASE */
4790void generate_key( int type_arg,
4791 int bits_arg,
4792 int usage_arg,
4793 int alg_arg,
4794 int expected_status_arg )
4795{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004796 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004797 psa_key_type_t type = type_arg;
4798 psa_key_usage_t usage = usage_arg;
4799 size_t bits = bits_arg;
4800 psa_algorithm_t alg = alg_arg;
4801 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004802 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004803 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004804
Gilles Peskine8817f612018-12-18 00:18:46 +01004805 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004806
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004807 psa_set_key_usage_flags( &attributes, usage );
4808 psa_set_key_algorithm( &attributes, alg );
4809 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004810 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004811
4812 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004813 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004814 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004815 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004816
4817 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004818 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4819 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4820 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004821
Gilles Peskine818ca122018-06-20 18:16:48 +02004822 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004823 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004824 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004825
4826exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004827 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004828 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004829 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004830}
4831/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004832
Gilles Peskinee56e8782019-04-26 17:34:02 +02004833/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4834void generate_key_rsa( int bits_arg,
4835 data_t *e_arg,
4836 int expected_status_arg )
4837{
4838 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02004839 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02004840 size_t bits = bits_arg;
4841 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4842 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4843 psa_status_t expected_status = expected_status_arg;
4844 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4845 uint8_t *exported = NULL;
4846 size_t exported_size =
4847 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4848 size_t exported_length = SIZE_MAX;
4849 uint8_t *e_read_buffer = NULL;
4850 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004851 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004852 size_t e_read_length = SIZE_MAX;
4853
4854 if( e_arg->len == 0 ||
4855 ( e_arg->len == 3 &&
4856 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4857 {
4858 is_default_public_exponent = 1;
4859 e_read_size = 0;
4860 }
4861 ASSERT_ALLOC( e_read_buffer, e_read_size );
4862 ASSERT_ALLOC( exported, exported_size );
4863
4864 PSA_ASSERT( psa_crypto_init( ) );
4865
4866 psa_set_key_usage_flags( &attributes, usage );
4867 psa_set_key_algorithm( &attributes, alg );
4868 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4869 e_arg->x, e_arg->len ) );
4870 psa_set_key_bits( &attributes, bits );
4871
4872 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004873 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004874 if( expected_status != PSA_SUCCESS )
4875 goto exit;
4876
4877 /* Test the key information */
4878 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4879 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4880 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4881 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4882 e_read_buffer, e_read_size,
4883 &e_read_length ) );
4884 if( is_default_public_exponent )
4885 TEST_EQUAL( e_read_length, 0 );
4886 else
4887 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4888
4889 /* Do something with the key according to its type and permitted usage. */
4890 if( ! exercise_key( handle, usage, alg ) )
4891 goto exit;
4892
4893 /* Export the key and check the public exponent. */
4894 PSA_ASSERT( psa_export_public_key( handle,
4895 exported, exported_size,
4896 &exported_length ) );
4897 {
4898 uint8_t *p = exported;
4899 uint8_t *end = exported + exported_length;
4900 size_t len;
4901 /* RSAPublicKey ::= SEQUENCE {
4902 * modulus INTEGER, -- n
4903 * publicExponent INTEGER } -- e
4904 */
4905 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004906 MBEDTLS_ASN1_SEQUENCE |
4907 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004908 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4909 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4910 MBEDTLS_ASN1_INTEGER ) );
4911 if( len >= 1 && p[0] == 0 )
4912 {
4913 ++p;
4914 --len;
4915 }
4916 if( e_arg->len == 0 )
4917 {
4918 TEST_EQUAL( len, 3 );
4919 TEST_EQUAL( p[0], 1 );
4920 TEST_EQUAL( p[1], 0 );
4921 TEST_EQUAL( p[2], 1 );
4922 }
4923 else
4924 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4925 }
4926
4927exit:
4928 psa_reset_key_attributes( &attributes );
4929 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004930 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004931 mbedtls_free( e_read_buffer );
4932 mbedtls_free( exported );
4933}
4934/* END_CASE */
4935
Darryl Greend49a4992018-06-18 17:27:26 +01004936/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004937void persistent_key_load_key_from_storage( data_t *data,
4938 int type_arg, int bits_arg,
4939 int usage_flags_arg, int alg_arg,
4940 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004941{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004942 psa_key_id_t key_id = 1;
4943 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004944 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004945 psa_key_handle_t base_key = 0;
4946 psa_key_type_t type = type_arg;
4947 size_t bits = bits_arg;
4948 psa_key_usage_t usage_flags = usage_flags_arg;
4949 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004950 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004951 unsigned char *first_export = NULL;
4952 unsigned char *second_export = NULL;
4953 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4954 size_t first_exported_length;
4955 size_t second_exported_length;
4956
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004957 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4958 {
4959 ASSERT_ALLOC( first_export, export_size );
4960 ASSERT_ALLOC( second_export, export_size );
4961 }
Darryl Greend49a4992018-06-18 17:27:26 +01004962
Gilles Peskine8817f612018-12-18 00:18:46 +01004963 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004964
Gilles Peskinec87af662019-05-15 16:12:22 +02004965 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004966 psa_set_key_usage_flags( &attributes, usage_flags );
4967 psa_set_key_algorithm( &attributes, alg );
4968 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004969 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004970
Darryl Green0c6575a2018-11-07 16:05:30 +00004971 switch( generation_method )
4972 {
4973 case IMPORT_KEY:
4974 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004975 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4976 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004977 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004978
Darryl Green0c6575a2018-11-07 16:05:30 +00004979 case GENERATE_KEY:
4980 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004981 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004982 break;
4983
4984 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004985 {
4986 /* Create base key */
4987 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4988 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4989 psa_set_key_usage_flags( &base_attributes,
4990 PSA_KEY_USAGE_DERIVE );
4991 psa_set_key_algorithm( &base_attributes, derive_alg );
4992 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004993 PSA_ASSERT( psa_import_key( &base_attributes,
4994 data->x, data->len,
4995 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004996 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004997 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004998 PSA_ASSERT( psa_key_derivation_input_key(
4999 &operation,
5000 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005001 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005002 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005003 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005004 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5005 &operation,
5006 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005007 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005008 PSA_ASSERT( psa_destroy_key( base_key ) );
5009 base_key = 0;
5010 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005011 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005012 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005013 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005014
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005015 /* Export the key if permitted by the key policy. */
5016 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5017 {
5018 PSA_ASSERT( psa_export_key( handle,
5019 first_export, export_size,
5020 &first_exported_length ) );
5021 if( generation_method == IMPORT_KEY )
5022 ASSERT_COMPARE( data->x, data->len,
5023 first_export, first_exported_length );
5024 }
Darryl Greend49a4992018-06-18 17:27:26 +01005025
5026 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005027 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005028 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005029 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005030
Darryl Greend49a4992018-06-18 17:27:26 +01005031 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005032 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005033 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5034 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5035 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5036 PSA_KEY_LIFETIME_PERSISTENT );
5037 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5038 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5039 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5040 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005041
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005042 /* Export the key again if permitted by the key policy. */
5043 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005044 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005045 PSA_ASSERT( psa_export_key( handle,
5046 second_export, export_size,
5047 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005048 ASSERT_COMPARE( first_export, first_exported_length,
5049 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005050 }
5051
5052 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005053 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005054 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005055
5056exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005057 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005058 mbedtls_free( first_export );
5059 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005060 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005061 psa_destroy_key( base_key );
5062 if( handle == 0 )
5063 {
5064 /* In case there was a test failure after creating the persistent key
5065 * but while it was not open, try to re-open the persistent key
5066 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005067 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005068 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005069 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005070 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005071}
5072/* END_CASE */