blob: acc2f8c1879e4c559d6ef58cb39002b2b26d3f51 [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 Peskine0b352bc2018-06-28 00:16:11 +02001294 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001295 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001296
1297exit:
1298 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001299 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001300}
1301/* END_CASE */
1302
1303/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001304void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001305 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001306 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001307 int expected_bits,
1308 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001309 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001310 int canonical_input )
1311{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001312 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001313 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001314 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001315 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001316 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317 unsigned char *exported = NULL;
1318 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001319 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001320 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001321 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001322 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001323 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001324
Moran Pekercb088e72018-07-17 17:36:59 +03001325 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001326 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001327 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001328 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001329 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001330
Gilles Peskine4747d192019-04-17 15:05:45 +02001331 psa_set_key_usage_flags( &attributes, usage_arg );
1332 psa_set_key_algorithm( &attributes, alg );
1333 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001334
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001335 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001336 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001337
1338 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001339 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1340 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1341 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001342
1343 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001344 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001345 exported, export_size,
1346 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001347 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001348
1349 /* The exported length must be set by psa_export_key() to a value between 0
1350 * and export_size. On errors, the exported length must be 0. */
1351 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1352 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1353 TEST_ASSERT( exported_length <= export_size );
1354
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001355 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001356 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001357 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001358 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001359 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001360 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001361 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001362
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001363 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001364 goto exit;
1365
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001366 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001367 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001368 else
1369 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001370 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001371 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1372 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001373 PSA_ASSERT( psa_export_key( handle2,
1374 reexported,
1375 export_size,
1376 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001377 ASSERT_COMPARE( exported, exported_length,
1378 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001379 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001380 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001381 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001382
1383destroy:
1384 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001385 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001386 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001387
1388exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001389 mbedtls_free( exported );
1390 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001391 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001392 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001393}
1394/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001395
Moran Pekerf709f4a2018-06-06 17:26:04 +03001396/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001397void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001398{
Gilles Peskine8817f612018-12-18 00:18:46 +01001399 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001400 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001401
1402exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001403 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001404}
1405/* END_CASE */
1406
1407/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001408void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001409 int type_arg,
1410 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001411 int export_size_delta,
1412 int expected_export_status_arg,
1413 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001414{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001415 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001416 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001417 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001418 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001419 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001420 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001421 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001422 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001423 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001424
Gilles Peskine8817f612018-12-18 00:18:46 +01001425 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001426
Gilles Peskine4747d192019-04-17 15:05:45 +02001427 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1428 psa_set_key_algorithm( &attributes, alg );
1429 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001430
1431 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001432 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001433
Gilles Peskine49c25912018-10-29 15:15:31 +01001434 /* Export the public key */
1435 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001436 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001437 exported, export_size,
1438 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001439 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001440 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001441 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001442 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001443 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001444 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1445 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001446 TEST_ASSERT( expected_public_key->len <=
1447 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001448 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1449 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001450 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001451
1452exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001453 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001454 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001455 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001456 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001457}
1458/* END_CASE */
1459
Gilles Peskine20035e32018-02-03 22:44:14 +01001460/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001461void import_and_exercise_key( data_t *data,
1462 int type_arg,
1463 int bits_arg,
1464 int alg_arg )
1465{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001466 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001467 psa_key_type_t type = type_arg;
1468 size_t bits = bits_arg;
1469 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001470 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001471 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001472 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001473
Gilles Peskine8817f612018-12-18 00:18:46 +01001474 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001475
Gilles Peskine4747d192019-04-17 15:05:45 +02001476 psa_set_key_usage_flags( &attributes, usage );
1477 psa_set_key_algorithm( &attributes, alg );
1478 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001479
1480 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001481 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001482
1483 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001484 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1485 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1486 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001487
1488 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001489 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001490 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001491
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001492 PSA_ASSERT( psa_destroy_key( handle ) );
1493 test_operations_on_invalid_handle( handle );
1494
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001495exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001496 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001497 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001498 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001499}
1500/* END_CASE */
1501
1502/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001503void key_policy( int usage_arg, int alg_arg )
1504{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001505 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001506 psa_algorithm_t alg = alg_arg;
1507 psa_key_usage_t usage = usage_arg;
1508 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1509 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001510 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001511
1512 memset( key, 0x2a, sizeof( key ) );
1513
Gilles Peskine8817f612018-12-18 00:18:46 +01001514 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001515
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001516 psa_set_key_usage_flags( &attributes, usage );
1517 psa_set_key_algorithm( &attributes, alg );
1518 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001519
Gilles Peskine73676cb2019-05-15 20:15:10 +02001520 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001521
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001522 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1523 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1524 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1525 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001526
1527exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001528 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001529 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001530 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001531}
1532/* END_CASE */
1533
1534/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001535void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001536{
1537 /* Test each valid way of initializing the object, except for `= {0}`, as
1538 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1539 * though it's OK by the C standard. We could test for this, but we'd need
1540 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001541 psa_key_attributes_t func = psa_key_attributes_init( );
1542 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1543 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001544
1545 memset( &zero, 0, sizeof( zero ) );
1546
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001547 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1548 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1549 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001550
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001551 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1552 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1553 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1554
1555 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1556 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1557 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1558
1559 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1560 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1561 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1562
1563 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1564 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1565 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001566}
1567/* END_CASE */
1568
1569/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001570void mac_key_policy( int policy_usage,
1571 int policy_alg,
1572 int key_type,
1573 data_t *key_data,
1574 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001575{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001576 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001577 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001578 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001579 psa_status_t status;
1580 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001581
Gilles Peskine8817f612018-12-18 00:18:46 +01001582 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001583
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001584 psa_set_key_usage_flags( &attributes, policy_usage );
1585 psa_set_key_algorithm( &attributes, policy_alg );
1586 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001587
Gilles Peskine049c7532019-05-15 20:22:09 +02001588 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1589 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001590
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001591 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001592 if( policy_alg == exercise_alg &&
1593 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001594 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001595 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001596 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001597 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001598
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001599 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001600 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001601 if( policy_alg == exercise_alg &&
1602 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001603 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001604 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001605 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001606
1607exit:
1608 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001609 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001610 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001611}
1612/* END_CASE */
1613
1614/* BEGIN_CASE */
1615void cipher_key_policy( int policy_usage,
1616 int policy_alg,
1617 int key_type,
1618 data_t *key_data,
1619 int exercise_alg )
1620{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001621 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001622 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001623 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001624 psa_status_t status;
1625
Gilles Peskine8817f612018-12-18 00:18:46 +01001626 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001627
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001628 psa_set_key_usage_flags( &attributes, policy_usage );
1629 psa_set_key_algorithm( &attributes, policy_alg );
1630 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001631
Gilles Peskine049c7532019-05-15 20:22:09 +02001632 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1633 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001634
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001635 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001636 if( policy_alg == exercise_alg &&
1637 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001638 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001639 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001640 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001641 psa_cipher_abort( &operation );
1642
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001643 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001644 if( policy_alg == exercise_alg &&
1645 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001646 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001647 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001648 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001649
1650exit:
1651 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001652 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001653 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654}
1655/* END_CASE */
1656
1657/* BEGIN_CASE */
1658void aead_key_policy( int policy_usage,
1659 int policy_alg,
1660 int key_type,
1661 data_t *key_data,
1662 int nonce_length_arg,
1663 int tag_length_arg,
1664 int exercise_alg )
1665{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001666 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001667 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001668 psa_status_t status;
1669 unsigned char nonce[16] = {0};
1670 size_t nonce_length = nonce_length_arg;
1671 unsigned char tag[16];
1672 size_t tag_length = tag_length_arg;
1673 size_t output_length;
1674
1675 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1676 TEST_ASSERT( tag_length <= sizeof( tag ) );
1677
Gilles Peskine8817f612018-12-18 00:18:46 +01001678 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001679
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001680 psa_set_key_usage_flags( &attributes, policy_usage );
1681 psa_set_key_algorithm( &attributes, policy_alg );
1682 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001683
Gilles Peskine049c7532019-05-15 20:22:09 +02001684 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1685 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001686
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001687 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001688 nonce, nonce_length,
1689 NULL, 0,
1690 NULL, 0,
1691 tag, tag_length,
1692 &output_length );
1693 if( policy_alg == exercise_alg &&
1694 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001695 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001696 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001697 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001698
1699 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001700 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001701 nonce, nonce_length,
1702 NULL, 0,
1703 tag, tag_length,
1704 NULL, 0,
1705 &output_length );
1706 if( policy_alg == exercise_alg &&
1707 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001708 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001709 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001710 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001711
1712exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001713 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001714 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001715}
1716/* END_CASE */
1717
1718/* BEGIN_CASE */
1719void asymmetric_encryption_key_policy( int policy_usage,
1720 int policy_alg,
1721 int key_type,
1722 data_t *key_data,
1723 int exercise_alg )
1724{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001725 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001726 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001727 psa_status_t status;
1728 size_t key_bits;
1729 size_t buffer_length;
1730 unsigned char *buffer = NULL;
1731 size_t output_length;
1732
Gilles Peskine8817f612018-12-18 00:18:46 +01001733 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001734
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001735 psa_set_key_usage_flags( &attributes, policy_usage );
1736 psa_set_key_algorithm( &attributes, policy_alg );
1737 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001738
Gilles Peskine049c7532019-05-15 20:22:09 +02001739 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1740 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001741
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001742 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1743 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001744 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1745 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001746 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001747
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001748 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001749 NULL, 0,
1750 NULL, 0,
1751 buffer, buffer_length,
1752 &output_length );
1753 if( policy_alg == exercise_alg &&
1754 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001755 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001756 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001757 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001759 if( buffer_length != 0 )
1760 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001761 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762 buffer, buffer_length,
1763 NULL, 0,
1764 buffer, buffer_length,
1765 &output_length );
1766 if( policy_alg == exercise_alg &&
1767 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001768 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001769 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001770 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001771
1772exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001773 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001774 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001775 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001776 mbedtls_free( buffer );
1777}
1778/* END_CASE */
1779
1780/* BEGIN_CASE */
1781void asymmetric_signature_key_policy( int policy_usage,
1782 int policy_alg,
1783 int key_type,
1784 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001785 int exercise_alg,
1786 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001787{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001788 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001789 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001790 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001791 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1792 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1793 * compatible with the policy and `payload_length_arg` is supposed to be
1794 * a valid input length to sign. If `payload_length_arg <= 0`,
1795 * `exercise_alg` is supposed to be forbidden by the policy. */
1796 int compatible_alg = payload_length_arg > 0;
1797 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001798 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1799 size_t signature_length;
1800
Gilles Peskine8817f612018-12-18 00:18:46 +01001801 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001802
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001803 psa_set_key_usage_flags( &attributes, policy_usage );
1804 psa_set_key_algorithm( &attributes, policy_alg );
1805 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001806
Gilles Peskine049c7532019-05-15 20:22:09 +02001807 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1808 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001809
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001810 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001811 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001812 signature, sizeof( signature ),
1813 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001814 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001815 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001816 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001817 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001818
1819 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001820 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001821 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001823 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001824 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001825 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001826 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001827
1828exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001829 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001830 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001831}
1832/* END_CASE */
1833
1834/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001835void derive_key_policy( int policy_usage,
1836 int policy_alg,
1837 int key_type,
1838 data_t *key_data,
1839 int exercise_alg )
1840{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001841 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001842 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001843 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001844 psa_status_t status;
1845
Gilles Peskine8817f612018-12-18 00:18:46 +01001846 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001847
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001848 psa_set_key_usage_flags( &attributes, policy_usage );
1849 psa_set_key_algorithm( &attributes, policy_alg );
1850 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001851
Gilles Peskine049c7532019-05-15 20:22:09 +02001852 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1853 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001854
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001855 status = psa_key_derivation( &operation, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001856 exercise_alg,
1857 NULL, 0,
1858 NULL, 0,
1859 1 );
1860 if( policy_alg == exercise_alg &&
1861 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001862 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001863 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001864 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001865
1866exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001867 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001868 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001869 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001870}
1871/* END_CASE */
1872
1873/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001874void agreement_key_policy( int policy_usage,
1875 int policy_alg,
1876 int key_type_arg,
1877 data_t *key_data,
1878 int exercise_alg )
1879{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001880 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001881 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001882 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001883 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001884 psa_status_t status;
1885
Gilles Peskine8817f612018-12-18 00:18:46 +01001886 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001887
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001888 psa_set_key_usage_flags( &attributes, policy_usage );
1889 psa_set_key_algorithm( &attributes, policy_alg );
1890 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001891
Gilles Peskine049c7532019-05-15 20:22:09 +02001892 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1893 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001894
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001895 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1896 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001897
Gilles Peskine01d718c2018-09-18 12:01:02 +02001898 if( policy_alg == exercise_alg &&
1899 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001900 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001901 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001902 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001903
1904exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001905 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001906 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001907 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001908}
1909/* END_CASE */
1910
1911/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001912void key_policy_alg2( int key_type_arg, data_t *key_data,
1913 int usage_arg, int alg_arg, int alg2_arg )
1914{
1915 psa_key_handle_t handle = 0;
1916 psa_key_type_t key_type = key_type_arg;
1917 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1918 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1919 psa_key_usage_t usage = usage_arg;
1920 psa_algorithm_t alg = alg_arg;
1921 psa_algorithm_t alg2 = alg2_arg;
1922
1923 PSA_ASSERT( psa_crypto_init( ) );
1924
1925 psa_set_key_usage_flags( &attributes, usage );
1926 psa_set_key_algorithm( &attributes, alg );
1927 psa_set_key_enrollment_algorithm( &attributes, alg2 );
1928 psa_set_key_type( &attributes, key_type );
1929 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1930 &handle ) );
1931
1932 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1933 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1934 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1935 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
1936
1937 if( ! exercise_key( handle, usage, alg ) )
1938 goto exit;
1939 if( ! exercise_key( handle, usage, alg2 ) )
1940 goto exit;
1941
1942exit:
1943 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001944 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001945}
1946/* END_CASE */
1947
1948/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001949void raw_agreement_key_policy( int policy_usage,
1950 int policy_alg,
1951 int key_type_arg,
1952 data_t *key_data,
1953 int exercise_alg )
1954{
1955 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001956 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001957 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001958 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001959 psa_status_t status;
1960
1961 PSA_ASSERT( psa_crypto_init( ) );
1962
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001963 psa_set_key_usage_flags( &attributes, policy_usage );
1964 psa_set_key_algorithm( &attributes, policy_alg );
1965 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001966
Gilles Peskine049c7532019-05-15 20:22:09 +02001967 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1968 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001969
1970 status = raw_key_agreement_with_self( exercise_alg, handle );
1971
1972 if( policy_alg == exercise_alg &&
1973 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1974 PSA_ASSERT( status );
1975 else
1976 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1977
1978exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001979 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001980 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001981 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001982}
1983/* END_CASE */
1984
1985/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001986void copy_success( int source_usage_arg,
1987 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02001988 int type_arg, data_t *material,
1989 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001990 int target_usage_arg,
1991 int target_alg_arg, int target_alg2_arg,
1992 int expected_usage_arg,
1993 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001994{
Gilles Peskineca25db92019-04-19 11:43:08 +02001995 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1996 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001997 psa_key_usage_t expected_usage = expected_usage_arg;
1998 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001999 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002000 psa_key_handle_t source_handle = 0;
2001 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002002 uint8_t *export_buffer = NULL;
2003
Gilles Peskine57ab7212019-01-28 13:03:09 +01002004 PSA_ASSERT( psa_crypto_init( ) );
2005
Gilles Peskineca25db92019-04-19 11:43:08 +02002006 /* Prepare the source key. */
2007 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2008 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002009 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002010 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002011 PSA_ASSERT( psa_import_key( &source_attributes,
2012 material->x, material->len,
2013 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002014 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002015
Gilles Peskineca25db92019-04-19 11:43:08 +02002016 /* Prepare the target attributes. */
2017 if( copy_attributes )
2018 target_attributes = source_attributes;
2019 if( target_usage_arg != -1 )
2020 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2021 if( target_alg_arg != -1 )
2022 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002023 if( target_alg2_arg != -1 )
2024 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002025
2026 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002027 PSA_ASSERT( psa_copy_key( source_handle,
2028 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002029
2030 /* Destroy the source to ensure that this doesn't affect the target. */
2031 PSA_ASSERT( psa_destroy_key( source_handle ) );
2032
2033 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002034 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2035 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2036 psa_get_key_type( &target_attributes ) );
2037 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2038 psa_get_key_bits( &target_attributes ) );
2039 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2040 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002041 TEST_EQUAL( expected_alg2,
2042 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002043 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2044 {
2045 size_t length;
2046 ASSERT_ALLOC( export_buffer, material->len );
2047 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2048 material->len, &length ) );
2049 ASSERT_COMPARE( material->x, material->len,
2050 export_buffer, length );
2051 }
2052 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2053 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002054 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2055 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002056
2057 PSA_ASSERT( psa_close_key( target_handle ) );
2058
2059exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002060 psa_reset_key_attributes( &source_attributes );
2061 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002062 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002063 mbedtls_free( export_buffer );
2064}
2065/* END_CASE */
2066
2067/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002068void copy_fail( int source_usage_arg,
2069 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002070 int type_arg, data_t *material,
2071 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002072 int target_usage_arg,
2073 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002074 int expected_status_arg )
2075{
2076 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2077 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2078 psa_key_handle_t source_handle = 0;
2079 psa_key_handle_t target_handle = 0;
2080
2081 PSA_ASSERT( psa_crypto_init( ) );
2082
2083 /* Prepare the source key. */
2084 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2085 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002086 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002087 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002088 PSA_ASSERT( psa_import_key( &source_attributes,
2089 material->x, material->len,
2090 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002091
2092 /* Prepare the target attributes. */
2093 psa_set_key_type( &target_attributes, target_type_arg );
2094 psa_set_key_bits( &target_attributes, target_bits_arg );
2095 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2096 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002097 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002098
2099 /* Try to copy the key. */
2100 TEST_EQUAL( psa_copy_key( source_handle,
2101 &target_attributes, &target_handle ),
2102 expected_status_arg );
2103exit:
2104 psa_reset_key_attributes( &source_attributes );
2105 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002106 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002107}
2108/* END_CASE */
2109
2110/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002111void hash_operation_init( )
2112{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002113 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002114 /* Test each valid way of initializing the object, except for `= {0}`, as
2115 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2116 * though it's OK by the C standard. We could test for this, but we'd need
2117 * to supress the Clang warning for the test. */
2118 psa_hash_operation_t func = psa_hash_operation_init( );
2119 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2120 psa_hash_operation_t zero;
2121
2122 memset( &zero, 0, sizeof( zero ) );
2123
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002124 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002125 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2126 PSA_ERROR_BAD_STATE );
2127 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2128 PSA_ERROR_BAD_STATE );
2129 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2130 PSA_ERROR_BAD_STATE );
2131
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002132 /* A default hash operation should be abortable without error. */
2133 PSA_ASSERT( psa_hash_abort( &func ) );
2134 PSA_ASSERT( psa_hash_abort( &init ) );
2135 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002136}
2137/* END_CASE */
2138
2139/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002140void hash_setup( int alg_arg,
2141 int expected_status_arg )
2142{
2143 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002144 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002145 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002146 psa_status_t status;
2147
Gilles Peskine8817f612018-12-18 00:18:46 +01002148 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002149
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002150 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002151 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002152
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002153 /* Whether setup succeeded or failed, abort must succeed. */
2154 PSA_ASSERT( psa_hash_abort( &operation ) );
2155
2156 /* If setup failed, reproduce the failure, so as to
2157 * test the resulting state of the operation object. */
2158 if( status != PSA_SUCCESS )
2159 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2160
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002161 /* Now the operation object should be reusable. */
2162#if defined(KNOWN_SUPPORTED_HASH_ALG)
2163 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2164 PSA_ASSERT( psa_hash_abort( &operation ) );
2165#endif
2166
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002167exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002168 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002169}
2170/* END_CASE */
2171
2172/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002173void hash_bad_order( )
2174{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002175 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002176 unsigned char input[] = "";
2177 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002178 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002179 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2180 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2181 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002182 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002183 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002184 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002185
Gilles Peskine8817f612018-12-18 00:18:46 +01002186 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002187
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002188 /* Call setup twice in a row. */
2189 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2190 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2191 PSA_ERROR_BAD_STATE );
2192 PSA_ASSERT( psa_hash_abort( &operation ) );
2193
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002194 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002195 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002196 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002197 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002198
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002199 /* Call update after finish. */
2200 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2201 PSA_ASSERT( psa_hash_finish( &operation,
2202 hash, sizeof( hash ), &hash_len ) );
2203 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002204 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002205 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002206
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002207 /* Call verify without calling setup beforehand. */
2208 TEST_EQUAL( psa_hash_verify( &operation,
2209 valid_hash, sizeof( valid_hash ) ),
2210 PSA_ERROR_BAD_STATE );
2211 PSA_ASSERT( psa_hash_abort( &operation ) );
2212
2213 /* Call verify after finish. */
2214 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2215 PSA_ASSERT( psa_hash_finish( &operation,
2216 hash, sizeof( hash ), &hash_len ) );
2217 TEST_EQUAL( psa_hash_verify( &operation,
2218 valid_hash, sizeof( valid_hash ) ),
2219 PSA_ERROR_BAD_STATE );
2220 PSA_ASSERT( psa_hash_abort( &operation ) );
2221
2222 /* Call verify twice in a row. */
2223 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2224 PSA_ASSERT( psa_hash_verify( &operation,
2225 valid_hash, sizeof( valid_hash ) ) );
2226 TEST_EQUAL( psa_hash_verify( &operation,
2227 valid_hash, sizeof( valid_hash ) ),
2228 PSA_ERROR_BAD_STATE );
2229 PSA_ASSERT( psa_hash_abort( &operation ) );
2230
2231 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002232 TEST_EQUAL( psa_hash_finish( &operation,
2233 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002234 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002235 PSA_ASSERT( psa_hash_abort( &operation ) );
2236
2237 /* Call finish twice in a row. */
2238 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2239 PSA_ASSERT( psa_hash_finish( &operation,
2240 hash, sizeof( hash ), &hash_len ) );
2241 TEST_EQUAL( psa_hash_finish( &operation,
2242 hash, sizeof( hash ), &hash_len ),
2243 PSA_ERROR_BAD_STATE );
2244 PSA_ASSERT( psa_hash_abort( &operation ) );
2245
2246 /* Call finish after calling verify. */
2247 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2248 PSA_ASSERT( psa_hash_verify( &operation,
2249 valid_hash, sizeof( valid_hash ) ) );
2250 TEST_EQUAL( psa_hash_finish( &operation,
2251 hash, sizeof( hash ), &hash_len ),
2252 PSA_ERROR_BAD_STATE );
2253 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002254
2255exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002256 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002257}
2258/* END_CASE */
2259
itayzafrir27e69452018-11-01 14:26:34 +02002260/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2261void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002262{
2263 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002264 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2265 * appended to it */
2266 unsigned char hash[] = {
2267 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2268 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2269 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002270 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002271 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002272
Gilles Peskine8817f612018-12-18 00:18:46 +01002273 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002274
itayzafrir27e69452018-11-01 14:26:34 +02002275 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002276 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002277 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002278 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002279
itayzafrir27e69452018-11-01 14:26:34 +02002280 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002281 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002282 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002283 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002284
itayzafrir27e69452018-11-01 14:26:34 +02002285 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002286 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002287 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002288 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002289
itayzafrirec93d302018-10-18 18:01:10 +03002290exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002291 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002292}
2293/* END_CASE */
2294
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002295/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2296void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002297{
2298 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002299 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002300 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002301 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002302 size_t hash_len;
2303
Gilles Peskine8817f612018-12-18 00:18:46 +01002304 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002305
itayzafrir58028322018-10-25 10:22:01 +03002306 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002307 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002308 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002309 hash, expected_size - 1, &hash_len ),
2310 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002311
2312exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002313 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002314}
2315/* END_CASE */
2316
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002317/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2318void hash_clone_source_state( )
2319{
2320 psa_algorithm_t alg = PSA_ALG_SHA_256;
2321 unsigned char hash[PSA_HASH_MAX_SIZE];
2322 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2323 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2324 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2325 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2326 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2327 size_t hash_len;
2328
2329 PSA_ASSERT( psa_crypto_init( ) );
2330 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2331
2332 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2333 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2334 PSA_ASSERT( psa_hash_finish( &op_finished,
2335 hash, sizeof( hash ), &hash_len ) );
2336 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2337 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2338
2339 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2340 PSA_ERROR_BAD_STATE );
2341
2342 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2343 PSA_ASSERT( psa_hash_finish( &op_init,
2344 hash, sizeof( hash ), &hash_len ) );
2345 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2346 PSA_ASSERT( psa_hash_finish( &op_finished,
2347 hash, sizeof( hash ), &hash_len ) );
2348 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2349 PSA_ASSERT( psa_hash_finish( &op_aborted,
2350 hash, sizeof( hash ), &hash_len ) );
2351
2352exit:
2353 psa_hash_abort( &op_source );
2354 psa_hash_abort( &op_init );
2355 psa_hash_abort( &op_setup );
2356 psa_hash_abort( &op_finished );
2357 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002358 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002359}
2360/* END_CASE */
2361
2362/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2363void hash_clone_target_state( )
2364{
2365 psa_algorithm_t alg = PSA_ALG_SHA_256;
2366 unsigned char hash[PSA_HASH_MAX_SIZE];
2367 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2368 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2369 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2370 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2371 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2372 size_t hash_len;
2373
2374 PSA_ASSERT( psa_crypto_init( ) );
2375
2376 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2377 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2378 PSA_ASSERT( psa_hash_finish( &op_finished,
2379 hash, sizeof( hash ), &hash_len ) );
2380 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2381 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2382
2383 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2384 PSA_ASSERT( psa_hash_finish( &op_target,
2385 hash, sizeof( hash ), &hash_len ) );
2386
2387 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2388 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2389 PSA_ERROR_BAD_STATE );
2390 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2391 PSA_ERROR_BAD_STATE );
2392
2393exit:
2394 psa_hash_abort( &op_target );
2395 psa_hash_abort( &op_init );
2396 psa_hash_abort( &op_setup );
2397 psa_hash_abort( &op_finished );
2398 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002399 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002400}
2401/* END_CASE */
2402
itayzafrir58028322018-10-25 10:22:01 +03002403/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002404void mac_operation_init( )
2405{
Jaeden Amero252ef282019-02-15 14:05:35 +00002406 const uint8_t input[1] = { 0 };
2407
Jaeden Amero769ce272019-01-04 11:48:03 +00002408 /* Test each valid way of initializing the object, except for `= {0}`, as
2409 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2410 * though it's OK by the C standard. We could test for this, but we'd need
2411 * to supress the Clang warning for the test. */
2412 psa_mac_operation_t func = psa_mac_operation_init( );
2413 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2414 psa_mac_operation_t zero;
2415
2416 memset( &zero, 0, sizeof( zero ) );
2417
Jaeden Amero252ef282019-02-15 14:05:35 +00002418 /* A freshly-initialized MAC operation should not be usable. */
2419 TEST_EQUAL( psa_mac_update( &func,
2420 input, sizeof( input ) ),
2421 PSA_ERROR_BAD_STATE );
2422 TEST_EQUAL( psa_mac_update( &init,
2423 input, sizeof( input ) ),
2424 PSA_ERROR_BAD_STATE );
2425 TEST_EQUAL( psa_mac_update( &zero,
2426 input, sizeof( input ) ),
2427 PSA_ERROR_BAD_STATE );
2428
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002429 /* A default MAC operation should be abortable without error. */
2430 PSA_ASSERT( psa_mac_abort( &func ) );
2431 PSA_ASSERT( psa_mac_abort( &init ) );
2432 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002433}
2434/* END_CASE */
2435
2436/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002437void mac_setup( int key_type_arg,
2438 data_t *key,
2439 int alg_arg,
2440 int expected_status_arg )
2441{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002442 psa_key_type_t key_type = key_type_arg;
2443 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002444 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002445 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002446 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2447#if defined(KNOWN_SUPPORTED_MAC_ALG)
2448 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2449#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002450
Gilles Peskine8817f612018-12-18 00:18:46 +01002451 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002452
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002453 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2454 &operation, &status ) )
2455 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002456 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002457
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002458 /* The operation object should be reusable. */
2459#if defined(KNOWN_SUPPORTED_MAC_ALG)
2460 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2461 smoke_test_key_data,
2462 sizeof( smoke_test_key_data ),
2463 KNOWN_SUPPORTED_MAC_ALG,
2464 &operation, &status ) )
2465 goto exit;
2466 TEST_EQUAL( status, PSA_SUCCESS );
2467#endif
2468
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002469exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002470 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002471}
2472/* END_CASE */
2473
2474/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002475void mac_bad_order( )
2476{
2477 psa_key_handle_t handle = 0;
2478 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2479 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2480 const uint8_t key[] = {
2481 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2482 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2483 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002484 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002485 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2486 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2487 size_t sign_mac_length = 0;
2488 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2489 const uint8_t verify_mac[] = {
2490 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2491 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2492 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2493
2494 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002495 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2496 psa_set_key_algorithm( &attributes, alg );
2497 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002498
Gilles Peskine73676cb2019-05-15 20:15:10 +02002499 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002500
Jaeden Amero252ef282019-02-15 14:05:35 +00002501 /* Call update without calling setup beforehand. */
2502 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2503 PSA_ERROR_BAD_STATE );
2504 PSA_ASSERT( psa_mac_abort( &operation ) );
2505
2506 /* Call sign finish without calling setup beforehand. */
2507 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2508 &sign_mac_length),
2509 PSA_ERROR_BAD_STATE );
2510 PSA_ASSERT( psa_mac_abort( &operation ) );
2511
2512 /* Call verify finish without calling setup beforehand. */
2513 TEST_EQUAL( psa_mac_verify_finish( &operation,
2514 verify_mac, sizeof( verify_mac ) ),
2515 PSA_ERROR_BAD_STATE );
2516 PSA_ASSERT( psa_mac_abort( &operation ) );
2517
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002518 /* Call setup twice in a row. */
2519 PSA_ASSERT( psa_mac_sign_setup( &operation,
2520 handle, alg ) );
2521 TEST_EQUAL( psa_mac_sign_setup( &operation,
2522 handle, alg ),
2523 PSA_ERROR_BAD_STATE );
2524 PSA_ASSERT( psa_mac_abort( &operation ) );
2525
Jaeden Amero252ef282019-02-15 14:05:35 +00002526 /* Call update after sign finish. */
2527 PSA_ASSERT( psa_mac_sign_setup( &operation,
2528 handle, alg ) );
2529 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2530 PSA_ASSERT( psa_mac_sign_finish( &operation,
2531 sign_mac, sizeof( sign_mac ),
2532 &sign_mac_length ) );
2533 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2534 PSA_ERROR_BAD_STATE );
2535 PSA_ASSERT( psa_mac_abort( &operation ) );
2536
2537 /* Call update after verify finish. */
2538 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002539 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002540 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2541 PSA_ASSERT( psa_mac_verify_finish( &operation,
2542 verify_mac, sizeof( verify_mac ) ) );
2543 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2544 PSA_ERROR_BAD_STATE );
2545 PSA_ASSERT( psa_mac_abort( &operation ) );
2546
2547 /* Call sign finish twice in a row. */
2548 PSA_ASSERT( psa_mac_sign_setup( &operation,
2549 handle, alg ) );
2550 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2551 PSA_ASSERT( psa_mac_sign_finish( &operation,
2552 sign_mac, sizeof( sign_mac ),
2553 &sign_mac_length ) );
2554 TEST_EQUAL( psa_mac_sign_finish( &operation,
2555 sign_mac, sizeof( sign_mac ),
2556 &sign_mac_length ),
2557 PSA_ERROR_BAD_STATE );
2558 PSA_ASSERT( psa_mac_abort( &operation ) );
2559
2560 /* Call verify finish twice in a row. */
2561 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002562 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002563 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2564 PSA_ASSERT( psa_mac_verify_finish( &operation,
2565 verify_mac, sizeof( verify_mac ) ) );
2566 TEST_EQUAL( psa_mac_verify_finish( &operation,
2567 verify_mac, sizeof( verify_mac ) ),
2568 PSA_ERROR_BAD_STATE );
2569 PSA_ASSERT( psa_mac_abort( &operation ) );
2570
2571 /* Setup sign but try verify. */
2572 PSA_ASSERT( psa_mac_sign_setup( &operation,
2573 handle, alg ) );
2574 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2575 TEST_EQUAL( psa_mac_verify_finish( &operation,
2576 verify_mac, sizeof( verify_mac ) ),
2577 PSA_ERROR_BAD_STATE );
2578 PSA_ASSERT( psa_mac_abort( &operation ) );
2579
2580 /* Setup verify but try sign. */
2581 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002582 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002583 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2584 TEST_EQUAL( psa_mac_sign_finish( &operation,
2585 sign_mac, sizeof( sign_mac ),
2586 &sign_mac_length ),
2587 PSA_ERROR_BAD_STATE );
2588 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002589
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002590exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002591 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002592}
2593/* END_CASE */
2594
2595/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002596void mac_sign( int key_type_arg,
2597 data_t *key,
2598 int alg_arg,
2599 data_t *input,
2600 data_t *expected_mac )
2601{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002602 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002603 psa_key_type_t key_type = key_type_arg;
2604 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002605 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002606 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002607 /* Leave a little extra room in the output buffer. At the end of the
2608 * test, we'll check that the implementation didn't overwrite onto
2609 * this extra room. */
2610 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2611 size_t mac_buffer_size =
2612 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2613 size_t mac_length = 0;
2614
2615 memset( actual_mac, '+', sizeof( actual_mac ) );
2616 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2617 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2618
Gilles Peskine8817f612018-12-18 00:18:46 +01002619 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002620
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002621 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2622 psa_set_key_algorithm( &attributes, alg );
2623 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002624
Gilles Peskine73676cb2019-05-15 20:15:10 +02002625 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002626
2627 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002628 PSA_ASSERT( psa_mac_sign_setup( &operation,
2629 handle, alg ) );
2630 PSA_ASSERT( psa_mac_update( &operation,
2631 input->x, input->len ) );
2632 PSA_ASSERT( psa_mac_sign_finish( &operation,
2633 actual_mac, mac_buffer_size,
2634 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002635
2636 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002637 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2638 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002639
2640 /* Verify that the end of the buffer is untouched. */
2641 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2642 sizeof( actual_mac ) - mac_length ) );
2643
2644exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002645 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002646 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002647}
2648/* END_CASE */
2649
2650/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002651void mac_verify( int key_type_arg,
2652 data_t *key,
2653 int alg_arg,
2654 data_t *input,
2655 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002656{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002657 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002658 psa_key_type_t key_type = key_type_arg;
2659 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002660 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002661 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002662
Gilles Peskine69c12672018-06-28 00:07:19 +02002663 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2664
Gilles Peskine8817f612018-12-18 00:18:46 +01002665 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002666
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002667 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2668 psa_set_key_algorithm( &attributes, alg );
2669 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002670
Gilles Peskine73676cb2019-05-15 20:15:10 +02002671 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002672
Gilles Peskine8817f612018-12-18 00:18:46 +01002673 PSA_ASSERT( psa_mac_verify_setup( &operation,
2674 handle, alg ) );
2675 PSA_ASSERT( psa_destroy_key( handle ) );
2676 PSA_ASSERT( psa_mac_update( &operation,
2677 input->x, input->len ) );
2678 PSA_ASSERT( psa_mac_verify_finish( &operation,
2679 expected_mac->x,
2680 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002681
2682exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002683 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002684 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002685}
2686/* END_CASE */
2687
2688/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002689void cipher_operation_init( )
2690{
Jaeden Ameroab439972019-02-15 14:12:05 +00002691 const uint8_t input[1] = { 0 };
2692 unsigned char output[1] = { 0 };
2693 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002694 /* Test each valid way of initializing the object, except for `= {0}`, as
2695 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2696 * though it's OK by the C standard. We could test for this, but we'd need
2697 * to supress the Clang warning for the test. */
2698 psa_cipher_operation_t func = psa_cipher_operation_init( );
2699 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2700 psa_cipher_operation_t zero;
2701
2702 memset( &zero, 0, sizeof( zero ) );
2703
Jaeden Ameroab439972019-02-15 14:12:05 +00002704 /* A freshly-initialized cipher operation should not be usable. */
2705 TEST_EQUAL( psa_cipher_update( &func,
2706 input, sizeof( input ),
2707 output, sizeof( output ),
2708 &output_length ),
2709 PSA_ERROR_BAD_STATE );
2710 TEST_EQUAL( psa_cipher_update( &init,
2711 input, sizeof( input ),
2712 output, sizeof( output ),
2713 &output_length ),
2714 PSA_ERROR_BAD_STATE );
2715 TEST_EQUAL( psa_cipher_update( &zero,
2716 input, sizeof( input ),
2717 output, sizeof( output ),
2718 &output_length ),
2719 PSA_ERROR_BAD_STATE );
2720
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002721 /* A default cipher operation should be abortable without error. */
2722 PSA_ASSERT( psa_cipher_abort( &func ) );
2723 PSA_ASSERT( psa_cipher_abort( &init ) );
2724 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002725}
2726/* END_CASE */
2727
2728/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002729void cipher_setup( int key_type_arg,
2730 data_t *key,
2731 int alg_arg,
2732 int expected_status_arg )
2733{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002734 psa_key_type_t key_type = key_type_arg;
2735 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002736 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002737 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002738 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002739#if defined(KNOWN_SUPPORTED_MAC_ALG)
2740 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2741#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002742
Gilles Peskine8817f612018-12-18 00:18:46 +01002743 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002744
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002745 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2746 &operation, &status ) )
2747 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002748 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002749
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002750 /* The operation object should be reusable. */
2751#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2752 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2753 smoke_test_key_data,
2754 sizeof( smoke_test_key_data ),
2755 KNOWN_SUPPORTED_CIPHER_ALG,
2756 &operation, &status ) )
2757 goto exit;
2758 TEST_EQUAL( status, PSA_SUCCESS );
2759#endif
2760
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002761exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002762 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002763}
2764/* END_CASE */
2765
2766/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002767void cipher_bad_order( )
2768{
2769 psa_key_handle_t handle = 0;
2770 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2771 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002772 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002773 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2774 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2775 const uint8_t key[] = {
2776 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2777 0xaa, 0xaa, 0xaa, 0xaa };
2778 const uint8_t text[] = {
2779 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2780 0xbb, 0xbb, 0xbb, 0xbb };
2781 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2782 size_t length = 0;
2783
2784 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002785 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2786 psa_set_key_algorithm( &attributes, alg );
2787 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002788 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002789
2790
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002791 /* Call encrypt setup twice in a row. */
2792 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2793 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2794 PSA_ERROR_BAD_STATE );
2795 PSA_ASSERT( psa_cipher_abort( &operation ) );
2796
2797 /* Call decrypt setup twice in a row. */
2798 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2799 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2800 PSA_ERROR_BAD_STATE );
2801 PSA_ASSERT( psa_cipher_abort( &operation ) );
2802
Jaeden Ameroab439972019-02-15 14:12:05 +00002803 /* Generate an IV without calling setup beforehand. */
2804 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2805 buffer, sizeof( buffer ),
2806 &length ),
2807 PSA_ERROR_BAD_STATE );
2808 PSA_ASSERT( psa_cipher_abort( &operation ) );
2809
2810 /* Generate an IV twice in a row. */
2811 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2812 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2813 buffer, sizeof( buffer ),
2814 &length ) );
2815 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2816 buffer, sizeof( buffer ),
2817 &length ),
2818 PSA_ERROR_BAD_STATE );
2819 PSA_ASSERT( psa_cipher_abort( &operation ) );
2820
2821 /* Generate an IV after it's already set. */
2822 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2823 PSA_ASSERT( psa_cipher_set_iv( &operation,
2824 iv, sizeof( iv ) ) );
2825 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2826 buffer, sizeof( buffer ),
2827 &length ),
2828 PSA_ERROR_BAD_STATE );
2829 PSA_ASSERT( psa_cipher_abort( &operation ) );
2830
2831 /* Set an IV without calling setup beforehand. */
2832 TEST_EQUAL( psa_cipher_set_iv( &operation,
2833 iv, sizeof( iv ) ),
2834 PSA_ERROR_BAD_STATE );
2835 PSA_ASSERT( psa_cipher_abort( &operation ) );
2836
2837 /* Set an IV after it's already set. */
2838 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2839 PSA_ASSERT( psa_cipher_set_iv( &operation,
2840 iv, sizeof( iv ) ) );
2841 TEST_EQUAL( psa_cipher_set_iv( &operation,
2842 iv, sizeof( iv ) ),
2843 PSA_ERROR_BAD_STATE );
2844 PSA_ASSERT( psa_cipher_abort( &operation ) );
2845
2846 /* Set an IV after it's already generated. */
2847 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2848 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2849 buffer, sizeof( buffer ),
2850 &length ) );
2851 TEST_EQUAL( psa_cipher_set_iv( &operation,
2852 iv, sizeof( iv ) ),
2853 PSA_ERROR_BAD_STATE );
2854 PSA_ASSERT( psa_cipher_abort( &operation ) );
2855
2856 /* Call update without calling setup beforehand. */
2857 TEST_EQUAL( psa_cipher_update( &operation,
2858 text, sizeof( text ),
2859 buffer, sizeof( buffer ),
2860 &length ),
2861 PSA_ERROR_BAD_STATE );
2862 PSA_ASSERT( psa_cipher_abort( &operation ) );
2863
2864 /* Call update without an IV where an IV is required. */
2865 TEST_EQUAL( psa_cipher_update( &operation,
2866 text, sizeof( text ),
2867 buffer, sizeof( buffer ),
2868 &length ),
2869 PSA_ERROR_BAD_STATE );
2870 PSA_ASSERT( psa_cipher_abort( &operation ) );
2871
2872 /* Call update after finish. */
2873 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2874 PSA_ASSERT( psa_cipher_set_iv( &operation,
2875 iv, sizeof( iv ) ) );
2876 PSA_ASSERT( psa_cipher_finish( &operation,
2877 buffer, sizeof( buffer ), &length ) );
2878 TEST_EQUAL( psa_cipher_update( &operation,
2879 text, sizeof( text ),
2880 buffer, sizeof( buffer ),
2881 &length ),
2882 PSA_ERROR_BAD_STATE );
2883 PSA_ASSERT( psa_cipher_abort( &operation ) );
2884
2885 /* Call finish without calling setup beforehand. */
2886 TEST_EQUAL( psa_cipher_finish( &operation,
2887 buffer, sizeof( buffer ), &length ),
2888 PSA_ERROR_BAD_STATE );
2889 PSA_ASSERT( psa_cipher_abort( &operation ) );
2890
2891 /* Call finish without an IV where an IV is required. */
2892 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2893 /* Not calling update means we are encrypting an empty buffer, which is OK
2894 * for cipher modes with padding. */
2895 TEST_EQUAL( psa_cipher_finish( &operation,
2896 buffer, sizeof( buffer ), &length ),
2897 PSA_ERROR_BAD_STATE );
2898 PSA_ASSERT( psa_cipher_abort( &operation ) );
2899
2900 /* Call finish twice in a row. */
2901 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2902 PSA_ASSERT( psa_cipher_set_iv( &operation,
2903 iv, sizeof( iv ) ) );
2904 PSA_ASSERT( psa_cipher_finish( &operation,
2905 buffer, sizeof( buffer ), &length ) );
2906 TEST_EQUAL( psa_cipher_finish( &operation,
2907 buffer, sizeof( buffer ), &length ),
2908 PSA_ERROR_BAD_STATE );
2909 PSA_ASSERT( psa_cipher_abort( &operation ) );
2910
2911exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002912 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002913}
2914/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002915
Gilles Peskine50e586b2018-06-08 14:28:46 +02002916/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002917void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002918 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002919 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002920 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002921{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002922 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002923 psa_status_t status;
2924 psa_key_type_t key_type = key_type_arg;
2925 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002926 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002927 unsigned char *output = NULL;
2928 size_t output_buffer_size = 0;
2929 size_t function_output_length = 0;
2930 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002931 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002932 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933
Gilles Peskine8817f612018-12-18 00:18:46 +01002934 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002935
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002936 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2937 psa_set_key_algorithm( &attributes, alg );
2938 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002939
Gilles Peskine73676cb2019-05-15 20:15:10 +02002940 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002941
Gilles Peskine8817f612018-12-18 00:18:46 +01002942 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2943 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002944
Gilles Peskine423005e2019-05-06 15:22:57 +02002945 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002946 output_buffer_size = ( (size_t) input->len +
2947 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002948 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002949
Gilles Peskine8817f612018-12-18 00:18:46 +01002950 PSA_ASSERT( psa_cipher_update( &operation,
2951 input->x, input->len,
2952 output, output_buffer_size,
2953 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002954 total_output_length += function_output_length;
2955 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002956 output + total_output_length,
2957 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002958 &function_output_length );
2959 total_output_length += function_output_length;
2960
Gilles Peskinefe11b722018-12-18 00:24:04 +01002961 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002962 if( expected_status == PSA_SUCCESS )
2963 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002964 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002965 ASSERT_COMPARE( expected_output->x, expected_output->len,
2966 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002967 }
2968
2969exit:
2970 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002971 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002972 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002973}
2974/* END_CASE */
2975
2976/* BEGIN_CASE */
2977void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002978 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002979 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002980 int first_part_size_arg,
2981 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002982 data_t *expected_output )
2983{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002984 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002985 psa_key_type_t key_type = key_type_arg;
2986 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002987 size_t first_part_size = first_part_size_arg;
2988 size_t output1_length = output1_length_arg;
2989 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002990 unsigned char *output = NULL;
2991 size_t output_buffer_size = 0;
2992 size_t function_output_length = 0;
2993 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002994 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002995 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002996
Gilles Peskine8817f612018-12-18 00:18:46 +01002997 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002998
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002999 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3000 psa_set_key_algorithm( &attributes, alg );
3001 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003002
Gilles Peskine73676cb2019-05-15 20:15:10 +02003003 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003004
Gilles Peskine8817f612018-12-18 00:18:46 +01003005 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3006 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003007
Gilles Peskine423005e2019-05-06 15:22:57 +02003008 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003009 output_buffer_size = ( (size_t) input->len +
3010 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003011 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012
Gilles Peskinee0866522019-02-19 19:44:00 +01003013 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003014 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3015 output, output_buffer_size,
3016 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003017 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003018 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003019 PSA_ASSERT( psa_cipher_update( &operation,
3020 input->x + first_part_size,
3021 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003022 output + total_output_length,
3023 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003024 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003025 TEST_ASSERT( function_output_length == output2_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_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003028 output + total_output_length,
3029 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003030 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003031 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003032 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003033
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003034 ASSERT_COMPARE( expected_output->x, expected_output->len,
3035 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003036
3037exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003038 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003039 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003040 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041}
3042/* END_CASE */
3043
3044/* BEGIN_CASE */
3045void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003046 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003047 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003048 int first_part_size_arg,
3049 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003050 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003051{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003052 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003053
3054 psa_key_type_t key_type = key_type_arg;
3055 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003056 size_t first_part_size = first_part_size_arg;
3057 size_t output1_length = output1_length_arg;
3058 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003059 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003060 size_t output_buffer_size = 0;
3061 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003062 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003063 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003064 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065
Gilles Peskine8817f612018-12-18 00:18:46 +01003066 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003067
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003068 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3069 psa_set_key_algorithm( &attributes, alg );
3070 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003071
Gilles Peskine73676cb2019-05-15 20:15:10 +02003072 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003073
Gilles Peskine8817f612018-12-18 00:18:46 +01003074 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3075 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003076
Gilles Peskine423005e2019-05-06 15:22:57 +02003077 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003078
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003079 output_buffer_size = ( (size_t) input->len +
3080 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003081 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003082
Gilles Peskinee0866522019-02-19 19:44:00 +01003083 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003084 PSA_ASSERT( psa_cipher_update( &operation,
3085 input->x, first_part_size,
3086 output, output_buffer_size,
3087 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003088 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003089 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003090 PSA_ASSERT( psa_cipher_update( &operation,
3091 input->x + first_part_size,
3092 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003093 output + total_output_length,
3094 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003095 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003096 TEST_ASSERT( function_output_length == output2_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_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003099 output + total_output_length,
3100 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003101 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003102 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003103 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003104
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003105 ASSERT_COMPARE( expected_output->x, expected_output->len,
3106 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003107
3108exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003109 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003110 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003111 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003112}
3113/* END_CASE */
3114
Gilles Peskine50e586b2018-06-08 14:28:46 +02003115/* BEGIN_CASE */
3116void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003117 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003118 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003119 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003120{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003121 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003122 psa_status_t status;
3123 psa_key_type_t key_type = key_type_arg;
3124 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003125 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003126 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003127 size_t output_buffer_size = 0;
3128 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003129 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003130 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003131 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003132
Gilles Peskine8817f612018-12-18 00:18:46 +01003133 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003134
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003135 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3136 psa_set_key_algorithm( &attributes, alg );
3137 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003138
Gilles Peskine73676cb2019-05-15 20:15:10 +02003139 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003140
Gilles Peskine8817f612018-12-18 00:18:46 +01003141 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3142 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003143
Gilles Peskine423005e2019-05-06 15:22:57 +02003144 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003145
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003146 output_buffer_size = ( (size_t) input->len +
3147 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003148 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003149
Gilles Peskine8817f612018-12-18 00:18:46 +01003150 PSA_ASSERT( psa_cipher_update( &operation,
3151 input->x, input->len,
3152 output, output_buffer_size,
3153 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003154 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003155 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003156 output + total_output_length,
3157 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003158 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003159 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003160 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003161
3162 if( expected_status == PSA_SUCCESS )
3163 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003164 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003165 ASSERT_COMPARE( expected_output->x, expected_output->len,
3166 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003167 }
3168
Gilles Peskine50e586b2018-06-08 14:28:46 +02003169exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003170 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003171 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003172 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003173}
3174/* END_CASE */
3175
Gilles Peskine50e586b2018-06-08 14:28:46 +02003176/* BEGIN_CASE */
3177void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003178 data_t *key,
3179 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003180{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003181 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003182 psa_key_type_t key_type = key_type_arg;
3183 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003184 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003185 size_t iv_size = 16;
3186 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003187 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003188 size_t output1_size = 0;
3189 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003190 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003191 size_t output2_size = 0;
3192 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003193 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003194 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3195 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003196 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003197
Gilles Peskine8817f612018-12-18 00:18:46 +01003198 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003199
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003200 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3201 psa_set_key_algorithm( &attributes, alg );
3202 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003203
Gilles Peskine73676cb2019-05-15 20:15:10 +02003204 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003205
Gilles Peskine8817f612018-12-18 00:18:46 +01003206 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3207 handle, alg ) );
3208 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3209 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003210
Gilles Peskine8817f612018-12-18 00:18:46 +01003211 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3212 iv, iv_size,
3213 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003214 output1_size = ( (size_t) input->len +
3215 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003216 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003217
Gilles Peskine8817f612018-12-18 00:18:46 +01003218 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3219 output1, output1_size,
3220 &output1_length ) );
3221 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003222 output1 + output1_length,
3223 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003224 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003225
Gilles Peskine048b7f02018-06-08 14:20:49 +02003226 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003227
Gilles Peskine8817f612018-12-18 00:18:46 +01003228 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003229
3230 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003231 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003232
Gilles Peskine8817f612018-12-18 00:18:46 +01003233 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3234 iv, iv_length ) );
3235 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3236 output2, output2_size,
3237 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003238 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003239 PSA_ASSERT( psa_cipher_finish( &operation2,
3240 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003241 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003242 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003243
Gilles Peskine048b7f02018-06-08 14:20:49 +02003244 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003245
Gilles Peskine8817f612018-12-18 00:18:46 +01003246 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003247
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003248 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003249
3250exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003251 mbedtls_free( output1 );
3252 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003253 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003254 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003255}
3256/* END_CASE */
3257
3258/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003259void cipher_verify_output_multipart( int alg_arg,
3260 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003261 data_t *key,
3262 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003263 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003264{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003265 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003266 psa_key_type_t key_type = key_type_arg;
3267 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003268 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003269 unsigned char iv[16] = {0};
3270 size_t iv_size = 16;
3271 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003272 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003273 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003274 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003275 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003276 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003277 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003278 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003279 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3280 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003281 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003282
Gilles Peskine8817f612018-12-18 00:18:46 +01003283 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003284
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003285 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3286 psa_set_key_algorithm( &attributes, alg );
3287 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003288
Gilles Peskine73676cb2019-05-15 20:15:10 +02003289 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003290
Gilles Peskine8817f612018-12-18 00:18:46 +01003291 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3292 handle, alg ) );
3293 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3294 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003295
Gilles Peskine8817f612018-12-18 00:18:46 +01003296 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3297 iv, iv_size,
3298 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003299 output1_buffer_size = ( (size_t) input->len +
3300 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003301 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003302
Gilles Peskinee0866522019-02-19 19:44:00 +01003303 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003304
Gilles Peskine8817f612018-12-18 00:18:46 +01003305 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3306 output1, output1_buffer_size,
3307 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003308 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003309
Gilles Peskine8817f612018-12-18 00:18:46 +01003310 PSA_ASSERT( psa_cipher_update( &operation1,
3311 input->x + first_part_size,
3312 input->len - first_part_size,
3313 output1, output1_buffer_size,
3314 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003315 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003316
Gilles Peskine8817f612018-12-18 00:18:46 +01003317 PSA_ASSERT( psa_cipher_finish( &operation1,
3318 output1 + output1_length,
3319 output1_buffer_size - output1_length,
3320 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003321 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003322
Gilles Peskine8817f612018-12-18 00:18:46 +01003323 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003324
Gilles Peskine048b7f02018-06-08 14:20:49 +02003325 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003326 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003327
Gilles Peskine8817f612018-12-18 00:18:46 +01003328 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3329 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003330
Gilles Peskine8817f612018-12-18 00:18:46 +01003331 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3332 output2, output2_buffer_size,
3333 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003334 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003335
Gilles Peskine8817f612018-12-18 00:18:46 +01003336 PSA_ASSERT( psa_cipher_update( &operation2,
3337 output1 + first_part_size,
3338 output1_length - first_part_size,
3339 output2, output2_buffer_size,
3340 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003341 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003342
Gilles Peskine8817f612018-12-18 00:18:46 +01003343 PSA_ASSERT( psa_cipher_finish( &operation2,
3344 output2 + output2_length,
3345 output2_buffer_size - output2_length,
3346 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003347 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003348
Gilles Peskine8817f612018-12-18 00:18:46 +01003349 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003350
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003351 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003352
3353exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003354 mbedtls_free( output1 );
3355 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003356 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003357 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003358}
3359/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003360
Gilles Peskine20035e32018-02-03 22:44:14 +01003361/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003362void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003363 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003364 data_t *nonce,
3365 data_t *additional_data,
3366 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003367 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003368{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003369 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003370 psa_key_type_t key_type = key_type_arg;
3371 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003372 unsigned char *output_data = NULL;
3373 size_t output_size = 0;
3374 size_t output_length = 0;
3375 unsigned char *output_data2 = NULL;
3376 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003377 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003378 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003379 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003380
Gilles Peskine4abf7412018-06-18 16:35:34 +02003381 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003382 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3383 * should be exact. */
3384 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3385 TEST_EQUAL( output_size,
3386 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003387 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003388
Gilles Peskine8817f612018-12-18 00:18:46 +01003389 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003390
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003391 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3392 psa_set_key_algorithm( &attributes, alg );
3393 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003394
Gilles Peskine049c7532019-05-15 20:22:09 +02003395 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3396 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003397
Gilles Peskinefe11b722018-12-18 00:24:04 +01003398 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3399 nonce->x, nonce->len,
3400 additional_data->x,
3401 additional_data->len,
3402 input_data->x, input_data->len,
3403 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003404 &output_length ),
3405 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003406
3407 if( PSA_SUCCESS == expected_result )
3408 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003409 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003410
Gilles Peskine003a4a92019-05-14 16:09:40 +02003411 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3412 * should be exact. */
3413 TEST_EQUAL( input_data->len,
3414 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3415
Gilles Peskinefe11b722018-12-18 00:24:04 +01003416 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3417 nonce->x, nonce->len,
3418 additional_data->x,
3419 additional_data->len,
3420 output_data, output_length,
3421 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003422 &output_length2 ),
3423 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003424
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003425 ASSERT_COMPARE( input_data->x, input_data->len,
3426 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003427 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003428
Gilles Peskinea1cac842018-06-11 19:33:02 +02003429exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003430 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003431 mbedtls_free( output_data );
3432 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003433 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003434}
3435/* END_CASE */
3436
3437/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003438void aead_encrypt( int key_type_arg, data_t *key_data,
3439 int alg_arg,
3440 data_t *nonce,
3441 data_t *additional_data,
3442 data_t *input_data,
3443 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003444{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003445 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003446 psa_key_type_t key_type = key_type_arg;
3447 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003448 unsigned char *output_data = NULL;
3449 size_t output_size = 0;
3450 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003451 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003452 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003453
Gilles Peskine4abf7412018-06-18 16:35:34 +02003454 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003455 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3456 * should be exact. */
3457 TEST_EQUAL( output_size,
3458 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003459 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003460
Gilles Peskine8817f612018-12-18 00:18:46 +01003461 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003462
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003463 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3464 psa_set_key_algorithm( &attributes, alg );
3465 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003466
Gilles Peskine049c7532019-05-15 20:22:09 +02003467 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3468 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003469
Gilles Peskine8817f612018-12-18 00:18:46 +01003470 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3471 nonce->x, nonce->len,
3472 additional_data->x, additional_data->len,
3473 input_data->x, input_data->len,
3474 output_data, output_size,
3475 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003476
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003477 ASSERT_COMPARE( expected_result->x, expected_result->len,
3478 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003479
Gilles Peskinea1cac842018-06-11 19:33:02 +02003480exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003481 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003482 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003483 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003484}
3485/* END_CASE */
3486
3487/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003488void aead_decrypt( int key_type_arg, data_t *key_data,
3489 int alg_arg,
3490 data_t *nonce,
3491 data_t *additional_data,
3492 data_t *input_data,
3493 data_t *expected_data,
3494 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003495{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003496 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003497 psa_key_type_t key_type = key_type_arg;
3498 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003499 unsigned char *output_data = NULL;
3500 size_t output_size = 0;
3501 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003502 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003503 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003504 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003505
Gilles Peskine003a4a92019-05-14 16:09:40 +02003506 output_size = input_data->len - tag_length;
3507 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3508 * should be exact. */
3509 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3510 TEST_EQUAL( output_size,
3511 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003512 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003513
Gilles Peskine8817f612018-12-18 00:18:46 +01003514 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003515
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003516 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3517 psa_set_key_algorithm( &attributes, alg );
3518 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003519
Gilles Peskine049c7532019-05-15 20:22:09 +02003520 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3521 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003522
Gilles Peskinefe11b722018-12-18 00:24:04 +01003523 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3524 nonce->x, nonce->len,
3525 additional_data->x,
3526 additional_data->len,
3527 input_data->x, input_data->len,
3528 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003529 &output_length ),
3530 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003531
Gilles Peskine2d277862018-06-18 15:41:12 +02003532 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003533 ASSERT_COMPARE( expected_data->x, expected_data->len,
3534 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003535
Gilles Peskinea1cac842018-06-11 19:33:02 +02003536exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003537 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003538 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003539 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003540}
3541/* END_CASE */
3542
3543/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003544void signature_size( int type_arg,
3545 int bits,
3546 int alg_arg,
3547 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003548{
3549 psa_key_type_t type = type_arg;
3550 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003551 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003552 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003553exit:
3554 ;
3555}
3556/* END_CASE */
3557
3558/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003559void sign_deterministic( int key_type_arg, data_t *key_data,
3560 int alg_arg, data_t *input_data,
3561 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003562{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003563 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003564 psa_key_type_t key_type = key_type_arg;
3565 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003566 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003567 unsigned char *signature = NULL;
3568 size_t signature_size;
3569 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003570 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003571
Gilles Peskine8817f612018-12-18 00:18:46 +01003572 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003573
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003574 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3575 psa_set_key_algorithm( &attributes, alg );
3576 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003577
Gilles Peskine049c7532019-05-15 20:22:09 +02003578 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3579 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003580 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3581 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003582
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003583 /* Allocate a buffer which has the size advertized by the
3584 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003585 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3586 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003587 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003588 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003589 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003590
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003591 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003592 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3593 input_data->x, input_data->len,
3594 signature, signature_size,
3595 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003596 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003597 ASSERT_COMPARE( output_data->x, output_data->len,
3598 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003599
3600exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003601 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003602 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003603 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003604 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003605}
3606/* END_CASE */
3607
3608/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003609void sign_fail( int key_type_arg, data_t *key_data,
3610 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003611 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003612{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003613 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003614 psa_key_type_t key_type = key_type_arg;
3615 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003616 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003617 psa_status_t actual_status;
3618 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003619 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003620 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003621 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003622
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003623 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003624
Gilles Peskine8817f612018-12-18 00:18:46 +01003625 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003626
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003627 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3628 psa_set_key_algorithm( &attributes, alg );
3629 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003630
Gilles Peskine049c7532019-05-15 20:22:09 +02003631 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3632 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003633
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003634 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003635 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003636 signature, signature_size,
3637 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003638 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003639 /* The value of *signature_length is unspecified on error, but
3640 * whatever it is, it should be less than signature_size, so that
3641 * if the caller tries to read *signature_length bytes without
3642 * checking the error code then they don't overflow a buffer. */
3643 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003644
3645exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003646 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003647 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003648 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003649 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003650}
3651/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003652
3653/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003654void sign_verify( int key_type_arg, data_t *key_data,
3655 int alg_arg, data_t *input_data )
3656{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003657 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003658 psa_key_type_t key_type = key_type_arg;
3659 psa_algorithm_t alg = alg_arg;
3660 size_t key_bits;
3661 unsigned char *signature = NULL;
3662 size_t signature_size;
3663 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003664 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003665
Gilles Peskine8817f612018-12-18 00:18:46 +01003666 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003667
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003668 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3669 psa_set_key_algorithm( &attributes, alg );
3670 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003671
Gilles Peskine049c7532019-05-15 20:22:09 +02003672 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3673 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003674 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3675 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003676
3677 /* Allocate a buffer which has the size advertized by the
3678 * library. */
3679 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3680 key_bits, alg );
3681 TEST_ASSERT( signature_size != 0 );
3682 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003683 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003684
3685 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003686 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3687 input_data->x, input_data->len,
3688 signature, signature_size,
3689 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003690 /* Check that the signature length looks sensible. */
3691 TEST_ASSERT( signature_length <= signature_size );
3692 TEST_ASSERT( signature_length > 0 );
3693
3694 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003695 PSA_ASSERT( psa_asymmetric_verify(
3696 handle, alg,
3697 input_data->x, input_data->len,
3698 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003699
3700 if( input_data->len != 0 )
3701 {
3702 /* Flip a bit in the input and verify that the signature is now
3703 * detected as invalid. Flip a bit at the beginning, not at the end,
3704 * because ECDSA may ignore the last few bits of the input. */
3705 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003706 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3707 input_data->x, input_data->len,
3708 signature, signature_length ),
3709 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003710 }
3711
3712exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003713 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003714 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003715 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003716 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003717}
3718/* END_CASE */
3719
3720/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003721void asymmetric_verify( int key_type_arg, data_t *key_data,
3722 int alg_arg, data_t *hash_data,
3723 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003724{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003725 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003726 psa_key_type_t key_type = key_type_arg;
3727 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003728 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003729
Gilles Peskine69c12672018-06-28 00:07:19 +02003730 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3731
Gilles Peskine8817f612018-12-18 00:18:46 +01003732 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003733
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003734 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3735 psa_set_key_algorithm( &attributes, alg );
3736 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003737
Gilles Peskine049c7532019-05-15 20:22:09 +02003738 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3739 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003740
Gilles Peskine8817f612018-12-18 00:18:46 +01003741 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3742 hash_data->x, hash_data->len,
3743 signature_data->x,
3744 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003745exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003746 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003747 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003748 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003749}
3750/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003751
3752/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003753void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3754 int alg_arg, data_t *hash_data,
3755 data_t *signature_data,
3756 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003757{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003758 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003759 psa_key_type_t key_type = key_type_arg;
3760 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003761 psa_status_t actual_status;
3762 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003763 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003764
Gilles Peskine8817f612018-12-18 00:18:46 +01003765 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003766
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003767 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3768 psa_set_key_algorithm( &attributes, alg );
3769 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003770
Gilles Peskine049c7532019-05-15 20:22:09 +02003771 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3772 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003773
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003774 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003775 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003776 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003777 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003778
Gilles Peskinefe11b722018-12-18 00:24:04 +01003779 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003780
3781exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003782 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003783 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003784 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003785}
3786/* END_CASE */
3787
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003788/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003789void asymmetric_encrypt( int key_type_arg,
3790 data_t *key_data,
3791 int alg_arg,
3792 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003793 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003794 int expected_output_length_arg,
3795 int expected_status_arg )
3796{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003797 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003798 psa_key_type_t key_type = key_type_arg;
3799 psa_algorithm_t alg = alg_arg;
3800 size_t expected_output_length = expected_output_length_arg;
3801 size_t key_bits;
3802 unsigned char *output = NULL;
3803 size_t output_size;
3804 size_t output_length = ~0;
3805 psa_status_t actual_status;
3806 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003807 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003808
Gilles Peskine8817f612018-12-18 00:18:46 +01003809 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003810
Gilles Peskine656896e2018-06-29 19:12:28 +02003811 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003812 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3813 psa_set_key_algorithm( &attributes, alg );
3814 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003815 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3816 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003817
3818 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003819 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3820 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003821 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003822 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003823
3824 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003825 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003826 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003827 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003828 output, output_size,
3829 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003830 TEST_EQUAL( actual_status, expected_status );
3831 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003832
Gilles Peskine68428122018-06-30 18:42:41 +02003833 /* If the label is empty, the test framework puts a non-null pointer
3834 * in label->x. Test that a null pointer works as well. */
3835 if( label->len == 0 )
3836 {
3837 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003838 if( output_size != 0 )
3839 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003840 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003841 input_data->x, input_data->len,
3842 NULL, label->len,
3843 output, output_size,
3844 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003845 TEST_EQUAL( actual_status, expected_status );
3846 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003847 }
3848
Gilles Peskine656896e2018-06-29 19:12:28 +02003849exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003850 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003851 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003852 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003853 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02003854}
3855/* END_CASE */
3856
3857/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003858void asymmetric_encrypt_decrypt( int key_type_arg,
3859 data_t *key_data,
3860 int alg_arg,
3861 data_t *input_data,
3862 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003863{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003864 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003865 psa_key_type_t key_type = key_type_arg;
3866 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003867 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003868 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003869 size_t output_size;
3870 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003871 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003872 size_t output2_size;
3873 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003874 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003875
Gilles Peskine8817f612018-12-18 00:18:46 +01003876 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003877
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003878 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3879 psa_set_key_algorithm( &attributes, alg );
3880 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003881
Gilles Peskine049c7532019-05-15 20:22:09 +02003882 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3883 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003884
3885 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003886 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3887 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003888 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003889 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003890 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003891 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003892
Gilles Peskineeebd7382018-06-08 18:11:54 +02003893 /* We test encryption by checking that encrypt-then-decrypt gives back
3894 * the original plaintext because of the non-optional random
3895 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003896 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3897 input_data->x, input_data->len,
3898 label->x, label->len,
3899 output, output_size,
3900 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003901 /* We don't know what ciphertext length to expect, but check that
3902 * it looks sensible. */
3903 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003904
Gilles Peskine8817f612018-12-18 00:18:46 +01003905 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3906 output, output_length,
3907 label->x, label->len,
3908 output2, output2_size,
3909 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003910 ASSERT_COMPARE( input_data->x, input_data->len,
3911 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003912
3913exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003914 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003915 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003916 mbedtls_free( output );
3917 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003918 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003919}
3920/* END_CASE */
3921
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003922/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003923void asymmetric_decrypt( int key_type_arg,
3924 data_t *key_data,
3925 int alg_arg,
3926 data_t *input_data,
3927 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003928 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003929{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003930 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003931 psa_key_type_t key_type = key_type_arg;
3932 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003933 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003934 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003935 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003936 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003937
Jaeden Amero412654a2019-02-06 12:57:46 +00003938 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003939 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003940
Gilles Peskine8817f612018-12-18 00:18:46 +01003941 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003942
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003943 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3944 psa_set_key_algorithm( &attributes, alg );
3945 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003946
Gilles Peskine049c7532019-05-15 20:22:09 +02003947 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3948 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003949
Gilles Peskine8817f612018-12-18 00:18:46 +01003950 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3951 input_data->x, input_data->len,
3952 label->x, label->len,
3953 output,
3954 output_size,
3955 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003956 ASSERT_COMPARE( expected_data->x, expected_data->len,
3957 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003958
Gilles Peskine68428122018-06-30 18:42:41 +02003959 /* If the label is empty, the test framework puts a non-null pointer
3960 * in label->x. Test that a null pointer works as well. */
3961 if( label->len == 0 )
3962 {
3963 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003964 if( output_size != 0 )
3965 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003966 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3967 input_data->x, input_data->len,
3968 NULL, label->len,
3969 output,
3970 output_size,
3971 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003972 ASSERT_COMPARE( expected_data->x, expected_data->len,
3973 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003974 }
3975
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003976exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003977 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003978 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003979 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003980 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003981}
3982/* END_CASE */
3983
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003984/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003985void asymmetric_decrypt_fail( int key_type_arg,
3986 data_t *key_data,
3987 int alg_arg,
3988 data_t *input_data,
3989 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003990 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003991 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003992{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003993 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003994 psa_key_type_t key_type = key_type_arg;
3995 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003996 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003997 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003998 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003999 psa_status_t actual_status;
4000 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004001 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004002
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004003 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004004
Gilles Peskine8817f612018-12-18 00:18:46 +01004005 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004006
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004007 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4008 psa_set_key_algorithm( &attributes, alg );
4009 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004010
Gilles Peskine049c7532019-05-15 20:22:09 +02004011 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4012 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004013
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004014 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004015 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004016 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004017 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004018 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004019 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004020 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004021
Gilles Peskine68428122018-06-30 18:42:41 +02004022 /* If the label is empty, the test framework puts a non-null pointer
4023 * in label->x. Test that a null pointer works as well. */
4024 if( label->len == 0 )
4025 {
4026 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004027 if( output_size != 0 )
4028 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004029 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004030 input_data->x, input_data->len,
4031 NULL, label->len,
4032 output, output_size,
4033 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004034 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004035 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004036 }
4037
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004038exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004039 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004040 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004041 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004042 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004043}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004044/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004045
4046/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004047void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004048{
4049 /* Test each valid way of initializing the object, except for `= {0}`, as
4050 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4051 * though it's OK by the C standard. We could test for this, but we'd need
4052 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004053 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004054 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4055 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4056 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004057
4058 memset( &zero, 0, sizeof( zero ) );
4059
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004060 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004061 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004062 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004063 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004064 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004065 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004066 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004067
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004068 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004069 PSA_ASSERT( psa_key_derivation_abort(&func) );
4070 PSA_ASSERT( psa_key_derivation_abort(&init) );
4071 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004072}
4073/* END_CASE */
4074
4075/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004076void derive_setup( int key_type_arg,
4077 data_t *key_data,
4078 int alg_arg,
4079 data_t *salt,
4080 data_t *label,
4081 int requested_capacity_arg,
4082 int expected_status_arg )
4083{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004084 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004085 size_t key_type = key_type_arg;
4086 psa_algorithm_t alg = alg_arg;
4087 size_t requested_capacity = requested_capacity_arg;
4088 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004089 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004090 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004091
Gilles Peskine8817f612018-12-18 00:18:46 +01004092 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004093
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004094 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4095 psa_set_key_algorithm( &attributes, alg );
4096 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004097
Gilles Peskine049c7532019-05-15 20:22:09 +02004098 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4099 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004100
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004101 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004102 salt->x, salt->len,
4103 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004104 requested_capacity ),
4105 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004106
4107exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004108 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004109 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004110 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004111}
4112/* END_CASE */
4113
4114/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004115void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004116{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004117 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004118 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004119 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004120 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004121 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004122 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004123 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4124 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4125 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004126 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004127
Gilles Peskine8817f612018-12-18 00:18:46 +01004128 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004129
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004130 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4131 psa_set_key_algorithm( &attributes, alg );
4132 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004133
Gilles Peskine73676cb2019-05-15 20:15:10 +02004134 PSA_ASSERT( psa_import_key( &attributes,
4135 key_data, sizeof( key_data ),
4136 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004137
4138 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004139 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004140 NULL, 0,
4141 NULL, 0,
4142 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004143
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004144 /* state of operation shouldn't allow additional generation */
4145 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004146 NULL, 0,
4147 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004148 capacity ),
4149 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004150
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004151 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004152
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004153 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004154 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004155
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004156exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004157 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004158 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004159 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004160}
4161/* END_CASE */
4162
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004163/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004164void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004165{
4166 uint8_t output_buffer[16];
4167 size_t buffer_size = 16;
4168 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004169 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004170
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004171 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4172 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004173 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004174
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004175 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004176 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004177
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004178 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004179
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004180 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4181 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004182 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004183
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004184 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004185 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004186
4187exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004188 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004189}
4190/* END_CASE */
4191
4192/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004193void derive_output( int alg_arg,
4194 data_t *key_data,
4195 data_t *salt,
4196 data_t *label,
4197 int requested_capacity_arg,
4198 data_t *expected_output1,
4199 data_t *expected_output2 )
4200{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004201 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004202 psa_algorithm_t alg = alg_arg;
4203 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004204 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004205 uint8_t *expected_outputs[2] =
4206 {expected_output1->x, expected_output2->x};
4207 size_t output_sizes[2] =
4208 {expected_output1->len, expected_output2->len};
4209 size_t output_buffer_size = 0;
4210 uint8_t *output_buffer = NULL;
4211 size_t expected_capacity;
4212 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004213 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004214 psa_status_t status;
4215 unsigned i;
4216
4217 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4218 {
4219 if( output_sizes[i] > output_buffer_size )
4220 output_buffer_size = output_sizes[i];
4221 if( output_sizes[i] == 0 )
4222 expected_outputs[i] = NULL;
4223 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004224 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004225 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004226
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004227 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4228 psa_set_key_algorithm( &attributes, alg );
4229 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004230
Gilles Peskine049c7532019-05-15 20:22:09 +02004231 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4232 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004233
4234 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004235 if( PSA_ALG_IS_HKDF( alg ) )
4236 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004237 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4238 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004239 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004240 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004241 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004242 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004243 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004244 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004245 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004246 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004247 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004248 label->x, label->len ) );
4249 }
4250 else
4251 {
4252 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004253 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004254 salt->x, salt->len,
4255 label->x, label->len,
4256 requested_capacity ) );
4257 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004258 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004259 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004260 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004261 expected_capacity = requested_capacity;
4262
4263 /* Expansion phase. */
4264 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4265 {
4266 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004267 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004268 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004269 if( expected_capacity == 0 && output_sizes[i] == 0 )
4270 {
4271 /* Reading 0 bytes when 0 bytes are available can go either way. */
4272 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004273 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004274 continue;
4275 }
4276 else if( expected_capacity == 0 ||
4277 output_sizes[i] > expected_capacity )
4278 {
4279 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004280 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004281 expected_capacity = 0;
4282 continue;
4283 }
4284 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004285 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004286 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004287 ASSERT_COMPARE( output_buffer, output_sizes[i],
4288 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004289 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004290 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004291 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004292 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004293 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004294 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004295 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004296
4297exit:
4298 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004299 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004300 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004301 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004302}
4303/* END_CASE */
4304
4305/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004306void derive_full( int alg_arg,
4307 data_t *key_data,
4308 data_t *salt,
4309 data_t *label,
4310 int requested_capacity_arg )
4311{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004312 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004313 psa_algorithm_t alg = alg_arg;
4314 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004315 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004316 unsigned char output_buffer[16];
4317 size_t expected_capacity = requested_capacity;
4318 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004319 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004320
Gilles Peskine8817f612018-12-18 00:18:46 +01004321 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004322
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004323 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4324 psa_set_key_algorithm( &attributes, alg );
4325 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004326
Gilles Peskine049c7532019-05-15 20:22:09 +02004327 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4328 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004329
4330 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004331 if( PSA_ALG_IS_HKDF( alg ) )
4332 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004333 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4334 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004335 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004336 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004337 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004338 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004339 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004340 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004341 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004342 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004343 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004344 label->x, label->len ) );
4345 }
4346 else
4347 {
4348 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004349 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004350 salt->x, salt->len,
4351 label->x, label->len,
4352 requested_capacity ) );
4353 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004354 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004355 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004356 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004357
4358 /* Expansion phase. */
4359 while( current_capacity > 0 )
4360 {
4361 size_t read_size = sizeof( output_buffer );
4362 if( read_size > current_capacity )
4363 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004364 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004365 output_buffer,
4366 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004367 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004368 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004369 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004370 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004371 }
4372
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004373 /* Check that the operation refuses to go over capacity. */
4374 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004375 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004376
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004377 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004378
4379exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004380 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004381 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004382 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004383}
4384/* END_CASE */
4385
4386/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004387void derive_key_exercise( int alg_arg,
4388 data_t *key_data,
4389 data_t *salt,
4390 data_t *label,
4391 int derived_type_arg,
4392 int derived_bits_arg,
4393 int derived_usage_arg,
4394 int derived_alg_arg )
4395{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004396 psa_key_handle_t base_handle = 0;
4397 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004398 psa_algorithm_t alg = alg_arg;
4399 psa_key_type_t derived_type = derived_type_arg;
4400 size_t derived_bits = derived_bits_arg;
4401 psa_key_usage_t derived_usage = derived_usage_arg;
4402 psa_algorithm_t derived_alg = derived_alg_arg;
4403 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004404 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004405 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004406 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004407
Gilles Peskine8817f612018-12-18 00:18:46 +01004408 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004409
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004410 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4411 psa_set_key_algorithm( &attributes, alg );
4412 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004413 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4414 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004415
4416 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004417 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004418 salt->x, salt->len,
4419 label->x, label->len,
4420 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004421 psa_set_key_usage_flags( &attributes, derived_usage );
4422 psa_set_key_algorithm( &attributes, derived_alg );
4423 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004424 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004425 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004426 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004427
4428 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004429 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4430 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4431 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004432
4433 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004434 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004435 goto exit;
4436
4437exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004438 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004439 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004440 psa_destroy_key( base_handle );
4441 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004442 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004443}
4444/* END_CASE */
4445
4446/* BEGIN_CASE */
4447void derive_key_export( int alg_arg,
4448 data_t *key_data,
4449 data_t *salt,
4450 data_t *label,
4451 int bytes1_arg,
4452 int bytes2_arg )
4453{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004454 psa_key_handle_t base_handle = 0;
4455 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004456 psa_algorithm_t alg = alg_arg;
4457 size_t bytes1 = bytes1_arg;
4458 size_t bytes2 = bytes2_arg;
4459 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004460 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004461 uint8_t *output_buffer = NULL;
4462 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004463 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4464 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004465 size_t length;
4466
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004467 ASSERT_ALLOC( output_buffer, capacity );
4468 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004469 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004470
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004471 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4472 psa_set_key_algorithm( &base_attributes, alg );
4473 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004474 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4475 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004476
4477 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004478 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004479 salt->x, salt->len,
4480 label->x, label->len,
4481 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004482 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004483 output_buffer,
4484 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004485 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004486
4487 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004488 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004489 salt->x, salt->len,
4490 label->x, label->len,
4491 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004492 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4493 psa_set_key_algorithm( &derived_attributes, 0 );
4494 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004495 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004496 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004497 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004498 PSA_ASSERT( psa_export_key( derived_handle,
4499 export_buffer, bytes1,
4500 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004501 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004502 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004503 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
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, bytes2,
4508 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004509 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004510
4511 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004512 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4513 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004514
4515exit:
4516 mbedtls_free( output_buffer );
4517 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004518 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004519 psa_destroy_key( base_handle );
4520 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004521 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004522}
4523/* END_CASE */
4524
4525/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004526void key_agreement_setup( int alg_arg,
4527 int our_key_type_arg, data_t *our_key_data,
4528 data_t *peer_key_data,
4529 int expected_status_arg )
4530{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004531 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004532 psa_algorithm_t alg = alg_arg;
4533 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004534 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004535 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004536 psa_status_t expected_status = expected_status_arg;
4537 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004538
Gilles Peskine8817f612018-12-18 00:18:46 +01004539 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004540
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004541 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4542 psa_set_key_algorithm( &attributes, alg );
4543 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004544 PSA_ASSERT( psa_import_key( &attributes,
4545 our_key_data->x, our_key_data->len,
4546 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004547
Gilles Peskine77f40d82019-04-11 21:27:06 +02004548 /* The tests currently include inputs that should fail at either step.
4549 * Test cases that fail at the setup step should be changed to call
4550 * key_derivation_setup instead, and this function should be renamed
4551 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004552 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004553 if( status == PSA_SUCCESS )
4554 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004555 TEST_EQUAL( psa_key_derivation_key_agreement(
4556 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4557 our_key,
4558 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004559 expected_status );
4560 }
4561 else
4562 {
4563 TEST_ASSERT( status == expected_status );
4564 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004565
4566exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004567 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004568 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004569 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004570}
4571/* END_CASE */
4572
4573/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004574void raw_key_agreement( int alg_arg,
4575 int our_key_type_arg, data_t *our_key_data,
4576 data_t *peer_key_data,
4577 data_t *expected_output )
4578{
4579 psa_key_handle_t our_key = 0;
4580 psa_algorithm_t alg = alg_arg;
4581 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004582 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004583 unsigned char *output = NULL;
4584 size_t output_length = ~0;
4585
4586 ASSERT_ALLOC( output, expected_output->len );
4587 PSA_ASSERT( psa_crypto_init( ) );
4588
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004589 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4590 psa_set_key_algorithm( &attributes, alg );
4591 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004592 PSA_ASSERT( psa_import_key( &attributes,
4593 our_key_data->x, our_key_data->len,
4594 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004595
Gilles Peskinebe697d82019-05-16 18:00:41 +02004596 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4597 peer_key_data->x, peer_key_data->len,
4598 output, expected_output->len,
4599 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004600 ASSERT_COMPARE( output, output_length,
4601 expected_output->x, expected_output->len );
4602
4603exit:
4604 mbedtls_free( output );
4605 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004606 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004607}
4608/* END_CASE */
4609
4610/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004611void key_agreement_capacity( int alg_arg,
4612 int our_key_type_arg, data_t *our_key_data,
4613 data_t *peer_key_data,
4614 int expected_capacity_arg )
4615{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004616 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004617 psa_algorithm_t alg = alg_arg;
4618 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004619 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004620 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004621 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004622 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004623
Gilles Peskine8817f612018-12-18 00:18:46 +01004624 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004625
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004626 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4627 psa_set_key_algorithm( &attributes, alg );
4628 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004629 PSA_ASSERT( psa_import_key( &attributes,
4630 our_key_data->x, our_key_data->len,
4631 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004632
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004633 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004634 PSA_ASSERT( psa_key_derivation_key_agreement(
4635 &operation,
4636 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4637 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004638 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4639 {
4640 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004641 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004642 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004643 NULL, 0 ) );
4644 }
Gilles Peskine59685592018-09-18 12:11:34 +02004645
Gilles Peskinebf491972018-10-25 22:36:12 +02004646 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004647 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004648 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004649 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004650
Gilles Peskinebf491972018-10-25 22:36:12 +02004651 /* Test the actual capacity by reading the output. */
4652 while( actual_capacity > sizeof( output ) )
4653 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004654 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004655 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004656 actual_capacity -= sizeof( output );
4657 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004658 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004659 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004660 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004661 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004662
Gilles Peskine59685592018-09-18 12:11:34 +02004663exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004664 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004665 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004666 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004667}
4668/* END_CASE */
4669
4670/* BEGIN_CASE */
4671void key_agreement_output( int alg_arg,
4672 int our_key_type_arg, data_t *our_key_data,
4673 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004674 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004675{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004676 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004677 psa_algorithm_t alg = alg_arg;
4678 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004679 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004680 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004681 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004682
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004683 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4684 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004685
Gilles Peskine8817f612018-12-18 00:18:46 +01004686 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004687
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004688 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4689 psa_set_key_algorithm( &attributes, alg );
4690 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004691 PSA_ASSERT( psa_import_key( &attributes,
4692 our_key_data->x, our_key_data->len,
4693 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004694
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004695 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004696 PSA_ASSERT( psa_key_derivation_key_agreement(
4697 &operation,
4698 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4699 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004700 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4701 {
4702 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004703 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004704 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004705 NULL, 0 ) );
4706 }
Gilles Peskine59685592018-09-18 12:11:34 +02004707
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004708 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004709 actual_output,
4710 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004711 ASSERT_COMPARE( actual_output, expected_output1->len,
4712 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004713 if( expected_output2->len != 0 )
4714 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004715 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004716 actual_output,
4717 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004718 ASSERT_COMPARE( actual_output, expected_output2->len,
4719 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004720 }
Gilles Peskine59685592018-09-18 12:11:34 +02004721
4722exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004723 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004724 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004725 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004726 mbedtls_free( actual_output );
4727}
4728/* END_CASE */
4729
4730/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004731void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004732{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004733 size_t bytes = bytes_arg;
4734 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004735 unsigned char *output = NULL;
4736 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004737 size_t i;
4738 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004739
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004740 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4741 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004742 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004743
Gilles Peskine8817f612018-12-18 00:18:46 +01004744 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004745
Gilles Peskinea50d7392018-06-21 10:22:13 +02004746 /* Run several times, to ensure that every output byte will be
4747 * nonzero at least once with overwhelming probability
4748 * (2^(-8*number_of_runs)). */
4749 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004750 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004751 if( bytes != 0 )
4752 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004753 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004754
4755 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004756 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4757 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004758
4759 for( i = 0; i < bytes; i++ )
4760 {
4761 if( output[i] != 0 )
4762 ++changed[i];
4763 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004764 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004765
4766 /* Check that every byte was changed to nonzero at least once. This
4767 * validates that psa_generate_random is overwriting every byte of
4768 * the output buffer. */
4769 for( i = 0; i < bytes; i++ )
4770 {
4771 TEST_ASSERT( changed[i] != 0 );
4772 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004773
4774exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004775 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004776 mbedtls_free( output );
4777 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004778}
4779/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004780
4781/* BEGIN_CASE */
4782void generate_key( int type_arg,
4783 int bits_arg,
4784 int usage_arg,
4785 int alg_arg,
4786 int expected_status_arg )
4787{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004788 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004789 psa_key_type_t type = type_arg;
4790 psa_key_usage_t usage = usage_arg;
4791 size_t bits = bits_arg;
4792 psa_algorithm_t alg = alg_arg;
4793 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004794 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004795 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004796
Gilles Peskine8817f612018-12-18 00:18:46 +01004797 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004798
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004799 psa_set_key_usage_flags( &attributes, usage );
4800 psa_set_key_algorithm( &attributes, alg );
4801 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004802 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004803
4804 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004805 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004806 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004807 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004808
4809 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004810 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4811 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4812 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004813
Gilles Peskine818ca122018-06-20 18:16:48 +02004814 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004815 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004816 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004817
4818exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004819 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004820 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004821 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004822}
4823/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004824
Gilles Peskinee56e8782019-04-26 17:34:02 +02004825/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4826void generate_key_rsa( int bits_arg,
4827 data_t *e_arg,
4828 int expected_status_arg )
4829{
4830 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02004831 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02004832 size_t bits = bits_arg;
4833 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4834 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4835 psa_status_t expected_status = expected_status_arg;
4836 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4837 uint8_t *exported = NULL;
4838 size_t exported_size =
4839 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4840 size_t exported_length = SIZE_MAX;
4841 uint8_t *e_read_buffer = NULL;
4842 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004843 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004844 size_t e_read_length = SIZE_MAX;
4845
4846 if( e_arg->len == 0 ||
4847 ( e_arg->len == 3 &&
4848 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4849 {
4850 is_default_public_exponent = 1;
4851 e_read_size = 0;
4852 }
4853 ASSERT_ALLOC( e_read_buffer, e_read_size );
4854 ASSERT_ALLOC( exported, exported_size );
4855
4856 PSA_ASSERT( psa_crypto_init( ) );
4857
4858 psa_set_key_usage_flags( &attributes, usage );
4859 psa_set_key_algorithm( &attributes, alg );
4860 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4861 e_arg->x, e_arg->len ) );
4862 psa_set_key_bits( &attributes, bits );
4863
4864 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004865 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004866 if( expected_status != PSA_SUCCESS )
4867 goto exit;
4868
4869 /* Test the key information */
4870 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4871 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4872 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4873 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4874 e_read_buffer, e_read_size,
4875 &e_read_length ) );
4876 if( is_default_public_exponent )
4877 TEST_EQUAL( e_read_length, 0 );
4878 else
4879 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4880
4881 /* Do something with the key according to its type and permitted usage. */
4882 if( ! exercise_key( handle, usage, alg ) )
4883 goto exit;
4884
4885 /* Export the key and check the public exponent. */
4886 PSA_ASSERT( psa_export_public_key( handle,
4887 exported, exported_size,
4888 &exported_length ) );
4889 {
4890 uint8_t *p = exported;
4891 uint8_t *end = exported + exported_length;
4892 size_t len;
4893 /* RSAPublicKey ::= SEQUENCE {
4894 * modulus INTEGER, -- n
4895 * publicExponent INTEGER } -- e
4896 */
4897 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004898 MBEDTLS_ASN1_SEQUENCE |
4899 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004900 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4901 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4902 MBEDTLS_ASN1_INTEGER ) );
4903 if( len >= 1 && p[0] == 0 )
4904 {
4905 ++p;
4906 --len;
4907 }
4908 if( e_arg->len == 0 )
4909 {
4910 TEST_EQUAL( len, 3 );
4911 TEST_EQUAL( p[0], 1 );
4912 TEST_EQUAL( p[1], 0 );
4913 TEST_EQUAL( p[2], 1 );
4914 }
4915 else
4916 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4917 }
4918
4919exit:
4920 psa_reset_key_attributes( &attributes );
4921 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004922 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004923 mbedtls_free( e_read_buffer );
4924 mbedtls_free( exported );
4925}
4926/* END_CASE */
4927
Darryl Greend49a4992018-06-18 17:27:26 +01004928/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004929void persistent_key_load_key_from_storage( data_t *data,
4930 int type_arg, int bits_arg,
4931 int usage_flags_arg, int alg_arg,
4932 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004933{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004934 psa_key_id_t key_id = 1;
4935 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004936 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004937 psa_key_handle_t base_key = 0;
4938 psa_key_type_t type = type_arg;
4939 size_t bits = bits_arg;
4940 psa_key_usage_t usage_flags = usage_flags_arg;
4941 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004942 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004943 unsigned char *first_export = NULL;
4944 unsigned char *second_export = NULL;
4945 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4946 size_t first_exported_length;
4947 size_t second_exported_length;
4948
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004949 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4950 {
4951 ASSERT_ALLOC( first_export, export_size );
4952 ASSERT_ALLOC( second_export, export_size );
4953 }
Darryl Greend49a4992018-06-18 17:27:26 +01004954
Gilles Peskine8817f612018-12-18 00:18:46 +01004955 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004956
Gilles Peskinec87af662019-05-15 16:12:22 +02004957 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004958 psa_set_key_usage_flags( &attributes, usage_flags );
4959 psa_set_key_algorithm( &attributes, alg );
4960 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004961 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004962
Darryl Green0c6575a2018-11-07 16:05:30 +00004963 switch( generation_method )
4964 {
4965 case IMPORT_KEY:
4966 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004967 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4968 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004969 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004970
Darryl Green0c6575a2018-11-07 16:05:30 +00004971 case GENERATE_KEY:
4972 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004973 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004974 break;
4975
4976 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004977 {
4978 /* Create base key */
4979 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4980 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4981 psa_set_key_usage_flags( &base_attributes,
4982 PSA_KEY_USAGE_DERIVE );
4983 psa_set_key_algorithm( &base_attributes, derive_alg );
4984 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004985 PSA_ASSERT( psa_import_key( &base_attributes,
4986 data->x, data->len,
4987 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004988 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004989 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004990 PSA_ASSERT( psa_key_derivation_input_key(
4991 &operation,
4992 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004993 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004994 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004995 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004996 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
4997 &operation,
4998 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004999 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005000 PSA_ASSERT( psa_destroy_key( base_key ) );
5001 base_key = 0;
5002 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005003 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005004 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005005 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005006
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005007 /* Export the key if permitted by the key policy. */
5008 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5009 {
5010 PSA_ASSERT( psa_export_key( handle,
5011 first_export, export_size,
5012 &first_exported_length ) );
5013 if( generation_method == IMPORT_KEY )
5014 ASSERT_COMPARE( data->x, data->len,
5015 first_export, first_exported_length );
5016 }
Darryl Greend49a4992018-06-18 17:27:26 +01005017
5018 /* Shutdown and restart */
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005019 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005020 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005021
Darryl Greend49a4992018-06-18 17:27:26 +01005022 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005023 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005024 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5025 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5026 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5027 PSA_KEY_LIFETIME_PERSISTENT );
5028 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5029 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5030 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5031 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005032
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005033 /* Export the key again if permitted by the key policy. */
5034 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005035 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005036 PSA_ASSERT( psa_export_key( handle,
5037 second_export, export_size,
5038 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005039 ASSERT_COMPARE( first_export, first_exported_length,
5040 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005041 }
5042
5043 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005044 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005045 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005046
5047exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005048 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005049 mbedtls_free( first_export );
5050 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005051 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005052 psa_destroy_key( base_key );
5053 if( handle == 0 )
5054 {
5055 /* In case there was a test failure after creating the persistent key
5056 * but while it was not open, try to re-open the persistent key
5057 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005058 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005059 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005060 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005061 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005062}
5063/* END_CASE */