blob: cb64532cc21a9a228cbd86c26350e78bceeabba0 [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 asn1_skip_integer( unsigned char **p, const unsigned char *end,
686 size_t min_bits, size_t max_bits,
687 int must_be_odd )
688{
689 size_t len;
690 size_t actual_bits;
691 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100692 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100693 MBEDTLS_ASN1_INTEGER ),
694 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200695 /* Tolerate a slight departure from DER encoding:
696 * - 0 may be represented by an empty string or a 1-byte string.
697 * - The sign bit may be used as a value bit. */
698 if( ( len == 1 && ( *p )[0] == 0 ) ||
699 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
700 {
701 ++( *p );
702 --len;
703 }
704 if( min_bits == 0 && len == 0 )
705 return( 1 );
706 msb = ( *p )[0];
707 TEST_ASSERT( msb != 0 );
708 actual_bits = 8 * ( len - 1 );
709 while( msb != 0 )
710 {
711 msb >>= 1;
712 ++actual_bits;
713 }
714 TEST_ASSERT( actual_bits >= min_bits );
715 TEST_ASSERT( actual_bits <= max_bits );
716 if( must_be_odd )
717 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
718 *p += len;
719 return( 1 );
720exit:
721 return( 0 );
722}
723
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200724static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
725 uint8_t *exported, size_t exported_length )
726{
727 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100728 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200729 else
730 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200731
732#if defined(MBEDTLS_DES_C)
733 if( type == PSA_KEY_TYPE_DES )
734 {
735 /* Check the parity bits. */
736 unsigned i;
737 for( i = 0; i < bits / 8; i++ )
738 {
739 unsigned bit_count = 0;
740 unsigned m;
741 for( m = 1; m <= 0x100; m <<= 1 )
742 {
743 if( exported[i] & m )
744 ++bit_count;
745 }
746 TEST_ASSERT( bit_count % 2 != 0 );
747 }
748 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200749 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200750#endif
751
752#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200753 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200754 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200755 uint8_t *p = exported;
756 uint8_t *end = exported + exported_length;
757 size_t len;
758 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200759 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200760 * modulus INTEGER, -- n
761 * publicExponent INTEGER, -- e
762 * privateExponent INTEGER, -- d
763 * prime1 INTEGER, -- p
764 * prime2 INTEGER, -- q
765 * exponent1 INTEGER, -- d mod (p-1)
766 * exponent2 INTEGER, -- d mod (q-1)
767 * coefficient INTEGER, -- (inverse of q) mod p
768 * }
769 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100770 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
771 MBEDTLS_ASN1_SEQUENCE |
772 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
773 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200774 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
775 goto exit;
776 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
777 goto exit;
778 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
779 goto exit;
780 /* Require d to be at least half the size of n. */
781 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
782 goto exit;
783 /* Require p and q to be at most half the size of n, rounded up. */
784 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
785 goto exit;
786 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
787 goto exit;
788 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
789 goto exit;
790 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
791 goto exit;
792 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
793 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100794 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100795 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200796 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200797#endif /* MBEDTLS_RSA_C */
798
799#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200800 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200801 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100802 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100803 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100804 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200805 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200806#endif /* MBEDTLS_ECP_C */
807
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200808 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
809 {
810 uint8_t *p = exported;
811 uint8_t *end = exported + exported_length;
812 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200813#if defined(MBEDTLS_RSA_C)
814 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
815 {
816 /* RSAPublicKey ::= SEQUENCE {
817 * modulus INTEGER, -- n
818 * publicExponent INTEGER } -- e
819 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100820 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
821 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100822 MBEDTLS_ASN1_CONSTRUCTED ),
823 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100824 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200825 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
826 goto exit;
827 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
828 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100829 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200830 }
831 else
832#endif /* MBEDTLS_RSA_C */
833#if defined(MBEDTLS_ECP_C)
834 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
835 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000836 /* The representation of an ECC public key is:
837 * - The byte 0x04;
838 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
839 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
840 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000841 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100842 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
843 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200844 }
845 else
846#endif /* MBEDTLS_ECP_C */
847 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100848 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200849 mbedtls_snprintf( message, sizeof( message ),
850 "No sanity check for public key type=0x%08lx",
851 (unsigned long) type );
852 test_fail( message, __LINE__, __FILE__ );
853 return( 0 );
854 }
855 }
856 else
857
858 {
859 /* No sanity checks for other types */
860 }
861
862 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200863
864exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200865 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200866}
867
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100868static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200869 psa_key_usage_t usage )
870{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200871 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200872 uint8_t *exported = NULL;
873 size_t exported_size = 0;
874 size_t exported_length = 0;
875 int ok = 0;
876
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200877 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200878
879 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200880 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200881 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100882 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
883 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200884 ok = 1;
885 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200886 }
887
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200888 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
889 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200890 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200891
Gilles Peskine8817f612018-12-18 00:18:46 +0100892 PSA_ASSERT( psa_export_key( handle,
893 exported, exported_size,
894 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200895 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
896 psa_get_key_bits( &attributes ),
897 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200898
899exit:
900 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200901 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200902 return( ok );
903}
904
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100905static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200906{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200907 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200908 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200909 uint8_t *exported = NULL;
910 size_t exported_size = 0;
911 size_t exported_length = 0;
912 int ok = 0;
913
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200914 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
915 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200916 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100917 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100918 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200919 return( 1 );
920 }
921
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200922 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200923 psa_get_key_type( &attributes ) );
924 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
925 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200926 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200927
Gilles Peskine8817f612018-12-18 00:18:46 +0100928 PSA_ASSERT( psa_export_public_key( handle,
929 exported, exported_size,
930 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200931 ok = exported_key_sanity_check( public_type,
932 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200933 exported, exported_length );
934
935exit:
936 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200937 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200938 return( ok );
939}
940
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100941/** Do smoke tests on a key.
942 *
943 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
944 * sign/verify, or derivation) that is permitted according to \p usage.
945 * \p usage and \p alg should correspond to the expected policy on the
946 * key.
947 *
948 * Export the key if permitted by \p usage, and check that the output
949 * looks sensible. If \p usage forbids export, check that
950 * \p psa_export_key correctly rejects the attempt. If the key is
951 * asymmetric, also check \p psa_export_public_key.
952 *
953 * If the key fails the tests, this function calls the test framework's
954 * `test_fail` function and returns false. Otherwise this function returns
955 * true. Therefore it should be used as follows:
956 * ```
957 * if( ! exercise_key( ... ) ) goto exit;
958 * ```
959 *
960 * \param handle The key to exercise. It should be capable of performing
961 * \p alg.
962 * \param usage The usage flags to assume.
963 * \param alg The algorithm to exercise.
964 *
965 * \retval 0 The key failed the smoke tests.
966 * \retval 1 The key passed the smoke tests.
967 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100968static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +0200969 psa_key_usage_t usage,
970 psa_algorithm_t alg )
971{
972 int ok;
973 if( alg == 0 )
974 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
975 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100976 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200977 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100978 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200979 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100980 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200981 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100982 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200983 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100984 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200985 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100986 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200987 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
988 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200989 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100990 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200991 else
992 {
993 char message[40];
994 mbedtls_snprintf( message, sizeof( message ),
995 "No code to exercise alg=0x%08lx",
996 (unsigned long) alg );
997 test_fail( message, __LINE__, __FILE__ );
998 ok = 0;
999 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001000
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001001 ok = ok && exercise_export_key( handle, usage );
1002 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001003
Gilles Peskine02b75072018-07-01 22:31:34 +02001004 return( ok );
1005}
1006
Gilles Peskine10df3412018-10-25 22:35:43 +02001007static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1008 psa_algorithm_t alg )
1009{
1010 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1011 {
1012 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1013 PSA_KEY_USAGE_VERIFY :
1014 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1015 }
1016 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1017 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1018 {
1019 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1020 PSA_KEY_USAGE_ENCRYPT :
1021 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1022 }
1023 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1024 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1025 {
1026 return( PSA_KEY_USAGE_DERIVE );
1027 }
1028 else
1029 {
1030 return( 0 );
1031 }
1032
1033}
Darryl Green0c6575a2018-11-07 16:05:30 +00001034
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001035static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1036{
1037 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1038 uint8_t buffer[1];
1039 size_t length;
1040 int ok = 0;
1041
Gilles Peskinec87af662019-05-15 16:12:22 +02001042 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001043 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1044 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1045 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1046 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1047 PSA_ERROR_INVALID_HANDLE );
1048 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001049 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001050 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1051 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1052 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1053 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1054
1055 TEST_EQUAL( psa_export_key( handle,
1056 buffer, sizeof( buffer ), &length ),
1057 PSA_ERROR_INVALID_HANDLE );
1058 TEST_EQUAL( psa_export_public_key( handle,
1059 buffer, sizeof( buffer ), &length ),
1060 PSA_ERROR_INVALID_HANDLE );
1061
1062 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1063 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1064
1065 ok = 1;
1066
1067exit:
1068 psa_reset_key_attributes( &attributes );
1069 return( ok );
1070}
1071
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001072/* An overapproximation of the amount of storage needed for a key of the
1073 * given type and with the given content. The API doesn't make it easy
1074 * to find a good value for the size. The current implementation doesn't
1075 * care about the value anyway. */
1076#define KEY_BITS_FROM_DATA( type, data ) \
1077 ( data )->len
1078
Darryl Green0c6575a2018-11-07 16:05:30 +00001079typedef enum {
1080 IMPORT_KEY = 0,
1081 GENERATE_KEY = 1,
1082 DERIVE_KEY = 2
1083} generate_method;
1084
Gilles Peskinee59236f2018-01-27 23:32:46 +01001085/* END_HEADER */
1086
1087/* BEGIN_DEPENDENCIES
1088 * depends_on:MBEDTLS_PSA_CRYPTO_C
1089 * END_DEPENDENCIES
1090 */
1091
1092/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001093void static_checks( )
1094{
1095 size_t max_truncated_mac_size =
1096 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1097
1098 /* Check that the length for a truncated MAC always fits in the algorithm
1099 * encoding. The shifted mask is the maximum truncated value. The
1100 * untruncated algorithm may be one byte larger. */
1101 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1102}
1103/* END_CASE */
1104
1105/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001106void attributes_set_get( int id_arg, int lifetime_arg,
1107 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001108 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001109{
Gilles Peskine4747d192019-04-17 15:05:45 +02001110 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001111 psa_key_id_t id = id_arg;
1112 psa_key_lifetime_t lifetime = lifetime_arg;
1113 psa_key_usage_t usage_flags = usage_flags_arg;
1114 psa_algorithm_t alg = alg_arg;
1115 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001116 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001117
1118 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1119 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1120 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1121 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1122 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001123 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001124
Gilles Peskinec87af662019-05-15 16:12:22 +02001125 psa_set_key_id( &attributes, id );
1126 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001127 psa_set_key_usage_flags( &attributes, usage_flags );
1128 psa_set_key_algorithm( &attributes, alg );
1129 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001130 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001131
1132 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1133 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1134 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1135 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1136 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001137 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001138
1139 psa_reset_key_attributes( &attributes );
1140
1141 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1142 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1143 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1144 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1145 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001146 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001147}
1148/* END_CASE */
1149
1150/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001151void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1152 int expected_id_arg, int expected_lifetime_arg )
1153{
1154 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1155 psa_key_id_t id1 = id1_arg;
1156 psa_key_lifetime_t lifetime = lifetime_arg;
1157 psa_key_id_t id2 = id2_arg;
1158 psa_key_id_t expected_id = expected_id_arg;
1159 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1160
1161 if( id1_arg != -1 )
1162 psa_set_key_id( &attributes, id1 );
1163 if( lifetime_arg != -1 )
1164 psa_set_key_lifetime( &attributes, lifetime );
1165 if( id2_arg != -1 )
1166 psa_set_key_id( &attributes, id2 );
1167
1168 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1169 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1170}
1171/* END_CASE */
1172
1173/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001174void import( data_t *data, int type_arg,
1175 int attr_bits_arg,
1176 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001177{
1178 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1179 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001180 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001181 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001182 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001183 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001184 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001185
Gilles Peskine8817f612018-12-18 00:18:46 +01001186 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001187
Gilles Peskine4747d192019-04-17 15:05:45 +02001188 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001189 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001190 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001191 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001192 if( status != PSA_SUCCESS )
1193 goto exit;
1194
1195 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1196 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001197 if( attr_bits != 0 )
1198 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001199
1200 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001201 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001202
1203exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001204 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001205 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001206 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001207}
1208/* END_CASE */
1209
1210/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001211void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1212{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001213 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001214 size_t bits = bits_arg;
1215 psa_status_t expected_status = expected_status_arg;
1216 psa_status_t status;
1217 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001218 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001219 size_t buffer_size = /* Slight overapproximations */
1220 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001221 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001222 unsigned char *p;
1223 int ret;
1224 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001225 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001226
Gilles Peskine8817f612018-12-18 00:18:46 +01001227 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001228 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001229
1230 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1231 bits, keypair ) ) >= 0 );
1232 length = ret;
1233
1234 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001235 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001236 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001237 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001238
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001239 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001240 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001241
1242exit:
1243 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001244 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001245}
1246/* END_CASE */
1247
1248/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001249void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001250 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001251 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001252 int expected_bits,
1253 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001254 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001255 int canonical_input )
1256{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001257 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001258 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001259 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001260 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001261 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001262 unsigned char *exported = NULL;
1263 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001264 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001265 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001266 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001267 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001268 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001269
Moran Pekercb088e72018-07-17 17:36:59 +03001270 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001271 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001272 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001273 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001274 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001275
Gilles Peskine4747d192019-04-17 15:05:45 +02001276 psa_set_key_usage_flags( &attributes, usage_arg );
1277 psa_set_key_algorithm( &attributes, alg );
1278 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001279
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001280 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001281 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001282
1283 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001284 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1285 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1286 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001287
1288 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001289 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001290 exported, export_size,
1291 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001292 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001293
1294 /* The exported length must be set by psa_export_key() to a value between 0
1295 * and export_size. On errors, the exported length must be 0. */
1296 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1297 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1298 TEST_ASSERT( exported_length <= export_size );
1299
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001300 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001301 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001302 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001303 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001304 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001305 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001306 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001307
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001308 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001309 goto exit;
1310
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001311 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001312 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001313 else
1314 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001315 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001316 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1317 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001318 PSA_ASSERT( psa_export_key( handle2,
1319 reexported,
1320 export_size,
1321 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001322 ASSERT_COMPARE( exported, exported_length,
1323 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001324 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001325 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001326 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001327
1328destroy:
1329 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001330 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001331 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001332
1333exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001334 mbedtls_free( exported );
1335 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001336 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001337 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001338}
1339/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001340
Moran Pekerf709f4a2018-06-06 17:26:04 +03001341/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001342void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001343{
Gilles Peskine8817f612018-12-18 00:18:46 +01001344 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001345 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001346
1347exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001348 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001349}
1350/* END_CASE */
1351
1352/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001353void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001354 int type_arg,
1355 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001356 int export_size_delta,
1357 int expected_export_status_arg,
1358 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001359{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001360 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001361 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001362 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001363 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001364 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001365 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001366 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001367 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001368 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001369
Gilles Peskine8817f612018-12-18 00:18:46 +01001370 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001371
Gilles Peskine4747d192019-04-17 15:05:45 +02001372 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1373 psa_set_key_algorithm( &attributes, alg );
1374 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001375
1376 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001377 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001378
Gilles Peskine49c25912018-10-29 15:15:31 +01001379 /* Export the public key */
1380 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001381 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001382 exported, export_size,
1383 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001384 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001385 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001386 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001387 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001388 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001389 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1390 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001391 TEST_ASSERT( expected_public_key->len <=
1392 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001393 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1394 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001395 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001396
1397exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001398 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001399 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001400 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001401 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001402}
1403/* END_CASE */
1404
Gilles Peskine20035e32018-02-03 22:44:14 +01001405/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001406void import_and_exercise_key( data_t *data,
1407 int type_arg,
1408 int bits_arg,
1409 int alg_arg )
1410{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001411 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001412 psa_key_type_t type = type_arg;
1413 size_t bits = bits_arg;
1414 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001415 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001416 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001417 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001418
Gilles Peskine8817f612018-12-18 00:18:46 +01001419 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001420
Gilles Peskine4747d192019-04-17 15:05:45 +02001421 psa_set_key_usage_flags( &attributes, usage );
1422 psa_set_key_algorithm( &attributes, alg );
1423 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001424
1425 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001426 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001427
1428 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001429 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1430 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1431 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001432
1433 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001434 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001435 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001436
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001437 PSA_ASSERT( psa_destroy_key( handle ) );
1438 test_operations_on_invalid_handle( handle );
1439
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001440exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001441 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001442 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001443 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001444}
1445/* END_CASE */
1446
1447/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001448void key_policy( int usage_arg, int alg_arg )
1449{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001450 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001451 psa_algorithm_t alg = alg_arg;
1452 psa_key_usage_t usage = usage_arg;
1453 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1454 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001455 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001456
1457 memset( key, 0x2a, sizeof( key ) );
1458
Gilles Peskine8817f612018-12-18 00:18:46 +01001459 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001460
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001461 psa_set_key_usage_flags( &attributes, usage );
1462 psa_set_key_algorithm( &attributes, alg );
1463 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001464
Gilles Peskine73676cb2019-05-15 20:15:10 +02001465 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001466
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001467 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1468 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1469 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1470 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001471
1472exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001473 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001474 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001475 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001476}
1477/* END_CASE */
1478
1479/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001480void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001481{
1482 /* Test each valid way of initializing the object, except for `= {0}`, as
1483 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1484 * though it's OK by the C standard. We could test for this, but we'd need
1485 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001486 psa_key_attributes_t func = psa_key_attributes_init( );
1487 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1488 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001489
1490 memset( &zero, 0, sizeof( zero ) );
1491
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001492 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1493 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1494 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001495
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001496 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1497 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1498 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1499
1500 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1501 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1502 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1503
1504 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1505 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1506 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1507
1508 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1509 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1510 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001511}
1512/* END_CASE */
1513
1514/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001515void mac_key_policy( int policy_usage,
1516 int policy_alg,
1517 int key_type,
1518 data_t *key_data,
1519 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001520{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001521 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001522 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001523 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001524 psa_status_t status;
1525 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001526
Gilles Peskine8817f612018-12-18 00:18:46 +01001527 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001528
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001529 psa_set_key_usage_flags( &attributes, policy_usage );
1530 psa_set_key_algorithm( &attributes, policy_alg );
1531 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001532
Gilles Peskine049c7532019-05-15 20:22:09 +02001533 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1534 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001535
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001536 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001537 if( policy_alg == exercise_alg &&
1538 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001539 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001540 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001541 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001542 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001543
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001544 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001545 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001546 if( policy_alg == exercise_alg &&
1547 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001548 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001549 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001550 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001551
1552exit:
1553 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001554 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001555 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001556}
1557/* END_CASE */
1558
1559/* BEGIN_CASE */
1560void cipher_key_policy( int policy_usage,
1561 int policy_alg,
1562 int key_type,
1563 data_t *key_data,
1564 int exercise_alg )
1565{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001566 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001567 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001568 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001569 psa_status_t status;
1570
Gilles Peskine8817f612018-12-18 00:18:46 +01001571 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001572
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001573 psa_set_key_usage_flags( &attributes, policy_usage );
1574 psa_set_key_algorithm( &attributes, policy_alg );
1575 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001576
Gilles Peskine049c7532019-05-15 20:22:09 +02001577 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1578 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001579
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001580 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001581 if( policy_alg == exercise_alg &&
1582 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001583 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001584 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001585 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001586 psa_cipher_abort( &operation );
1587
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001588 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001589 if( policy_alg == exercise_alg &&
1590 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001591 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001592 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001593 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001594
1595exit:
1596 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001597 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001598 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001599}
1600/* END_CASE */
1601
1602/* BEGIN_CASE */
1603void aead_key_policy( int policy_usage,
1604 int policy_alg,
1605 int key_type,
1606 data_t *key_data,
1607 int nonce_length_arg,
1608 int tag_length_arg,
1609 int exercise_alg )
1610{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001611 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001612 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001613 psa_status_t status;
1614 unsigned char nonce[16] = {0};
1615 size_t nonce_length = nonce_length_arg;
1616 unsigned char tag[16];
1617 size_t tag_length = tag_length_arg;
1618 size_t output_length;
1619
1620 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1621 TEST_ASSERT( tag_length <= sizeof( tag ) );
1622
Gilles Peskine8817f612018-12-18 00:18:46 +01001623 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001624
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001625 psa_set_key_usage_flags( &attributes, policy_usage );
1626 psa_set_key_algorithm( &attributes, policy_alg );
1627 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001628
Gilles Peskine049c7532019-05-15 20:22:09 +02001629 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1630 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001631
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001632 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001633 nonce, nonce_length,
1634 NULL, 0,
1635 NULL, 0,
1636 tag, tag_length,
1637 &output_length );
1638 if( policy_alg == exercise_alg &&
1639 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001640 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001641 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001642 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001643
1644 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001645 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001646 nonce, nonce_length,
1647 NULL, 0,
1648 tag, tag_length,
1649 NULL, 0,
1650 &output_length );
1651 if( policy_alg == exercise_alg &&
1652 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001653 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001655 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001656
1657exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001658 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001659 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001660}
1661/* END_CASE */
1662
1663/* BEGIN_CASE */
1664void asymmetric_encryption_key_policy( int policy_usage,
1665 int policy_alg,
1666 int key_type,
1667 data_t *key_data,
1668 int exercise_alg )
1669{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001670 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001671 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001672 psa_status_t status;
1673 size_t key_bits;
1674 size_t buffer_length;
1675 unsigned char *buffer = NULL;
1676 size_t output_length;
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 Peskine8c8f2ab2019-04-18 21:44:46 +02001687 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1688 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001689 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1690 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001691 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001693 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001694 NULL, 0,
1695 NULL, 0,
1696 buffer, buffer_length,
1697 &output_length );
1698 if( policy_alg == exercise_alg &&
1699 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001700 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001701 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001702 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001703
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001704 if( buffer_length != 0 )
1705 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001706 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001707 buffer, buffer_length,
1708 NULL, 0,
1709 buffer, buffer_length,
1710 &output_length );
1711 if( policy_alg == exercise_alg &&
1712 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001713 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001714 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001715 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716
1717exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001718 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001719 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001720 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001721 mbedtls_free( buffer );
1722}
1723/* END_CASE */
1724
1725/* BEGIN_CASE */
1726void asymmetric_signature_key_policy( int policy_usage,
1727 int policy_alg,
1728 int key_type,
1729 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001730 int exercise_alg,
1731 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001732{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001733 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001734 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001735 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001736 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1737 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1738 * compatible with the policy and `payload_length_arg` is supposed to be
1739 * a valid input length to sign. If `payload_length_arg <= 0`,
1740 * `exercise_alg` is supposed to be forbidden by the policy. */
1741 int compatible_alg = payload_length_arg > 0;
1742 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001743 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1744 size_t signature_length;
1745
Gilles Peskine8817f612018-12-18 00:18:46 +01001746 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001747
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001748 psa_set_key_usage_flags( &attributes, policy_usage );
1749 psa_set_key_algorithm( &attributes, policy_alg );
1750 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751
Gilles Peskine049c7532019-05-15 20:22:09 +02001752 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1753 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001754
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001755 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001756 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001757 signature, sizeof( signature ),
1758 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001759 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001760 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001761 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001762 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001763
1764 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001765 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001766 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001768 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001769 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001770 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001771 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001772
1773exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001774 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001775 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001776}
1777/* END_CASE */
1778
1779/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001780void derive_key_policy( int policy_usage,
1781 int policy_alg,
1782 int key_type,
1783 data_t *key_data,
1784 int exercise_alg )
1785{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001786 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001787 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001788 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001789 psa_status_t status;
1790
Gilles Peskine8817f612018-12-18 00:18:46 +01001791 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001792
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001793 psa_set_key_usage_flags( &attributes, policy_usage );
1794 psa_set_key_algorithm( &attributes, policy_alg );
1795 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001796
Gilles Peskine049c7532019-05-15 20:22:09 +02001797 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1798 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001799
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001800 status = psa_key_derivation( &operation, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001801 exercise_alg,
1802 NULL, 0,
1803 NULL, 0,
1804 1 );
1805 if( policy_alg == exercise_alg &&
1806 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001807 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001808 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001809 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001810
1811exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001812 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001813 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001814 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001815}
1816/* END_CASE */
1817
1818/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001819void agreement_key_policy( int policy_usage,
1820 int policy_alg,
1821 int key_type_arg,
1822 data_t *key_data,
1823 int exercise_alg )
1824{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001825 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001826 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001827 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001828 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001829 psa_status_t status;
1830
Gilles Peskine8817f612018-12-18 00:18:46 +01001831 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001832
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001833 psa_set_key_usage_flags( &attributes, policy_usage );
1834 psa_set_key_algorithm( &attributes, policy_alg );
1835 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001836
Gilles Peskine049c7532019-05-15 20:22:09 +02001837 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1838 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001839
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001840 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1841 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001842
Gilles Peskine01d718c2018-09-18 12:01:02 +02001843 if( policy_alg == exercise_alg &&
1844 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001845 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001846 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001847 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001848
1849exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001850 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001851 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001852 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001853}
1854/* END_CASE */
1855
1856/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001857void key_policy_alg2( int key_type_arg, data_t *key_data,
1858 int usage_arg, int alg_arg, int alg2_arg )
1859{
1860 psa_key_handle_t handle = 0;
1861 psa_key_type_t key_type = key_type_arg;
1862 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1863 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1864 psa_key_usage_t usage = usage_arg;
1865 psa_algorithm_t alg = alg_arg;
1866 psa_algorithm_t alg2 = alg2_arg;
1867
1868 PSA_ASSERT( psa_crypto_init( ) );
1869
1870 psa_set_key_usage_flags( &attributes, usage );
1871 psa_set_key_algorithm( &attributes, alg );
1872 psa_set_key_enrollment_algorithm( &attributes, alg2 );
1873 psa_set_key_type( &attributes, key_type );
1874 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1875 &handle ) );
1876
1877 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1878 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1879 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1880 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
1881
1882 if( ! exercise_key( handle, usage, alg ) )
1883 goto exit;
1884 if( ! exercise_key( handle, usage, alg2 ) )
1885 goto exit;
1886
1887exit:
1888 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001889 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02001890}
1891/* END_CASE */
1892
1893/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001894void raw_agreement_key_policy( int policy_usage,
1895 int policy_alg,
1896 int key_type_arg,
1897 data_t *key_data,
1898 int exercise_alg )
1899{
1900 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001901 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001902 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001903 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001904 psa_status_t status;
1905
1906 PSA_ASSERT( psa_crypto_init( ) );
1907
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001908 psa_set_key_usage_flags( &attributes, policy_usage );
1909 psa_set_key_algorithm( &attributes, policy_alg );
1910 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001911
Gilles Peskine049c7532019-05-15 20:22:09 +02001912 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1913 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001914
1915 status = raw_key_agreement_with_self( exercise_alg, handle );
1916
1917 if( policy_alg == exercise_alg &&
1918 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1919 PSA_ASSERT( status );
1920 else
1921 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1922
1923exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001924 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001925 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001926 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001927}
1928/* END_CASE */
1929
1930/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001931void copy_success( int source_usage_arg,
1932 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02001933 int type_arg, data_t *material,
1934 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001935 int target_usage_arg,
1936 int target_alg_arg, int target_alg2_arg,
1937 int expected_usage_arg,
1938 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001939{
Gilles Peskineca25db92019-04-19 11:43:08 +02001940 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1941 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001942 psa_key_usage_t expected_usage = expected_usage_arg;
1943 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001944 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001945 psa_key_handle_t source_handle = 0;
1946 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001947 uint8_t *export_buffer = NULL;
1948
Gilles Peskine57ab7212019-01-28 13:03:09 +01001949 PSA_ASSERT( psa_crypto_init( ) );
1950
Gilles Peskineca25db92019-04-19 11:43:08 +02001951 /* Prepare the source key. */
1952 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1953 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001954 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02001955 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02001956 PSA_ASSERT( psa_import_key( &source_attributes,
1957 material->x, material->len,
1958 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001959 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001960
Gilles Peskineca25db92019-04-19 11:43:08 +02001961 /* Prepare the target attributes. */
1962 if( copy_attributes )
1963 target_attributes = source_attributes;
1964 if( target_usage_arg != -1 )
1965 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1966 if( target_alg_arg != -1 )
1967 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001968 if( target_alg2_arg != -1 )
1969 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001970
1971 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02001972 PSA_ASSERT( psa_copy_key( source_handle,
1973 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001974
1975 /* Destroy the source to ensure that this doesn't affect the target. */
1976 PSA_ASSERT( psa_destroy_key( source_handle ) );
1977
1978 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001979 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1980 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1981 psa_get_key_type( &target_attributes ) );
1982 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1983 psa_get_key_bits( &target_attributes ) );
1984 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
1985 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001986 TEST_EQUAL( expected_alg2,
1987 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001988 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1989 {
1990 size_t length;
1991 ASSERT_ALLOC( export_buffer, material->len );
1992 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1993 material->len, &length ) );
1994 ASSERT_COMPARE( material->x, material->len,
1995 export_buffer, length );
1996 }
1997 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1998 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001999 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2000 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002001
2002 PSA_ASSERT( psa_close_key( target_handle ) );
2003
2004exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002005 psa_reset_key_attributes( &source_attributes );
2006 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002007 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002008 mbedtls_free( export_buffer );
2009}
2010/* END_CASE */
2011
2012/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002013void copy_fail( int source_usage_arg,
2014 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002015 int type_arg, data_t *material,
2016 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002017 int target_usage_arg,
2018 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002019 int expected_status_arg )
2020{
2021 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2022 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2023 psa_key_handle_t source_handle = 0;
2024 psa_key_handle_t target_handle = 0;
2025
2026 PSA_ASSERT( psa_crypto_init( ) );
2027
2028 /* Prepare the source key. */
2029 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2030 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002031 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002032 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002033 PSA_ASSERT( psa_import_key( &source_attributes,
2034 material->x, material->len,
2035 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002036
2037 /* Prepare the target attributes. */
2038 psa_set_key_type( &target_attributes, target_type_arg );
2039 psa_set_key_bits( &target_attributes, target_bits_arg );
2040 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2041 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002042 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002043
2044 /* Try to copy the key. */
2045 TEST_EQUAL( psa_copy_key( source_handle,
2046 &target_attributes, &target_handle ),
2047 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002048
2049 PSA_ASSERT( psa_destroy_key( source_handle ) );
2050
Gilles Peskine4a644642019-05-03 17:14:08 +02002051exit:
2052 psa_reset_key_attributes( &source_attributes );
2053 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002054 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002055}
2056/* END_CASE */
2057
2058/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002059void hash_operation_init( )
2060{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002061 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002062 /* Test each valid way of initializing the object, except for `= {0}`, as
2063 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2064 * though it's OK by the C standard. We could test for this, but we'd need
2065 * to supress the Clang warning for the test. */
2066 psa_hash_operation_t func = psa_hash_operation_init( );
2067 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2068 psa_hash_operation_t zero;
2069
2070 memset( &zero, 0, sizeof( zero ) );
2071
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002072 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002073 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2074 PSA_ERROR_BAD_STATE );
2075 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2076 PSA_ERROR_BAD_STATE );
2077 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2078 PSA_ERROR_BAD_STATE );
2079
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002080 /* A default hash operation should be abortable without error. */
2081 PSA_ASSERT( psa_hash_abort( &func ) );
2082 PSA_ASSERT( psa_hash_abort( &init ) );
2083 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002084}
2085/* END_CASE */
2086
2087/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002088void hash_setup( int alg_arg,
2089 int expected_status_arg )
2090{
2091 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002092 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002093 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002094 psa_status_t status;
2095
Gilles Peskine8817f612018-12-18 00:18:46 +01002096 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002097
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002098 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002099 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002100
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002101 /* Whether setup succeeded or failed, abort must succeed. */
2102 PSA_ASSERT( psa_hash_abort( &operation ) );
2103
2104 /* If setup failed, reproduce the failure, so as to
2105 * test the resulting state of the operation object. */
2106 if( status != PSA_SUCCESS )
2107 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2108
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002109 /* Now the operation object should be reusable. */
2110#if defined(KNOWN_SUPPORTED_HASH_ALG)
2111 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2112 PSA_ASSERT( psa_hash_abort( &operation ) );
2113#endif
2114
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002115exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002116 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002117}
2118/* END_CASE */
2119
2120/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002121void hash_bad_order( )
2122{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002123 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002124 unsigned char input[] = "";
2125 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002126 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002127 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2128 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2129 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002130 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002131 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002132 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002133
Gilles Peskine8817f612018-12-18 00:18:46 +01002134 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002135
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002136 /* Call setup twice in a row. */
2137 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2138 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2139 PSA_ERROR_BAD_STATE );
2140 PSA_ASSERT( psa_hash_abort( &operation ) );
2141
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002142 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002143 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002144 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002145 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002146
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002147 /* Call update after finish. */
2148 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2149 PSA_ASSERT( psa_hash_finish( &operation,
2150 hash, sizeof( hash ), &hash_len ) );
2151 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002152 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002153 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002154
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002155 /* Call verify without calling setup beforehand. */
2156 TEST_EQUAL( psa_hash_verify( &operation,
2157 valid_hash, sizeof( valid_hash ) ),
2158 PSA_ERROR_BAD_STATE );
2159 PSA_ASSERT( psa_hash_abort( &operation ) );
2160
2161 /* Call verify after finish. */
2162 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2163 PSA_ASSERT( psa_hash_finish( &operation,
2164 hash, sizeof( hash ), &hash_len ) );
2165 TEST_EQUAL( psa_hash_verify( &operation,
2166 valid_hash, sizeof( valid_hash ) ),
2167 PSA_ERROR_BAD_STATE );
2168 PSA_ASSERT( psa_hash_abort( &operation ) );
2169
2170 /* Call verify twice in a row. */
2171 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2172 PSA_ASSERT( psa_hash_verify( &operation,
2173 valid_hash, sizeof( valid_hash ) ) );
2174 TEST_EQUAL( psa_hash_verify( &operation,
2175 valid_hash, sizeof( valid_hash ) ),
2176 PSA_ERROR_BAD_STATE );
2177 PSA_ASSERT( psa_hash_abort( &operation ) );
2178
2179 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002180 TEST_EQUAL( psa_hash_finish( &operation,
2181 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002182 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002183 PSA_ASSERT( psa_hash_abort( &operation ) );
2184
2185 /* Call finish twice in a row. */
2186 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2187 PSA_ASSERT( psa_hash_finish( &operation,
2188 hash, sizeof( hash ), &hash_len ) );
2189 TEST_EQUAL( psa_hash_finish( &operation,
2190 hash, sizeof( hash ), &hash_len ),
2191 PSA_ERROR_BAD_STATE );
2192 PSA_ASSERT( psa_hash_abort( &operation ) );
2193
2194 /* Call finish after calling verify. */
2195 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2196 PSA_ASSERT( psa_hash_verify( &operation,
2197 valid_hash, sizeof( valid_hash ) ) );
2198 TEST_EQUAL( psa_hash_finish( &operation,
2199 hash, sizeof( hash ), &hash_len ),
2200 PSA_ERROR_BAD_STATE );
2201 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002202
2203exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002204 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002205}
2206/* END_CASE */
2207
itayzafrir27e69452018-11-01 14:26:34 +02002208/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2209void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002210{
2211 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002212 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2213 * appended to it */
2214 unsigned char hash[] = {
2215 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2216 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2217 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002218 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002219 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002220
Gilles Peskine8817f612018-12-18 00:18:46 +01002221 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002222
itayzafrir27e69452018-11-01 14:26:34 +02002223 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002224 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002225 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002226 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002227
itayzafrir27e69452018-11-01 14:26:34 +02002228 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002229 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002230 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002231 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002232
itayzafrir27e69452018-11-01 14:26:34 +02002233 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002234 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002235 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002236 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002237
itayzafrirec93d302018-10-18 18:01:10 +03002238exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002239 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002240}
2241/* END_CASE */
2242
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002243/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2244void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002245{
2246 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002247 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002248 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002249 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002250 size_t hash_len;
2251
Gilles Peskine8817f612018-12-18 00:18:46 +01002252 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002253
itayzafrir58028322018-10-25 10:22:01 +03002254 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002255 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002256 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002257 hash, expected_size - 1, &hash_len ),
2258 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002259
2260exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002261 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002262}
2263/* END_CASE */
2264
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002265/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2266void hash_clone_source_state( )
2267{
2268 psa_algorithm_t alg = PSA_ALG_SHA_256;
2269 unsigned char hash[PSA_HASH_MAX_SIZE];
2270 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2271 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2272 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2273 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2274 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2275 size_t hash_len;
2276
2277 PSA_ASSERT( psa_crypto_init( ) );
2278 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2279
2280 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2281 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2282 PSA_ASSERT( psa_hash_finish( &op_finished,
2283 hash, sizeof( hash ), &hash_len ) );
2284 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2285 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2286
2287 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2288 PSA_ERROR_BAD_STATE );
2289
2290 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2291 PSA_ASSERT( psa_hash_finish( &op_init,
2292 hash, sizeof( hash ), &hash_len ) );
2293 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2294 PSA_ASSERT( psa_hash_finish( &op_finished,
2295 hash, sizeof( hash ), &hash_len ) );
2296 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2297 PSA_ASSERT( psa_hash_finish( &op_aborted,
2298 hash, sizeof( hash ), &hash_len ) );
2299
2300exit:
2301 psa_hash_abort( &op_source );
2302 psa_hash_abort( &op_init );
2303 psa_hash_abort( &op_setup );
2304 psa_hash_abort( &op_finished );
2305 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002306 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002307}
2308/* END_CASE */
2309
2310/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2311void hash_clone_target_state( )
2312{
2313 psa_algorithm_t alg = PSA_ALG_SHA_256;
2314 unsigned char hash[PSA_HASH_MAX_SIZE];
2315 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2316 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2317 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2318 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2319 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2320 size_t hash_len;
2321
2322 PSA_ASSERT( psa_crypto_init( ) );
2323
2324 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2325 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2326 PSA_ASSERT( psa_hash_finish( &op_finished,
2327 hash, sizeof( hash ), &hash_len ) );
2328 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2329 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2330
2331 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2332 PSA_ASSERT( psa_hash_finish( &op_target,
2333 hash, sizeof( hash ), &hash_len ) );
2334
2335 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2336 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2337 PSA_ERROR_BAD_STATE );
2338 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2339 PSA_ERROR_BAD_STATE );
2340
2341exit:
2342 psa_hash_abort( &op_target );
2343 psa_hash_abort( &op_init );
2344 psa_hash_abort( &op_setup );
2345 psa_hash_abort( &op_finished );
2346 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002347 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002348}
2349/* END_CASE */
2350
itayzafrir58028322018-10-25 10:22:01 +03002351/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002352void mac_operation_init( )
2353{
Jaeden Amero252ef282019-02-15 14:05:35 +00002354 const uint8_t input[1] = { 0 };
2355
Jaeden Amero769ce272019-01-04 11:48:03 +00002356 /* Test each valid way of initializing the object, except for `= {0}`, as
2357 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2358 * though it's OK by the C standard. We could test for this, but we'd need
2359 * to supress the Clang warning for the test. */
2360 psa_mac_operation_t func = psa_mac_operation_init( );
2361 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2362 psa_mac_operation_t zero;
2363
2364 memset( &zero, 0, sizeof( zero ) );
2365
Jaeden Amero252ef282019-02-15 14:05:35 +00002366 /* A freshly-initialized MAC operation should not be usable. */
2367 TEST_EQUAL( psa_mac_update( &func,
2368 input, sizeof( input ) ),
2369 PSA_ERROR_BAD_STATE );
2370 TEST_EQUAL( psa_mac_update( &init,
2371 input, sizeof( input ) ),
2372 PSA_ERROR_BAD_STATE );
2373 TEST_EQUAL( psa_mac_update( &zero,
2374 input, sizeof( input ) ),
2375 PSA_ERROR_BAD_STATE );
2376
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002377 /* A default MAC operation should be abortable without error. */
2378 PSA_ASSERT( psa_mac_abort( &func ) );
2379 PSA_ASSERT( psa_mac_abort( &init ) );
2380 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002381}
2382/* END_CASE */
2383
2384/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002385void mac_setup( int key_type_arg,
2386 data_t *key,
2387 int alg_arg,
2388 int expected_status_arg )
2389{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002390 psa_key_type_t key_type = key_type_arg;
2391 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002392 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002393 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002394 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2395#if defined(KNOWN_SUPPORTED_MAC_ALG)
2396 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2397#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002398
Gilles Peskine8817f612018-12-18 00:18:46 +01002399 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002400
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002401 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2402 &operation, &status ) )
2403 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002404 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002405
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002406 /* The operation object should be reusable. */
2407#if defined(KNOWN_SUPPORTED_MAC_ALG)
2408 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2409 smoke_test_key_data,
2410 sizeof( smoke_test_key_data ),
2411 KNOWN_SUPPORTED_MAC_ALG,
2412 &operation, &status ) )
2413 goto exit;
2414 TEST_EQUAL( status, PSA_SUCCESS );
2415#endif
2416
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002417exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002418 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002419}
2420/* END_CASE */
2421
2422/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002423void mac_bad_order( )
2424{
2425 psa_key_handle_t handle = 0;
2426 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2427 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2428 const uint8_t key[] = {
2429 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2430 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2431 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002432 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002433 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2434 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2435 size_t sign_mac_length = 0;
2436 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2437 const uint8_t verify_mac[] = {
2438 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2439 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2440 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2441
2442 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002443 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2444 psa_set_key_algorithm( &attributes, alg );
2445 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002446
Gilles Peskine73676cb2019-05-15 20:15:10 +02002447 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002448
Jaeden Amero252ef282019-02-15 14:05:35 +00002449 /* Call update without calling setup beforehand. */
2450 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2451 PSA_ERROR_BAD_STATE );
2452 PSA_ASSERT( psa_mac_abort( &operation ) );
2453
2454 /* Call sign finish without calling setup beforehand. */
2455 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2456 &sign_mac_length),
2457 PSA_ERROR_BAD_STATE );
2458 PSA_ASSERT( psa_mac_abort( &operation ) );
2459
2460 /* Call verify finish without calling setup beforehand. */
2461 TEST_EQUAL( psa_mac_verify_finish( &operation,
2462 verify_mac, sizeof( verify_mac ) ),
2463 PSA_ERROR_BAD_STATE );
2464 PSA_ASSERT( psa_mac_abort( &operation ) );
2465
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002466 /* Call setup twice in a row. */
2467 PSA_ASSERT( psa_mac_sign_setup( &operation,
2468 handle, alg ) );
2469 TEST_EQUAL( psa_mac_sign_setup( &operation,
2470 handle, alg ),
2471 PSA_ERROR_BAD_STATE );
2472 PSA_ASSERT( psa_mac_abort( &operation ) );
2473
Jaeden Amero252ef282019-02-15 14:05:35 +00002474 /* Call update after sign finish. */
2475 PSA_ASSERT( psa_mac_sign_setup( &operation,
2476 handle, alg ) );
2477 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2478 PSA_ASSERT( psa_mac_sign_finish( &operation,
2479 sign_mac, sizeof( sign_mac ),
2480 &sign_mac_length ) );
2481 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2482 PSA_ERROR_BAD_STATE );
2483 PSA_ASSERT( psa_mac_abort( &operation ) );
2484
2485 /* Call update after verify finish. */
2486 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002487 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002488 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2489 PSA_ASSERT( psa_mac_verify_finish( &operation,
2490 verify_mac, sizeof( verify_mac ) ) );
2491 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2492 PSA_ERROR_BAD_STATE );
2493 PSA_ASSERT( psa_mac_abort( &operation ) );
2494
2495 /* Call sign finish twice in a row. */
2496 PSA_ASSERT( psa_mac_sign_setup( &operation,
2497 handle, alg ) );
2498 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2499 PSA_ASSERT( psa_mac_sign_finish( &operation,
2500 sign_mac, sizeof( sign_mac ),
2501 &sign_mac_length ) );
2502 TEST_EQUAL( psa_mac_sign_finish( &operation,
2503 sign_mac, sizeof( sign_mac ),
2504 &sign_mac_length ),
2505 PSA_ERROR_BAD_STATE );
2506 PSA_ASSERT( psa_mac_abort( &operation ) );
2507
2508 /* Call verify finish twice in a row. */
2509 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002510 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002511 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2512 PSA_ASSERT( psa_mac_verify_finish( &operation,
2513 verify_mac, sizeof( verify_mac ) ) );
2514 TEST_EQUAL( psa_mac_verify_finish( &operation,
2515 verify_mac, sizeof( verify_mac ) ),
2516 PSA_ERROR_BAD_STATE );
2517 PSA_ASSERT( psa_mac_abort( &operation ) );
2518
2519 /* Setup sign but try verify. */
2520 PSA_ASSERT( psa_mac_sign_setup( &operation,
2521 handle, alg ) );
2522 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2523 TEST_EQUAL( psa_mac_verify_finish( &operation,
2524 verify_mac, sizeof( verify_mac ) ),
2525 PSA_ERROR_BAD_STATE );
2526 PSA_ASSERT( psa_mac_abort( &operation ) );
2527
2528 /* Setup verify but try sign. */
2529 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002530 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002531 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2532 TEST_EQUAL( psa_mac_sign_finish( &operation,
2533 sign_mac, sizeof( sign_mac ),
2534 &sign_mac_length ),
2535 PSA_ERROR_BAD_STATE );
2536 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002537
Gilles Peskine76b29a72019-05-28 14:08:50 +02002538 PSA_ASSERT( psa_destroy_key( handle ) );
2539
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002540exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002541 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002542}
2543/* END_CASE */
2544
2545/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002546void mac_sign( int key_type_arg,
2547 data_t *key,
2548 int alg_arg,
2549 data_t *input,
2550 data_t *expected_mac )
2551{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002552 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002553 psa_key_type_t key_type = key_type_arg;
2554 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002555 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002556 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002557 /* Leave a little extra room in the output buffer. At the end of the
2558 * test, we'll check that the implementation didn't overwrite onto
2559 * this extra room. */
2560 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2561 size_t mac_buffer_size =
2562 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2563 size_t mac_length = 0;
2564
2565 memset( actual_mac, '+', sizeof( actual_mac ) );
2566 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2567 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2568
Gilles Peskine8817f612018-12-18 00:18:46 +01002569 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002570
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002571 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2572 psa_set_key_algorithm( &attributes, alg );
2573 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002574
Gilles Peskine73676cb2019-05-15 20:15:10 +02002575 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002576
2577 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002578 PSA_ASSERT( psa_mac_sign_setup( &operation,
2579 handle, alg ) );
2580 PSA_ASSERT( psa_mac_update( &operation,
2581 input->x, input->len ) );
2582 PSA_ASSERT( psa_mac_sign_finish( &operation,
2583 actual_mac, mac_buffer_size,
2584 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002585
2586 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002587 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2588 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002589
2590 /* Verify that the end of the buffer is untouched. */
2591 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2592 sizeof( actual_mac ) - mac_length ) );
2593
2594exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002595 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002596 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002597}
2598/* END_CASE */
2599
2600/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002601void mac_verify( int key_type_arg,
2602 data_t *key,
2603 int alg_arg,
2604 data_t *input,
2605 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002606{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002607 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002608 psa_key_type_t key_type = key_type_arg;
2609 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002610 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002611 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002612
Gilles Peskine69c12672018-06-28 00:07:19 +02002613 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2614
Gilles Peskine8817f612018-12-18 00:18:46 +01002615 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002616
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002617 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2618 psa_set_key_algorithm( &attributes, alg );
2619 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002620
Gilles Peskine73676cb2019-05-15 20:15:10 +02002621 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002622
Gilles Peskine8817f612018-12-18 00:18:46 +01002623 PSA_ASSERT( psa_mac_verify_setup( &operation,
2624 handle, alg ) );
2625 PSA_ASSERT( psa_destroy_key( handle ) );
2626 PSA_ASSERT( psa_mac_update( &operation,
2627 input->x, input->len ) );
2628 PSA_ASSERT( psa_mac_verify_finish( &operation,
2629 expected_mac->x,
2630 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002631
2632exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002633 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002634 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002635}
2636/* END_CASE */
2637
2638/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002639void cipher_operation_init( )
2640{
Jaeden Ameroab439972019-02-15 14:12:05 +00002641 const uint8_t input[1] = { 0 };
2642 unsigned char output[1] = { 0 };
2643 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002644 /* Test each valid way of initializing the object, except for `= {0}`, as
2645 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2646 * though it's OK by the C standard. We could test for this, but we'd need
2647 * to supress the Clang warning for the test. */
2648 psa_cipher_operation_t func = psa_cipher_operation_init( );
2649 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2650 psa_cipher_operation_t zero;
2651
2652 memset( &zero, 0, sizeof( zero ) );
2653
Jaeden Ameroab439972019-02-15 14:12:05 +00002654 /* A freshly-initialized cipher operation should not be usable. */
2655 TEST_EQUAL( psa_cipher_update( &func,
2656 input, sizeof( input ),
2657 output, sizeof( output ),
2658 &output_length ),
2659 PSA_ERROR_BAD_STATE );
2660 TEST_EQUAL( psa_cipher_update( &init,
2661 input, sizeof( input ),
2662 output, sizeof( output ),
2663 &output_length ),
2664 PSA_ERROR_BAD_STATE );
2665 TEST_EQUAL( psa_cipher_update( &zero,
2666 input, sizeof( input ),
2667 output, sizeof( output ),
2668 &output_length ),
2669 PSA_ERROR_BAD_STATE );
2670
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002671 /* A default cipher operation should be abortable without error. */
2672 PSA_ASSERT( psa_cipher_abort( &func ) );
2673 PSA_ASSERT( psa_cipher_abort( &init ) );
2674 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002675}
2676/* END_CASE */
2677
2678/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002679void cipher_setup( int key_type_arg,
2680 data_t *key,
2681 int alg_arg,
2682 int expected_status_arg )
2683{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002684 psa_key_type_t key_type = key_type_arg;
2685 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002686 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002687 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002688 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002689#if defined(KNOWN_SUPPORTED_MAC_ALG)
2690 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2691#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002692
Gilles Peskine8817f612018-12-18 00:18:46 +01002693 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002694
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002695 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2696 &operation, &status ) )
2697 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002698 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002699
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002700 /* The operation object should be reusable. */
2701#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2702 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2703 smoke_test_key_data,
2704 sizeof( smoke_test_key_data ),
2705 KNOWN_SUPPORTED_CIPHER_ALG,
2706 &operation, &status ) )
2707 goto exit;
2708 TEST_EQUAL( status, PSA_SUCCESS );
2709#endif
2710
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002711exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002712 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002713}
2714/* END_CASE */
2715
2716/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002717void cipher_bad_order( )
2718{
2719 psa_key_handle_t handle = 0;
2720 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2721 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002722 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002723 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2724 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2725 const uint8_t key[] = {
2726 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2727 0xaa, 0xaa, 0xaa, 0xaa };
2728 const uint8_t text[] = {
2729 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2730 0xbb, 0xbb, 0xbb, 0xbb };
2731 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2732 size_t length = 0;
2733
2734 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002735 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2736 psa_set_key_algorithm( &attributes, alg );
2737 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002738 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002739
2740
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002741 /* Call encrypt setup twice in a row. */
2742 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2743 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2744 PSA_ERROR_BAD_STATE );
2745 PSA_ASSERT( psa_cipher_abort( &operation ) );
2746
2747 /* Call decrypt setup twice in a row. */
2748 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2749 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2750 PSA_ERROR_BAD_STATE );
2751 PSA_ASSERT( psa_cipher_abort( &operation ) );
2752
Jaeden Ameroab439972019-02-15 14:12:05 +00002753 /* Generate an IV without calling setup beforehand. */
2754 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2755 buffer, sizeof( buffer ),
2756 &length ),
2757 PSA_ERROR_BAD_STATE );
2758 PSA_ASSERT( psa_cipher_abort( &operation ) );
2759
2760 /* Generate an IV twice in a row. */
2761 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2762 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2763 buffer, sizeof( buffer ),
2764 &length ) );
2765 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2766 buffer, sizeof( buffer ),
2767 &length ),
2768 PSA_ERROR_BAD_STATE );
2769 PSA_ASSERT( psa_cipher_abort( &operation ) );
2770
2771 /* Generate an IV after it's already set. */
2772 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2773 PSA_ASSERT( psa_cipher_set_iv( &operation,
2774 iv, sizeof( iv ) ) );
2775 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2776 buffer, sizeof( buffer ),
2777 &length ),
2778 PSA_ERROR_BAD_STATE );
2779 PSA_ASSERT( psa_cipher_abort( &operation ) );
2780
2781 /* Set an IV without calling setup beforehand. */
2782 TEST_EQUAL( psa_cipher_set_iv( &operation,
2783 iv, sizeof( iv ) ),
2784 PSA_ERROR_BAD_STATE );
2785 PSA_ASSERT( psa_cipher_abort( &operation ) );
2786
2787 /* Set an IV after it's already set. */
2788 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2789 PSA_ASSERT( psa_cipher_set_iv( &operation,
2790 iv, sizeof( iv ) ) );
2791 TEST_EQUAL( psa_cipher_set_iv( &operation,
2792 iv, sizeof( iv ) ),
2793 PSA_ERROR_BAD_STATE );
2794 PSA_ASSERT( psa_cipher_abort( &operation ) );
2795
2796 /* Set an IV after it's already generated. */
2797 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2798 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2799 buffer, sizeof( buffer ),
2800 &length ) );
2801 TEST_EQUAL( psa_cipher_set_iv( &operation,
2802 iv, sizeof( iv ) ),
2803 PSA_ERROR_BAD_STATE );
2804 PSA_ASSERT( psa_cipher_abort( &operation ) );
2805
2806 /* Call update without calling setup beforehand. */
2807 TEST_EQUAL( psa_cipher_update( &operation,
2808 text, sizeof( text ),
2809 buffer, sizeof( buffer ),
2810 &length ),
2811 PSA_ERROR_BAD_STATE );
2812 PSA_ASSERT( psa_cipher_abort( &operation ) );
2813
2814 /* Call update without an IV where an IV is required. */
2815 TEST_EQUAL( psa_cipher_update( &operation,
2816 text, sizeof( text ),
2817 buffer, sizeof( buffer ),
2818 &length ),
2819 PSA_ERROR_BAD_STATE );
2820 PSA_ASSERT( psa_cipher_abort( &operation ) );
2821
2822 /* Call update after finish. */
2823 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2824 PSA_ASSERT( psa_cipher_set_iv( &operation,
2825 iv, sizeof( iv ) ) );
2826 PSA_ASSERT( psa_cipher_finish( &operation,
2827 buffer, sizeof( buffer ), &length ) );
2828 TEST_EQUAL( psa_cipher_update( &operation,
2829 text, sizeof( text ),
2830 buffer, sizeof( buffer ),
2831 &length ),
2832 PSA_ERROR_BAD_STATE );
2833 PSA_ASSERT( psa_cipher_abort( &operation ) );
2834
2835 /* Call finish without calling setup beforehand. */
2836 TEST_EQUAL( psa_cipher_finish( &operation,
2837 buffer, sizeof( buffer ), &length ),
2838 PSA_ERROR_BAD_STATE );
2839 PSA_ASSERT( psa_cipher_abort( &operation ) );
2840
2841 /* Call finish without an IV where an IV is required. */
2842 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2843 /* Not calling update means we are encrypting an empty buffer, which is OK
2844 * for cipher modes with padding. */
2845 TEST_EQUAL( psa_cipher_finish( &operation,
2846 buffer, sizeof( buffer ), &length ),
2847 PSA_ERROR_BAD_STATE );
2848 PSA_ASSERT( psa_cipher_abort( &operation ) );
2849
2850 /* Call finish twice in a row. */
2851 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2852 PSA_ASSERT( psa_cipher_set_iv( &operation,
2853 iv, sizeof( iv ) ) );
2854 PSA_ASSERT( psa_cipher_finish( &operation,
2855 buffer, sizeof( buffer ), &length ) );
2856 TEST_EQUAL( psa_cipher_finish( &operation,
2857 buffer, sizeof( buffer ), &length ),
2858 PSA_ERROR_BAD_STATE );
2859 PSA_ASSERT( psa_cipher_abort( &operation ) );
2860
Gilles Peskine76b29a72019-05-28 14:08:50 +02002861 PSA_ASSERT( psa_destroy_key( handle ) );
2862
Jaeden Ameroab439972019-02-15 14:12:05 +00002863exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002864 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002865}
2866/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002867
Gilles Peskine50e586b2018-06-08 14:28:46 +02002868/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002869void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002870 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002871 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002872 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002873{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002874 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002875 psa_status_t status;
2876 psa_key_type_t key_type = key_type_arg;
2877 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002878 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002879 unsigned char *output = NULL;
2880 size_t output_buffer_size = 0;
2881 size_t function_output_length = 0;
2882 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002883 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002884 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002885
Gilles Peskine8817f612018-12-18 00:18:46 +01002886 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002887
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002888 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2889 psa_set_key_algorithm( &attributes, alg );
2890 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002891
Gilles Peskine73676cb2019-05-15 20:15:10 +02002892 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002893
Gilles Peskine8817f612018-12-18 00:18:46 +01002894 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2895 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002896
Gilles Peskine423005e2019-05-06 15:22:57 +02002897 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002898 output_buffer_size = ( (size_t) input->len +
2899 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002900 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002901
Gilles Peskine8817f612018-12-18 00:18:46 +01002902 PSA_ASSERT( psa_cipher_update( &operation,
2903 input->x, input->len,
2904 output, output_buffer_size,
2905 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002906 total_output_length += function_output_length;
2907 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002908 output + total_output_length,
2909 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002910 &function_output_length );
2911 total_output_length += function_output_length;
2912
Gilles Peskinefe11b722018-12-18 00:24:04 +01002913 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002914 if( expected_status == PSA_SUCCESS )
2915 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002916 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002917 ASSERT_COMPARE( expected_output->x, expected_output->len,
2918 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002919 }
2920
2921exit:
2922 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002923 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002924 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002925}
2926/* END_CASE */
2927
2928/* BEGIN_CASE */
2929void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002930 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002931 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002932 int first_part_size_arg,
2933 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002934 data_t *expected_output )
2935{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002936 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002937 psa_key_type_t key_type = key_type_arg;
2938 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002939 size_t first_part_size = first_part_size_arg;
2940 size_t output1_length = output1_length_arg;
2941 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002942 unsigned char *output = NULL;
2943 size_t output_buffer_size = 0;
2944 size_t function_output_length = 0;
2945 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002946 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002947 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002948
Gilles Peskine8817f612018-12-18 00:18:46 +01002949 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002950
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002951 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2952 psa_set_key_algorithm( &attributes, alg );
2953 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002954
Gilles Peskine73676cb2019-05-15 20:15:10 +02002955 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002956
Gilles Peskine8817f612018-12-18 00:18:46 +01002957 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2958 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002959
Gilles Peskine423005e2019-05-06 15:22:57 +02002960 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002961 output_buffer_size = ( (size_t) input->len +
2962 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002963 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002964
Gilles Peskinee0866522019-02-19 19:44:00 +01002965 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002966 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2967 output, output_buffer_size,
2968 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002969 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002970 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002971 PSA_ASSERT( psa_cipher_update( &operation,
2972 input->x + first_part_size,
2973 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002974 output + total_output_length,
2975 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002976 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002977 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002978 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002979 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002980 output + total_output_length,
2981 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002982 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002983 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002984 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002985
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002986 ASSERT_COMPARE( expected_output->x, expected_output->len,
2987 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002988
2989exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002990 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002991 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002992 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002993}
2994/* END_CASE */
2995
2996/* BEGIN_CASE */
2997void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002998 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002999 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003000 int first_part_size_arg,
3001 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003002 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003003{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003004 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003005
3006 psa_key_type_t key_type = key_type_arg;
3007 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003008 size_t first_part_size = first_part_size_arg;
3009 size_t output1_length = output1_length_arg;
3010 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003011 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012 size_t output_buffer_size = 0;
3013 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003014 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003015 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003016 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003017
Gilles Peskine8817f612018-12-18 00:18:46 +01003018 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003019
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003020 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3021 psa_set_key_algorithm( &attributes, alg );
3022 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003023
Gilles Peskine73676cb2019-05-15 20:15:10 +02003024 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003025
Gilles Peskine8817f612018-12-18 00:18:46 +01003026 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3027 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003028
Gilles Peskine423005e2019-05-06 15:22:57 +02003029 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003030
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003031 output_buffer_size = ( (size_t) input->len +
3032 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003033 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003034
Gilles Peskinee0866522019-02-19 19:44:00 +01003035 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003036 PSA_ASSERT( psa_cipher_update( &operation,
3037 input->x, first_part_size,
3038 output, output_buffer_size,
3039 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003040 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003041 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003042 PSA_ASSERT( psa_cipher_update( &operation,
3043 input->x + first_part_size,
3044 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003045 output + total_output_length,
3046 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003047 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003048 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003049 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003050 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003051 output + total_output_length,
3052 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003053 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003054 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003055 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003056
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003057 ASSERT_COMPARE( expected_output->x, expected_output->len,
3058 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003059
3060exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003061 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003062 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003063 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003064}
3065/* END_CASE */
3066
Gilles Peskine50e586b2018-06-08 14:28:46 +02003067/* BEGIN_CASE */
3068void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003069 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003070 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003071 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003072{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003073 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074 psa_status_t status;
3075 psa_key_type_t key_type = key_type_arg;
3076 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003077 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003078 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003079 size_t output_buffer_size = 0;
3080 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003081 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003082 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003083 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003084
Gilles Peskine8817f612018-12-18 00:18:46 +01003085 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003087 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3088 psa_set_key_algorithm( &attributes, alg );
3089 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003090
Gilles Peskine73676cb2019-05-15 20:15:10 +02003091 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003092
Gilles Peskine8817f612018-12-18 00:18:46 +01003093 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3094 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003095
Gilles Peskine423005e2019-05-06 15:22:57 +02003096 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003097
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003098 output_buffer_size = ( (size_t) input->len +
3099 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003100 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003101
Gilles Peskine8817f612018-12-18 00:18:46 +01003102 PSA_ASSERT( psa_cipher_update( &operation,
3103 input->x, input->len,
3104 output, output_buffer_size,
3105 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003106 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003107 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003108 output + total_output_length,
3109 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003110 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003111 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003112 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003113
3114 if( expected_status == PSA_SUCCESS )
3115 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003116 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003117 ASSERT_COMPARE( expected_output->x, expected_output->len,
3118 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003119 }
3120
Gilles Peskine50e586b2018-06-08 14:28:46 +02003121exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003122 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003123 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003124 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003125}
3126/* END_CASE */
3127
Gilles Peskine50e586b2018-06-08 14:28:46 +02003128/* BEGIN_CASE */
3129void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003130 data_t *key,
3131 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003132{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003133 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003134 psa_key_type_t key_type = key_type_arg;
3135 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003136 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003137 size_t iv_size = 16;
3138 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003139 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003140 size_t output1_size = 0;
3141 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003142 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003143 size_t output2_size = 0;
3144 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003145 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003146 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3147 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003148 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003149
Gilles Peskine8817f612018-12-18 00:18:46 +01003150 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003151
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003152 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3153 psa_set_key_algorithm( &attributes, alg );
3154 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003155
Gilles Peskine73676cb2019-05-15 20:15:10 +02003156 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003157
Gilles Peskine8817f612018-12-18 00:18:46 +01003158 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3159 handle, alg ) );
3160 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3161 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003162
Gilles Peskine8817f612018-12-18 00:18:46 +01003163 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3164 iv, iv_size,
3165 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003166 output1_size = ( (size_t) input->len +
3167 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003168 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003169
Gilles Peskine8817f612018-12-18 00:18:46 +01003170 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3171 output1, output1_size,
3172 &output1_length ) );
3173 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003174 output1 + output1_length,
3175 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003176 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003177
Gilles Peskine048b7f02018-06-08 14:20:49 +02003178 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003179
Gilles Peskine8817f612018-12-18 00:18:46 +01003180 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003181
3182 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003183 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003184
Gilles Peskine8817f612018-12-18 00:18:46 +01003185 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3186 iv, iv_length ) );
3187 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3188 output2, output2_size,
3189 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003190 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003191 PSA_ASSERT( psa_cipher_finish( &operation2,
3192 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003193 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003194 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003195
Gilles Peskine048b7f02018-06-08 14:20:49 +02003196 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003197
Gilles Peskine8817f612018-12-18 00:18:46 +01003198 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003199
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003200 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003201
3202exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003203 mbedtls_free( output1 );
3204 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003205 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003206 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003207}
3208/* END_CASE */
3209
3210/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003211void cipher_verify_output_multipart( int alg_arg,
3212 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003213 data_t *key,
3214 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003215 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003216{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003217 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003218 psa_key_type_t key_type = key_type_arg;
3219 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003220 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003221 unsigned char iv[16] = {0};
3222 size_t iv_size = 16;
3223 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003224 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003225 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003226 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003227 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003228 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003229 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003230 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003231 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3232 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003233 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003234
Gilles Peskine8817f612018-12-18 00:18:46 +01003235 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003236
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003237 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3238 psa_set_key_algorithm( &attributes, alg );
3239 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003240
Gilles Peskine73676cb2019-05-15 20:15:10 +02003241 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003242
Gilles Peskine8817f612018-12-18 00:18:46 +01003243 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3244 handle, alg ) );
3245 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3246 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003247
Gilles Peskine8817f612018-12-18 00:18:46 +01003248 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3249 iv, iv_size,
3250 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003251 output1_buffer_size = ( (size_t) input->len +
3252 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003253 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003254
Gilles Peskinee0866522019-02-19 19:44:00 +01003255 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003256
Gilles Peskine8817f612018-12-18 00:18:46 +01003257 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3258 output1, output1_buffer_size,
3259 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003260 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003261
Gilles Peskine8817f612018-12-18 00:18:46 +01003262 PSA_ASSERT( psa_cipher_update( &operation1,
3263 input->x + first_part_size,
3264 input->len - first_part_size,
3265 output1, output1_buffer_size,
3266 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003267 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003268
Gilles Peskine8817f612018-12-18 00:18:46 +01003269 PSA_ASSERT( psa_cipher_finish( &operation1,
3270 output1 + output1_length,
3271 output1_buffer_size - output1_length,
3272 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003273 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003274
Gilles Peskine8817f612018-12-18 00:18:46 +01003275 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003276
Gilles Peskine048b7f02018-06-08 14:20:49 +02003277 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003278 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003279
Gilles Peskine8817f612018-12-18 00:18:46 +01003280 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3281 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003282
Gilles Peskine8817f612018-12-18 00:18:46 +01003283 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3284 output2, output2_buffer_size,
3285 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003286 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003287
Gilles Peskine8817f612018-12-18 00:18:46 +01003288 PSA_ASSERT( psa_cipher_update( &operation2,
3289 output1 + first_part_size,
3290 output1_length - first_part_size,
3291 output2, output2_buffer_size,
3292 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003293 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003294
Gilles Peskine8817f612018-12-18 00:18:46 +01003295 PSA_ASSERT( psa_cipher_finish( &operation2,
3296 output2 + output2_length,
3297 output2_buffer_size - output2_length,
3298 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003299 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003300
Gilles Peskine8817f612018-12-18 00:18:46 +01003301 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003302
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003303 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003304
3305exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003306 mbedtls_free( output1 );
3307 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003308 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003309 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003310}
3311/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003312
Gilles Peskine20035e32018-02-03 22:44:14 +01003313/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003314void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003315 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003316 data_t *nonce,
3317 data_t *additional_data,
3318 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003319 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003320{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003321 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003322 psa_key_type_t key_type = key_type_arg;
3323 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003324 unsigned char *output_data = NULL;
3325 size_t output_size = 0;
3326 size_t output_length = 0;
3327 unsigned char *output_data2 = NULL;
3328 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003329 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003330 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003331 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003332
Gilles Peskine4abf7412018-06-18 16:35:34 +02003333 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003334 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3335 * should be exact. */
3336 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3337 TEST_EQUAL( output_size,
3338 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003339 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003340
Gilles Peskine8817f612018-12-18 00:18:46 +01003341 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003342
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003343 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3344 psa_set_key_algorithm( &attributes, alg );
3345 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003346
Gilles Peskine049c7532019-05-15 20:22:09 +02003347 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3348 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003349
Gilles Peskinefe11b722018-12-18 00:24:04 +01003350 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3351 nonce->x, nonce->len,
3352 additional_data->x,
3353 additional_data->len,
3354 input_data->x, input_data->len,
3355 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003356 &output_length ),
3357 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003358
3359 if( PSA_SUCCESS == expected_result )
3360 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003361 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003362
Gilles Peskine003a4a92019-05-14 16:09:40 +02003363 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3364 * should be exact. */
3365 TEST_EQUAL( input_data->len,
3366 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3367
Gilles Peskinefe11b722018-12-18 00:24:04 +01003368 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3369 nonce->x, nonce->len,
3370 additional_data->x,
3371 additional_data->len,
3372 output_data, output_length,
3373 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003374 &output_length2 ),
3375 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003376
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003377 ASSERT_COMPARE( input_data->x, input_data->len,
3378 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003379 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003380
Gilles Peskinea1cac842018-06-11 19:33:02 +02003381exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003382 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003383 mbedtls_free( output_data );
3384 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003385 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003386}
3387/* END_CASE */
3388
3389/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003390void aead_encrypt( int key_type_arg, data_t *key_data,
3391 int alg_arg,
3392 data_t *nonce,
3393 data_t *additional_data,
3394 data_t *input_data,
3395 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003396{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003397 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398 psa_key_type_t key_type = key_type_arg;
3399 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400 unsigned char *output_data = NULL;
3401 size_t output_size = 0;
3402 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003403 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003404 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003405
Gilles Peskine4abf7412018-06-18 16:35:34 +02003406 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003407 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3408 * should be exact. */
3409 TEST_EQUAL( output_size,
3410 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003411 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003412
Gilles Peskine8817f612018-12-18 00:18:46 +01003413 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003414
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003415 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3416 psa_set_key_algorithm( &attributes, alg );
3417 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418
Gilles Peskine049c7532019-05-15 20:22:09 +02003419 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3420 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421
Gilles Peskine8817f612018-12-18 00:18:46 +01003422 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3423 nonce->x, nonce->len,
3424 additional_data->x, additional_data->len,
3425 input_data->x, input_data->len,
3426 output_data, output_size,
3427 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003428
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003429 ASSERT_COMPARE( expected_result->x, expected_result->len,
3430 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003431
Gilles Peskinea1cac842018-06-11 19:33:02 +02003432exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003433 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003434 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003435 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003436}
3437/* END_CASE */
3438
3439/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003440void aead_decrypt( int key_type_arg, data_t *key_data,
3441 int alg_arg,
3442 data_t *nonce,
3443 data_t *additional_data,
3444 data_t *input_data,
3445 data_t *expected_data,
3446 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003447{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003448 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003449 psa_key_type_t key_type = key_type_arg;
3450 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003451 unsigned char *output_data = NULL;
3452 size_t output_size = 0;
3453 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003454 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003455 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003456 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003457
Gilles Peskine003a4a92019-05-14 16:09:40 +02003458 output_size = input_data->len - tag_length;
3459 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3460 * should be exact. */
3461 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3462 TEST_EQUAL( output_size,
3463 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003464 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003465
Gilles Peskine8817f612018-12-18 00:18:46 +01003466 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003467
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003468 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3469 psa_set_key_algorithm( &attributes, alg );
3470 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003471
Gilles Peskine049c7532019-05-15 20:22:09 +02003472 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3473 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003474
Gilles Peskinefe11b722018-12-18 00:24:04 +01003475 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3476 nonce->x, nonce->len,
3477 additional_data->x,
3478 additional_data->len,
3479 input_data->x, input_data->len,
3480 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003481 &output_length ),
3482 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003483
Gilles Peskine2d277862018-06-18 15:41:12 +02003484 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003485 ASSERT_COMPARE( expected_data->x, expected_data->len,
3486 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003487
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003489 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003490 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003491 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003492}
3493/* END_CASE */
3494
3495/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003496void signature_size( int type_arg,
3497 int bits,
3498 int alg_arg,
3499 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003500{
3501 psa_key_type_t type = type_arg;
3502 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003503 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003504 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003505exit:
3506 ;
3507}
3508/* END_CASE */
3509
3510/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003511void sign_deterministic( int key_type_arg, data_t *key_data,
3512 int alg_arg, data_t *input_data,
3513 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003514{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003515 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003516 psa_key_type_t key_type = key_type_arg;
3517 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003518 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003519 unsigned char *signature = NULL;
3520 size_t signature_size;
3521 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003522 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003523
Gilles Peskine8817f612018-12-18 00:18:46 +01003524 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003525
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003526 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3527 psa_set_key_algorithm( &attributes, alg );
3528 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003529
Gilles Peskine049c7532019-05-15 20:22:09 +02003530 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3531 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003532 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3533 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003534
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003535 /* Allocate a buffer which has the size advertized by the
3536 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003537 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3538 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003539 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003540 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003541 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003542
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003543 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003544 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3545 input_data->x, input_data->len,
3546 signature, signature_size,
3547 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003548 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003549 ASSERT_COMPARE( output_data->x, output_data->len,
3550 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003551
3552exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003553 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003554 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003555 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003556 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003557}
3558/* END_CASE */
3559
3560/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003561void sign_fail( int key_type_arg, data_t *key_data,
3562 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003563 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003564{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003565 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003566 psa_key_type_t key_type = key_type_arg;
3567 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003568 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003569 psa_status_t actual_status;
3570 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003571 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003572 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003573 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003574
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003575 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003576
Gilles Peskine8817f612018-12-18 00:18:46 +01003577 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003578
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003579 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3580 psa_set_key_algorithm( &attributes, alg );
3581 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003582
Gilles Peskine049c7532019-05-15 20:22:09 +02003583 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3584 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003585
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003586 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003587 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003588 signature, signature_size,
3589 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003590 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003591 /* The value of *signature_length is unspecified on error, but
3592 * whatever it is, it should be less than signature_size, so that
3593 * if the caller tries to read *signature_length bytes without
3594 * checking the error code then they don't overflow a buffer. */
3595 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003596
3597exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003598 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003599 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003600 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003601 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003602}
3603/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003604
3605/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003606void sign_verify( int key_type_arg, data_t *key_data,
3607 int alg_arg, data_t *input_data )
3608{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003609 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003610 psa_key_type_t key_type = key_type_arg;
3611 psa_algorithm_t alg = alg_arg;
3612 size_t key_bits;
3613 unsigned char *signature = NULL;
3614 size_t signature_size;
3615 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003616 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003617
Gilles Peskine8817f612018-12-18 00:18:46 +01003618 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003619
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003620 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3621 psa_set_key_algorithm( &attributes, alg );
3622 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003623
Gilles Peskine049c7532019-05-15 20:22:09 +02003624 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3625 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003626 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3627 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003628
3629 /* Allocate a buffer which has the size advertized by the
3630 * library. */
3631 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3632 key_bits, alg );
3633 TEST_ASSERT( signature_size != 0 );
3634 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003635 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003636
3637 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003638 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3639 input_data->x, input_data->len,
3640 signature, signature_size,
3641 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003642 /* Check that the signature length looks sensible. */
3643 TEST_ASSERT( signature_length <= signature_size );
3644 TEST_ASSERT( signature_length > 0 );
3645
3646 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003647 PSA_ASSERT( psa_asymmetric_verify(
3648 handle, alg,
3649 input_data->x, input_data->len,
3650 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003651
3652 if( input_data->len != 0 )
3653 {
3654 /* Flip a bit in the input and verify that the signature is now
3655 * detected as invalid. Flip a bit at the beginning, not at the end,
3656 * because ECDSA may ignore the last few bits of the input. */
3657 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003658 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3659 input_data->x, input_data->len,
3660 signature, signature_length ),
3661 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003662 }
3663
3664exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003665 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003666 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003667 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003668 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003669}
3670/* END_CASE */
3671
3672/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003673void asymmetric_verify( int key_type_arg, data_t *key_data,
3674 int alg_arg, data_t *hash_data,
3675 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003676{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003677 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003678 psa_key_type_t key_type = key_type_arg;
3679 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003680 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003681
Gilles Peskine69c12672018-06-28 00:07:19 +02003682 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3683
Gilles Peskine8817f612018-12-18 00:18:46 +01003684 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003685
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003686 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3687 psa_set_key_algorithm( &attributes, alg );
3688 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003689
Gilles Peskine049c7532019-05-15 20:22:09 +02003690 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3691 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003692
Gilles Peskine8817f612018-12-18 00:18:46 +01003693 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3694 hash_data->x, hash_data->len,
3695 signature_data->x,
3696 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003697exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003698 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003699 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003700 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003701}
3702/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003703
3704/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003705void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3706 int alg_arg, data_t *hash_data,
3707 data_t *signature_data,
3708 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003709{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003710 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003711 psa_key_type_t key_type = key_type_arg;
3712 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003713 psa_status_t actual_status;
3714 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003715 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003716
Gilles Peskine8817f612018-12-18 00:18:46 +01003717 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003718
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003719 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3720 psa_set_key_algorithm( &attributes, alg );
3721 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003722
Gilles Peskine049c7532019-05-15 20:22:09 +02003723 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3724 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003725
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003726 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003727 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003728 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003729 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003730
Gilles Peskinefe11b722018-12-18 00:24:04 +01003731 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003732
3733exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003734 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003735 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003736 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003737}
3738/* END_CASE */
3739
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003740/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003741void asymmetric_encrypt( int key_type_arg,
3742 data_t *key_data,
3743 int alg_arg,
3744 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003745 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003746 int expected_output_length_arg,
3747 int expected_status_arg )
3748{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003749 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003750 psa_key_type_t key_type = key_type_arg;
3751 psa_algorithm_t alg = alg_arg;
3752 size_t expected_output_length = expected_output_length_arg;
3753 size_t key_bits;
3754 unsigned char *output = NULL;
3755 size_t output_size;
3756 size_t output_length = ~0;
3757 psa_status_t actual_status;
3758 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003759 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003760
Gilles Peskine8817f612018-12-18 00:18:46 +01003761 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003762
Gilles Peskine656896e2018-06-29 19:12:28 +02003763 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003764 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3765 psa_set_key_algorithm( &attributes, alg );
3766 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003767 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3768 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003769
3770 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003771 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3772 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003773 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003774 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003775
3776 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003777 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003778 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003779 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003780 output, output_size,
3781 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003782 TEST_EQUAL( actual_status, expected_status );
3783 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003784
Gilles Peskine68428122018-06-30 18:42:41 +02003785 /* If the label is empty, the test framework puts a non-null pointer
3786 * in label->x. Test that a null pointer works as well. */
3787 if( label->len == 0 )
3788 {
3789 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003790 if( output_size != 0 )
3791 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003792 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003793 input_data->x, input_data->len,
3794 NULL, label->len,
3795 output, output_size,
3796 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003797 TEST_EQUAL( actual_status, expected_status );
3798 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003799 }
3800
Gilles Peskine656896e2018-06-29 19:12:28 +02003801exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003802 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003803 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003804 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003805 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02003806}
3807/* END_CASE */
3808
3809/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003810void asymmetric_encrypt_decrypt( int key_type_arg,
3811 data_t *key_data,
3812 int alg_arg,
3813 data_t *input_data,
3814 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003815{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003816 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003817 psa_key_type_t key_type = key_type_arg;
3818 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003819 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003820 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003821 size_t output_size;
3822 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003823 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003824 size_t output2_size;
3825 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003826 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003827
Gilles Peskine8817f612018-12-18 00:18:46 +01003828 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003829
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003830 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3831 psa_set_key_algorithm( &attributes, alg );
3832 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003833
Gilles Peskine049c7532019-05-15 20:22:09 +02003834 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3835 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003836
3837 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003838 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3839 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003840 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003841 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003842 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003843 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003844
Gilles Peskineeebd7382018-06-08 18:11:54 +02003845 /* We test encryption by checking that encrypt-then-decrypt gives back
3846 * the original plaintext because of the non-optional random
3847 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003848 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3849 input_data->x, input_data->len,
3850 label->x, label->len,
3851 output, output_size,
3852 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003853 /* We don't know what ciphertext length to expect, but check that
3854 * it looks sensible. */
3855 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003856
Gilles Peskine8817f612018-12-18 00:18:46 +01003857 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3858 output, output_length,
3859 label->x, label->len,
3860 output2, output2_size,
3861 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003862 ASSERT_COMPARE( input_data->x, input_data->len,
3863 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003864
3865exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003866 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003867 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003868 mbedtls_free( output );
3869 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003870 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871}
3872/* END_CASE */
3873
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003874/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003875void asymmetric_decrypt( int key_type_arg,
3876 data_t *key_data,
3877 int alg_arg,
3878 data_t *input_data,
3879 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003880 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003882 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883 psa_key_type_t key_type = key_type_arg;
3884 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003885 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003886 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003887 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003888 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003889
Jaeden Amero412654a2019-02-06 12:57:46 +00003890 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003891 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003892
Gilles Peskine8817f612018-12-18 00:18:46 +01003893 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003894
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003895 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3896 psa_set_key_algorithm( &attributes, alg );
3897 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003898
Gilles Peskine049c7532019-05-15 20:22:09 +02003899 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3900 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003901
Gilles Peskine8817f612018-12-18 00:18:46 +01003902 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3903 input_data->x, input_data->len,
3904 label->x, label->len,
3905 output,
3906 output_size,
3907 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003908 ASSERT_COMPARE( expected_data->x, expected_data->len,
3909 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003910
Gilles Peskine68428122018-06-30 18:42:41 +02003911 /* If the label is empty, the test framework puts a non-null pointer
3912 * in label->x. Test that a null pointer works as well. */
3913 if( label->len == 0 )
3914 {
3915 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003916 if( output_size != 0 )
3917 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003918 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3919 input_data->x, input_data->len,
3920 NULL, label->len,
3921 output,
3922 output_size,
3923 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003924 ASSERT_COMPARE( expected_data->x, expected_data->len,
3925 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003926 }
3927
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003928exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003929 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003930 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003931 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003932 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003933}
3934/* END_CASE */
3935
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003936/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003937void asymmetric_decrypt_fail( int key_type_arg,
3938 data_t *key_data,
3939 int alg_arg,
3940 data_t *input_data,
3941 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003942 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003943 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003944{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003945 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003946 psa_key_type_t key_type = key_type_arg;
3947 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003948 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003949 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003950 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003951 psa_status_t actual_status;
3952 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003953 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003954
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003955 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003956
Gilles Peskine8817f612018-12-18 00:18:46 +01003957 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003958
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003959 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3960 psa_set_key_algorithm( &attributes, alg );
3961 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003962
Gilles Peskine049c7532019-05-15 20:22:09 +02003963 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3964 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003965
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003966 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003967 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003968 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003969 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003970 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003971 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003972 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003973
Gilles Peskine68428122018-06-30 18:42:41 +02003974 /* If the label is empty, the test framework puts a non-null pointer
3975 * in label->x. Test that a null pointer works as well. */
3976 if( label->len == 0 )
3977 {
3978 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003979 if( output_size != 0 )
3980 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003981 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003982 input_data->x, input_data->len,
3983 NULL, label->len,
3984 output, output_size,
3985 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003986 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003987 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003988 }
3989
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003990exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003991 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003992 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003993 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003994 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003995}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003996/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003997
3998/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02003999void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004000{
4001 /* Test each valid way of initializing the object, except for `= {0}`, as
4002 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4003 * though it's OK by the C standard. We could test for this, but we'd need
4004 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004005 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004006 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4007 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4008 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004009
4010 memset( &zero, 0, sizeof( zero ) );
4011
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004012 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004013 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004014 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004015 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004016 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004017 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004018 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004019
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004020 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004021 PSA_ASSERT( psa_key_derivation_abort(&func) );
4022 PSA_ASSERT( psa_key_derivation_abort(&init) );
4023 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004024}
4025/* END_CASE */
4026
4027/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004028void derive_setup( int key_type_arg,
4029 data_t *key_data,
4030 int alg_arg,
4031 data_t *salt,
4032 data_t *label,
4033 int requested_capacity_arg,
4034 int expected_status_arg )
4035{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004036 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004037 size_t key_type = key_type_arg;
4038 psa_algorithm_t alg = alg_arg;
4039 size_t requested_capacity = requested_capacity_arg;
4040 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004041 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004042 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004043
Gilles Peskine8817f612018-12-18 00:18:46 +01004044 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004045
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004046 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4047 psa_set_key_algorithm( &attributes, alg );
4048 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004049
Gilles Peskine049c7532019-05-15 20:22:09 +02004050 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4051 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004052
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004053 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004054 salt->x, salt->len,
4055 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004056 requested_capacity ),
4057 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004058
4059exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004060 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004061 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004062 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004063}
4064/* END_CASE */
4065
4066/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004067void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004068{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004069 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004070 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004071 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004072 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004073 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004074 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004075 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4076 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4077 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004078 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004079
Gilles Peskine8817f612018-12-18 00:18:46 +01004080 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004081
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004082 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4083 psa_set_key_algorithm( &attributes, alg );
4084 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004085
Gilles Peskine73676cb2019-05-15 20:15:10 +02004086 PSA_ASSERT( psa_import_key( &attributes,
4087 key_data, sizeof( key_data ),
4088 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004089
4090 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004091 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004092 NULL, 0,
4093 NULL, 0,
4094 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004095
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004096 /* state of operation shouldn't allow additional generation */
4097 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004098 NULL, 0,
4099 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004100 capacity ),
4101 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004102
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004103 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004104
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004105 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004106 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004107
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004108exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004109 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004110 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004111 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004112}
4113/* END_CASE */
4114
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004115/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004116void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004117{
4118 uint8_t output_buffer[16];
4119 size_t buffer_size = 16;
4120 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004121 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004122
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004123 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4124 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004125 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004126
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004127 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004128 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004129
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004130 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004131
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004132 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4133 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004134 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004135
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004136 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004137 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004138
4139exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004140 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004141}
4142/* END_CASE */
4143
4144/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004145void derive_output( int alg_arg,
4146 data_t *key_data,
4147 data_t *salt,
4148 data_t *label,
4149 int requested_capacity_arg,
4150 data_t *expected_output1,
4151 data_t *expected_output2 )
4152{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004153 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004154 psa_algorithm_t alg = alg_arg;
4155 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004156 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004157 uint8_t *expected_outputs[2] =
4158 {expected_output1->x, expected_output2->x};
4159 size_t output_sizes[2] =
4160 {expected_output1->len, expected_output2->len};
4161 size_t output_buffer_size = 0;
4162 uint8_t *output_buffer = NULL;
4163 size_t expected_capacity;
4164 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004165 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004166 psa_status_t status;
4167 unsigned i;
4168
4169 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4170 {
4171 if( output_sizes[i] > output_buffer_size )
4172 output_buffer_size = output_sizes[i];
4173 if( output_sizes[i] == 0 )
4174 expected_outputs[i] = NULL;
4175 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004176 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004177 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004178
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004179 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4180 psa_set_key_algorithm( &attributes, alg );
4181 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004182
Gilles Peskine049c7532019-05-15 20:22:09 +02004183 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4184 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004185
4186 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004187 if( PSA_ALG_IS_HKDF( alg ) )
4188 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004189 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4190 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004191 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004192 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004193 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004194 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004195 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004196 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004197 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004198 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004199 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004200 label->x, label->len ) );
4201 }
4202 else
4203 {
4204 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004205 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004206 salt->x, salt->len,
4207 label->x, label->len,
4208 requested_capacity ) );
4209 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004210 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004211 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004212 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004213 expected_capacity = requested_capacity;
4214
4215 /* Expansion phase. */
4216 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4217 {
4218 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004219 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004220 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004221 if( expected_capacity == 0 && output_sizes[i] == 0 )
4222 {
4223 /* Reading 0 bytes when 0 bytes are available can go either way. */
4224 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004225 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004226 continue;
4227 }
4228 else if( expected_capacity == 0 ||
4229 output_sizes[i] > expected_capacity )
4230 {
4231 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004232 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004233 expected_capacity = 0;
4234 continue;
4235 }
4236 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004237 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004238 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004239 ASSERT_COMPARE( output_buffer, output_sizes[i],
4240 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004241 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004242 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004243 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004244 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004245 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004246 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004247 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004248
4249exit:
4250 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004251 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004252 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004253 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004254}
4255/* END_CASE */
4256
4257/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004258void derive_full( int alg_arg,
4259 data_t *key_data,
4260 data_t *salt,
4261 data_t *label,
4262 int requested_capacity_arg )
4263{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004264 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004265 psa_algorithm_t alg = alg_arg;
4266 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004267 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004268 unsigned char output_buffer[16];
4269 size_t expected_capacity = requested_capacity;
4270 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004271 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004272
Gilles Peskine8817f612018-12-18 00:18:46 +01004273 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004274
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004275 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4276 psa_set_key_algorithm( &attributes, alg );
4277 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004278
Gilles Peskine049c7532019-05-15 20:22:09 +02004279 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4280 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004281
4282 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004283 if( PSA_ALG_IS_HKDF( alg ) )
4284 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004285 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4286 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004287 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004288 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004289 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004290 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004291 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004292 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004293 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004294 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004295 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004296 label->x, label->len ) );
4297 }
4298 else
4299 {
4300 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004301 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004302 salt->x, salt->len,
4303 label->x, label->len,
4304 requested_capacity ) );
4305 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004306 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004307 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004308 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004309
4310 /* Expansion phase. */
4311 while( current_capacity > 0 )
4312 {
4313 size_t read_size = sizeof( output_buffer );
4314 if( read_size > current_capacity )
4315 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004316 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004317 output_buffer,
4318 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004319 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004320 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004321 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004322 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004323 }
4324
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004325 /* Check that the operation refuses to go over capacity. */
4326 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004327 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004328
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004329 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004330
4331exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004332 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004333 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004334 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004335}
4336/* END_CASE */
4337
4338/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004339void derive_key_exercise( int alg_arg,
4340 data_t *key_data,
4341 data_t *salt,
4342 data_t *label,
4343 int derived_type_arg,
4344 int derived_bits_arg,
4345 int derived_usage_arg,
4346 int derived_alg_arg )
4347{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004348 psa_key_handle_t base_handle = 0;
4349 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004350 psa_algorithm_t alg = alg_arg;
4351 psa_key_type_t derived_type = derived_type_arg;
4352 size_t derived_bits = derived_bits_arg;
4353 psa_key_usage_t derived_usage = derived_usage_arg;
4354 psa_algorithm_t derived_alg = derived_alg_arg;
4355 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004356 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004357 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004358 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004359
Gilles Peskine8817f612018-12-18 00:18:46 +01004360 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004361
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004362 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4363 psa_set_key_algorithm( &attributes, alg );
4364 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004365 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4366 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004367
4368 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004369 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004370 salt->x, salt->len,
4371 label->x, label->len,
4372 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004373 psa_set_key_usage_flags( &attributes, derived_usage );
4374 psa_set_key_algorithm( &attributes, derived_alg );
4375 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004376 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004377 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004378 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004379
4380 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004381 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4382 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4383 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004384
4385 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004386 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004387 goto exit;
4388
4389exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004390 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004391 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004392 psa_destroy_key( base_handle );
4393 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004394 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004395}
4396/* END_CASE */
4397
4398/* BEGIN_CASE */
4399void derive_key_export( int alg_arg,
4400 data_t *key_data,
4401 data_t *salt,
4402 data_t *label,
4403 int bytes1_arg,
4404 int bytes2_arg )
4405{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004406 psa_key_handle_t base_handle = 0;
4407 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004408 psa_algorithm_t alg = alg_arg;
4409 size_t bytes1 = bytes1_arg;
4410 size_t bytes2 = bytes2_arg;
4411 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004412 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004413 uint8_t *output_buffer = NULL;
4414 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004415 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4416 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004417 size_t length;
4418
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004419 ASSERT_ALLOC( output_buffer, capacity );
4420 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004421 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004422
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004423 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4424 psa_set_key_algorithm( &base_attributes, alg );
4425 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004426 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4427 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004428
4429 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004430 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004431 salt->x, salt->len,
4432 label->x, label->len,
4433 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004434 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004435 output_buffer,
4436 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004437 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004438
4439 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004440 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004441 salt->x, salt->len,
4442 label->x, label->len,
4443 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004444 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4445 psa_set_key_algorithm( &derived_attributes, 0 );
4446 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004447 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004448 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004449 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004450 PSA_ASSERT( psa_export_key( derived_handle,
4451 export_buffer, bytes1,
4452 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004453 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004454 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004455 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004456 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004457 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004458 PSA_ASSERT( psa_export_key( derived_handle,
4459 export_buffer + bytes1, bytes2,
4460 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004461 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004462
4463 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004464 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4465 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004466
4467exit:
4468 mbedtls_free( output_buffer );
4469 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004470 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004471 psa_destroy_key( base_handle );
4472 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004473 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004474}
4475/* END_CASE */
4476
4477/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004478void key_agreement_setup( int alg_arg,
4479 int our_key_type_arg, data_t *our_key_data,
4480 data_t *peer_key_data,
4481 int expected_status_arg )
4482{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004483 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004484 psa_algorithm_t alg = alg_arg;
4485 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004486 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004487 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004488 psa_status_t expected_status = expected_status_arg;
4489 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004490
Gilles Peskine8817f612018-12-18 00:18:46 +01004491 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004492
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004493 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4494 psa_set_key_algorithm( &attributes, alg );
4495 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004496 PSA_ASSERT( psa_import_key( &attributes,
4497 our_key_data->x, our_key_data->len,
4498 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004499
Gilles Peskine77f40d82019-04-11 21:27:06 +02004500 /* The tests currently include inputs that should fail at either step.
4501 * Test cases that fail at the setup step should be changed to call
4502 * key_derivation_setup instead, and this function should be renamed
4503 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004504 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004505 if( status == PSA_SUCCESS )
4506 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004507 TEST_EQUAL( psa_key_derivation_key_agreement(
4508 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4509 our_key,
4510 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004511 expected_status );
4512 }
4513 else
4514 {
4515 TEST_ASSERT( status == expected_status );
4516 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004517
4518exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004519 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004520 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004521 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004522}
4523/* END_CASE */
4524
4525/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004526void raw_key_agreement( int alg_arg,
4527 int our_key_type_arg, data_t *our_key_data,
4528 data_t *peer_key_data,
4529 data_t *expected_output )
4530{
4531 psa_key_handle_t our_key = 0;
4532 psa_algorithm_t alg = alg_arg;
4533 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004534 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004535 unsigned char *output = NULL;
4536 size_t output_length = ~0;
4537
4538 ASSERT_ALLOC( output, expected_output->len );
4539 PSA_ASSERT( psa_crypto_init( ) );
4540
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 Peskinef0cba732019-04-11 22:12:38 +02004547
Gilles Peskinebe697d82019-05-16 18:00:41 +02004548 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4549 peer_key_data->x, peer_key_data->len,
4550 output, expected_output->len,
4551 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004552 ASSERT_COMPARE( output, output_length,
4553 expected_output->x, expected_output->len );
4554
4555exit:
4556 mbedtls_free( output );
4557 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004558 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004559}
4560/* END_CASE */
4561
4562/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004563void key_agreement_capacity( int alg_arg,
4564 int our_key_type_arg, data_t *our_key_data,
4565 data_t *peer_key_data,
4566 int expected_capacity_arg )
4567{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004568 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004569 psa_algorithm_t alg = alg_arg;
4570 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004571 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004572 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004573 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004574 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004575
Gilles Peskine8817f612018-12-18 00:18:46 +01004576 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004577
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004578 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4579 psa_set_key_algorithm( &attributes, alg );
4580 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004581 PSA_ASSERT( psa_import_key( &attributes,
4582 our_key_data->x, our_key_data->len,
4583 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004584
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004585 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004586 PSA_ASSERT( psa_key_derivation_key_agreement(
4587 &operation,
4588 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4589 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004590 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4591 {
4592 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004593 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004594 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004595 NULL, 0 ) );
4596 }
Gilles Peskine59685592018-09-18 12:11:34 +02004597
Gilles Peskinebf491972018-10-25 22:36:12 +02004598 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004599 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004600 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004601 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004602
Gilles Peskinebf491972018-10-25 22:36:12 +02004603 /* Test the actual capacity by reading the output. */
4604 while( actual_capacity > sizeof( output ) )
4605 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004606 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004607 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004608 actual_capacity -= sizeof( output );
4609 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004610 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004611 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004612 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004613 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004614
Gilles Peskine59685592018-09-18 12:11:34 +02004615exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004616 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004617 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004618 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004619}
4620/* END_CASE */
4621
4622/* BEGIN_CASE */
4623void key_agreement_output( int alg_arg,
4624 int our_key_type_arg, data_t *our_key_data,
4625 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004626 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004627{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004628 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004629 psa_algorithm_t alg = alg_arg;
4630 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004631 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004632 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004633 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004634
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004635 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4636 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004637
Gilles Peskine8817f612018-12-18 00:18:46 +01004638 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004639
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004640 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4641 psa_set_key_algorithm( &attributes, alg );
4642 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004643 PSA_ASSERT( psa_import_key( &attributes,
4644 our_key_data->x, our_key_data->len,
4645 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004646
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004647 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004648 PSA_ASSERT( psa_key_derivation_key_agreement(
4649 &operation,
4650 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4651 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004652 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4653 {
4654 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004655 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004656 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004657 NULL, 0 ) );
4658 }
Gilles Peskine59685592018-09-18 12:11:34 +02004659
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004660 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004661 actual_output,
4662 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004663 ASSERT_COMPARE( actual_output, expected_output1->len,
4664 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004665 if( expected_output2->len != 0 )
4666 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004667 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004668 actual_output,
4669 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004670 ASSERT_COMPARE( actual_output, expected_output2->len,
4671 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004672 }
Gilles Peskine59685592018-09-18 12:11:34 +02004673
4674exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004675 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004676 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004677 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004678 mbedtls_free( actual_output );
4679}
4680/* END_CASE */
4681
4682/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004683void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004684{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004685 size_t bytes = bytes_arg;
4686 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004687 unsigned char *output = NULL;
4688 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004689 size_t i;
4690 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004691
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004692 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4693 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004694 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004695
Gilles Peskine8817f612018-12-18 00:18:46 +01004696 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004697
Gilles Peskinea50d7392018-06-21 10:22:13 +02004698 /* Run several times, to ensure that every output byte will be
4699 * nonzero at least once with overwhelming probability
4700 * (2^(-8*number_of_runs)). */
4701 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004702 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004703 if( bytes != 0 )
4704 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004705 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004706
4707 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004708 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4709 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004710
4711 for( i = 0; i < bytes; i++ )
4712 {
4713 if( output[i] != 0 )
4714 ++changed[i];
4715 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004716 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004717
4718 /* Check that every byte was changed to nonzero at least once. This
4719 * validates that psa_generate_random is overwriting every byte of
4720 * the output buffer. */
4721 for( i = 0; i < bytes; i++ )
4722 {
4723 TEST_ASSERT( changed[i] != 0 );
4724 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004725
4726exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004727 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004728 mbedtls_free( output );
4729 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004730}
4731/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004732
4733/* BEGIN_CASE */
4734void generate_key( int type_arg,
4735 int bits_arg,
4736 int usage_arg,
4737 int alg_arg,
4738 int expected_status_arg )
4739{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004740 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004741 psa_key_type_t type = type_arg;
4742 psa_key_usage_t usage = usage_arg;
4743 size_t bits = bits_arg;
4744 psa_algorithm_t alg = alg_arg;
4745 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004746 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004747 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004748
Gilles Peskine8817f612018-12-18 00:18:46 +01004749 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004750
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004751 psa_set_key_usage_flags( &attributes, usage );
4752 psa_set_key_algorithm( &attributes, alg );
4753 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004754 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004755
4756 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004757 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004758 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004759 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004760
4761 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004762 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4763 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4764 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004765
Gilles Peskine818ca122018-06-20 18:16:48 +02004766 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004767 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004768 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004769
4770exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004771 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004772 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004773 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004774}
4775/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004776
Gilles Peskinee56e8782019-04-26 17:34:02 +02004777/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4778void generate_key_rsa( int bits_arg,
4779 data_t *e_arg,
4780 int expected_status_arg )
4781{
4782 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02004783 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02004784 size_t bits = bits_arg;
4785 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4786 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4787 psa_status_t expected_status = expected_status_arg;
4788 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4789 uint8_t *exported = NULL;
4790 size_t exported_size =
4791 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4792 size_t exported_length = SIZE_MAX;
4793 uint8_t *e_read_buffer = NULL;
4794 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004795 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004796 size_t e_read_length = SIZE_MAX;
4797
4798 if( e_arg->len == 0 ||
4799 ( e_arg->len == 3 &&
4800 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4801 {
4802 is_default_public_exponent = 1;
4803 e_read_size = 0;
4804 }
4805 ASSERT_ALLOC( e_read_buffer, e_read_size );
4806 ASSERT_ALLOC( exported, exported_size );
4807
4808 PSA_ASSERT( psa_crypto_init( ) );
4809
4810 psa_set_key_usage_flags( &attributes, usage );
4811 psa_set_key_algorithm( &attributes, alg );
4812 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4813 e_arg->x, e_arg->len ) );
4814 psa_set_key_bits( &attributes, bits );
4815
4816 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004817 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004818 if( expected_status != PSA_SUCCESS )
4819 goto exit;
4820
4821 /* Test the key information */
4822 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4823 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4824 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4825 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4826 e_read_buffer, e_read_size,
4827 &e_read_length ) );
4828 if( is_default_public_exponent )
4829 TEST_EQUAL( e_read_length, 0 );
4830 else
4831 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4832
4833 /* Do something with the key according to its type and permitted usage. */
4834 if( ! exercise_key( handle, usage, alg ) )
4835 goto exit;
4836
4837 /* Export the key and check the public exponent. */
4838 PSA_ASSERT( psa_export_public_key( handle,
4839 exported, exported_size,
4840 &exported_length ) );
4841 {
4842 uint8_t *p = exported;
4843 uint8_t *end = exported + exported_length;
4844 size_t len;
4845 /* RSAPublicKey ::= SEQUENCE {
4846 * modulus INTEGER, -- n
4847 * publicExponent INTEGER } -- e
4848 */
4849 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004850 MBEDTLS_ASN1_SEQUENCE |
4851 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004852 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4853 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4854 MBEDTLS_ASN1_INTEGER ) );
4855 if( len >= 1 && p[0] == 0 )
4856 {
4857 ++p;
4858 --len;
4859 }
4860 if( e_arg->len == 0 )
4861 {
4862 TEST_EQUAL( len, 3 );
4863 TEST_EQUAL( p[0], 1 );
4864 TEST_EQUAL( p[1], 0 );
4865 TEST_EQUAL( p[2], 1 );
4866 }
4867 else
4868 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4869 }
4870
4871exit:
4872 psa_reset_key_attributes( &attributes );
4873 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004874 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004875 mbedtls_free( e_read_buffer );
4876 mbedtls_free( exported );
4877}
4878/* END_CASE */
4879
Darryl Greend49a4992018-06-18 17:27:26 +01004880/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004881void persistent_key_load_key_from_storage( data_t *data,
4882 int type_arg, int bits_arg,
4883 int usage_flags_arg, int alg_arg,
4884 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004885{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004886 psa_key_id_t key_id = 1;
4887 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004888 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004889 psa_key_handle_t base_key = 0;
4890 psa_key_type_t type = type_arg;
4891 size_t bits = bits_arg;
4892 psa_key_usage_t usage_flags = usage_flags_arg;
4893 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004894 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004895 unsigned char *first_export = NULL;
4896 unsigned char *second_export = NULL;
4897 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4898 size_t first_exported_length;
4899 size_t second_exported_length;
4900
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004901 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4902 {
4903 ASSERT_ALLOC( first_export, export_size );
4904 ASSERT_ALLOC( second_export, export_size );
4905 }
Darryl Greend49a4992018-06-18 17:27:26 +01004906
Gilles Peskine8817f612018-12-18 00:18:46 +01004907 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004908
Gilles Peskinec87af662019-05-15 16:12:22 +02004909 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004910 psa_set_key_usage_flags( &attributes, usage_flags );
4911 psa_set_key_algorithm( &attributes, alg );
4912 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004913 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004914
Darryl Green0c6575a2018-11-07 16:05:30 +00004915 switch( generation_method )
4916 {
4917 case IMPORT_KEY:
4918 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004919 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4920 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004921 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004922
Darryl Green0c6575a2018-11-07 16:05:30 +00004923 case GENERATE_KEY:
4924 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004925 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004926 break;
4927
4928 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004929 {
4930 /* Create base key */
4931 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4932 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4933 psa_set_key_usage_flags( &base_attributes,
4934 PSA_KEY_USAGE_DERIVE );
4935 psa_set_key_algorithm( &base_attributes, derive_alg );
4936 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004937 PSA_ASSERT( psa_import_key( &base_attributes,
4938 data->x, data->len,
4939 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004940 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004941 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004942 PSA_ASSERT( psa_key_derivation_input_key(
4943 &operation,
4944 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004945 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004946 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004947 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004948 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
4949 &operation,
4950 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004951 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004952 PSA_ASSERT( psa_destroy_key( base_key ) );
4953 base_key = 0;
4954 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004955 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00004956 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004957 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004958
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004959 /* Export the key if permitted by the key policy. */
4960 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4961 {
4962 PSA_ASSERT( psa_export_key( handle,
4963 first_export, export_size,
4964 &first_exported_length ) );
4965 if( generation_method == IMPORT_KEY )
4966 ASSERT_COMPARE( data->x, data->len,
4967 first_export, first_exported_length );
4968 }
Darryl Greend49a4992018-06-18 17:27:26 +01004969
4970 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02004971 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004972 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01004973 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004974
Darryl Greend49a4992018-06-18 17:27:26 +01004975 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02004976 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004977 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4978 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4979 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4980 PSA_KEY_LIFETIME_PERSISTENT );
4981 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4982 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4983 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4984 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004985
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004986 /* Export the key again if permitted by the key policy. */
4987 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004988 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004989 PSA_ASSERT( psa_export_key( handle,
4990 second_export, export_size,
4991 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004992 ASSERT_COMPARE( first_export, first_exported_length,
4993 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004994 }
4995
4996 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004997 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004998 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004999
5000exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005001 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005002 mbedtls_free( first_export );
5003 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005004 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005005 psa_destroy_key( base_key );
5006 if( handle == 0 )
5007 {
5008 /* In case there was a test failure after creating the persistent key
5009 * but while it was not open, try to re-open the persistent key
5010 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005011 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005012 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005013 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005014 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005015}
5016/* END_CASE */