blob: e856e6e8bf69279f4ddc4c5e84e1925383282efe [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
4#if defined(MBEDTLS_PSA_CRYPTO_SPM)
5#include "spm/psa_defs.h"
6#endif
7
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02008#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02009#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +020010#include "mbedtls/oid.h"
11
Gilles Peskinee59236f2018-01-27 23:32:46 +010012#include "psa/crypto.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +030013
Jaeden Amerof24c7f82018-06-27 17:20:43 +010014/** An invalid export length that will never be set by psa_export_key(). */
15static const size_t INVALID_EXPORT_LENGTH = ~0U;
16
Gilles Peskinef426e0f2019-02-25 17:42:03 +010017/* A hash algorithm that is known to be supported.
18 *
19 * This is used in some smoke tests.
20 */
21#if defined(MBEDTLS_MD2_C)
22#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
23#elif defined(MBEDTLS_MD4_C)
24#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
25#elif defined(MBEDTLS_MD5_C)
26#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
27/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
28 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
29 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
30 * implausible anyway. */
31#elif defined(MBEDTLS_SHA1_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
33#elif defined(MBEDTLS_SHA256_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
35#elif defined(MBEDTLS_SHA512_C)
36#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
37#elif defined(MBEDTLS_SHA3_C)
38#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
39#else
40#undef KNOWN_SUPPORTED_HASH_ALG
41#endif
42
43/* A block cipher that is known to be supported.
44 *
45 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
46 */
47#if defined(MBEDTLS_AES_C)
48#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
49#elif defined(MBEDTLS_ARIA_C)
50#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
51#elif defined(MBEDTLS_CAMELLIA_C)
52#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
53#undef KNOWN_SUPPORTED_BLOCK_CIPHER
54#endif
55
56/* A MAC mode that is known to be supported.
57 *
58 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
59 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
60 *
61 * This is used in some smoke tests.
62 */
63#if defined(KNOWN_SUPPORTED_HASH_ALG)
64#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
65#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
66#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
67#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
68#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
69#else
70#undef KNOWN_SUPPORTED_MAC_ALG
71#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
72#endif
73
74/* A cipher algorithm and key type that are known to be supported.
75 *
76 * This is used in some smoke tests.
77 */
78#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
79#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
80#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
81#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
82#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
83#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
84#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
85#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
86#else
87#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
88#endif
89#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
90#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
91#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
92#elif defined(MBEDTLS_RC4_C)
93#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
94#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
95#else
96#undef KNOWN_SUPPORTED_CIPHER_ALG
97#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
98#endif
99
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200100/** Test if a buffer contains a constant byte value.
101 *
102 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200103 *
104 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200105 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 * \param size Size of the buffer in bytes.
107 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200108 * \return 1 if the buffer is all-bits-zero.
109 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200110 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200111static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200112{
113 size_t i;
114 for( i = 0; i < size; i++ )
115 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200116 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200117 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200118 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200119 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200120}
Gilles Peskine818ca122018-06-20 18:16:48 +0200121
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200122/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
123static int asn1_write_10x( unsigned char **p,
124 unsigned char *start,
125 size_t bits,
126 unsigned char x )
127{
128 int ret;
129 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200130 if( bits == 0 )
131 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
132 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200133 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300134 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200135 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
136 *p -= len;
137 ( *p )[len-1] = x;
138 if( bits % 8 == 0 )
139 ( *p )[1] |= 1;
140 else
141 ( *p )[0] |= 1 << ( bits % 8 );
142 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
143 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
144 MBEDTLS_ASN1_INTEGER ) );
145 return( len );
146}
147
148static int construct_fake_rsa_key( unsigned char *buffer,
149 size_t buffer_size,
150 unsigned char **p,
151 size_t bits,
152 int keypair )
153{
154 size_t half_bits = ( bits + 1 ) / 2;
155 int ret;
156 int len = 0;
157 /* Construct something that looks like a DER encoding of
158 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
159 * RSAPrivateKey ::= SEQUENCE {
160 * version Version,
161 * modulus INTEGER, -- n
162 * publicExponent INTEGER, -- e
163 * privateExponent INTEGER, -- d
164 * prime1 INTEGER, -- p
165 * prime2 INTEGER, -- q
166 * exponent1 INTEGER, -- d mod (p-1)
167 * exponent2 INTEGER, -- d mod (q-1)
168 * coefficient INTEGER, -- (inverse of q) mod p
169 * otherPrimeInfos OtherPrimeInfos OPTIONAL
170 * }
171 * Or, for a public key, the same structure with only
172 * version, modulus and publicExponent.
173 */
174 *p = buffer + buffer_size;
175 if( keypair )
176 {
177 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
178 asn1_write_10x( p, buffer, half_bits, 1 ) );
179 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
180 asn1_write_10x( p, buffer, half_bits, 1 ) );
181 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
182 asn1_write_10x( p, buffer, half_bits, 1 ) );
183 MBEDTLS_ASN1_CHK_ADD( len, /* q */
184 asn1_write_10x( p, buffer, half_bits, 1 ) );
185 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
186 asn1_write_10x( p, buffer, half_bits, 3 ) );
187 MBEDTLS_ASN1_CHK_ADD( len, /* d */
188 asn1_write_10x( p, buffer, bits, 1 ) );
189 }
190 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
191 asn1_write_10x( p, buffer, 17, 1 ) );
192 MBEDTLS_ASN1_CHK_ADD( len, /* n */
193 asn1_write_10x( p, buffer, bits, 1 ) );
194 if( keypair )
195 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
196 mbedtls_asn1_write_int( p, buffer, 0 ) );
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
198 {
199 const unsigned char tag =
200 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
201 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
202 }
203 return( len );
204}
205
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100206int exercise_mac_setup( psa_key_type_t key_type,
207 const unsigned char *key_bytes,
208 size_t key_length,
209 psa_algorithm_t alg,
210 psa_mac_operation_t *operation,
211 psa_status_t *status )
212{
213 psa_key_handle_t handle = 0;
214 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
215
216 PSA_ASSERT( psa_allocate_key( &handle ) );
217 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
218 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +0200219 PSA_ASSERT( psa_import_key_to_handle( handle, key_type, key_bytes, key_length ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100220
221 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100222 /* Whether setup succeeded or failed, abort must succeed. */
223 PSA_ASSERT( psa_mac_abort( operation ) );
224 /* If setup failed, reproduce the failure, so that the caller can
225 * test the resulting state of the operation object. */
226 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100227 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100228 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
229 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100230 }
231
232 psa_destroy_key( handle );
233 return( 1 );
234
235exit:
236 psa_destroy_key( handle );
237 return( 0 );
238}
239
240int exercise_cipher_setup( psa_key_type_t key_type,
241 const unsigned char *key_bytes,
242 size_t key_length,
243 psa_algorithm_t alg,
244 psa_cipher_operation_t *operation,
245 psa_status_t *status )
246{
247 psa_key_handle_t handle = 0;
248 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
249
250 PSA_ASSERT( psa_allocate_key( &handle ) );
251 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
252 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +0200253 PSA_ASSERT( psa_import_key_to_handle( handle, key_type, key_bytes, key_length ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100254
255 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100256 /* Whether setup succeeded or failed, abort must succeed. */
257 PSA_ASSERT( psa_cipher_abort( operation ) );
258 /* If setup failed, reproduce the failure, so that the caller can
259 * test the resulting state of the operation object. */
260 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100261 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100262 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
263 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100264 }
265
266 psa_destroy_key( handle );
267 return( 1 );
268
269exit:
270 psa_destroy_key( handle );
271 return( 0 );
272}
273
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100274static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200275 psa_key_usage_t usage,
276 psa_algorithm_t alg )
277{
Jaeden Amero769ce272019-01-04 11:48:03 +0000278 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200279 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200280 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200281 size_t mac_length = sizeof( mac );
282
283 if( usage & PSA_KEY_USAGE_SIGN )
284 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100285 PSA_ASSERT( psa_mac_sign_setup( &operation,
286 handle, alg ) );
287 PSA_ASSERT( psa_mac_update( &operation,
288 input, sizeof( input ) ) );
289 PSA_ASSERT( psa_mac_sign_finish( &operation,
290 mac, sizeof( mac ),
291 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200292 }
293
294 if( usage & PSA_KEY_USAGE_VERIFY )
295 {
296 psa_status_t verify_status =
297 ( usage & PSA_KEY_USAGE_SIGN ?
298 PSA_SUCCESS :
299 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100300 PSA_ASSERT( psa_mac_verify_setup( &operation,
301 handle, alg ) );
302 PSA_ASSERT( psa_mac_update( &operation,
303 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100304 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
305 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200306 }
307
308 return( 1 );
309
310exit:
311 psa_mac_abort( &operation );
312 return( 0 );
313}
314
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100315static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200316 psa_key_usage_t usage,
317 psa_algorithm_t alg )
318{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000319 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200320 unsigned char iv[16] = {0};
321 size_t iv_length = sizeof( iv );
322 const unsigned char plaintext[16] = "Hello, world...";
323 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
324 size_t ciphertext_length = sizeof( ciphertext );
325 unsigned char decrypted[sizeof( ciphertext )];
326 size_t part_length;
327
328 if( usage & PSA_KEY_USAGE_ENCRYPT )
329 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100330 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
331 handle, alg ) );
332 PSA_ASSERT( psa_cipher_generate_iv( &operation,
333 iv, sizeof( iv ),
334 &iv_length ) );
335 PSA_ASSERT( psa_cipher_update( &operation,
336 plaintext, sizeof( plaintext ),
337 ciphertext, sizeof( ciphertext ),
338 &ciphertext_length ) );
339 PSA_ASSERT( psa_cipher_finish( &operation,
340 ciphertext + ciphertext_length,
341 sizeof( ciphertext ) - ciphertext_length,
342 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200343 ciphertext_length += part_length;
344 }
345
346 if( usage & PSA_KEY_USAGE_DECRYPT )
347 {
348 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200349 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200350 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
351 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200352 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
353 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
354 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
355 * have this macro yet. */
356 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
357 psa_get_key_type( &attributes ) );
358 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200359 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100360 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
361 handle, alg ) );
362 PSA_ASSERT( psa_cipher_set_iv( &operation,
363 iv, iv_length ) );
364 PSA_ASSERT( psa_cipher_update( &operation,
365 ciphertext, ciphertext_length,
366 decrypted, sizeof( decrypted ),
367 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200368 status = psa_cipher_finish( &operation,
369 decrypted + part_length,
370 sizeof( decrypted ) - part_length,
371 &part_length );
372 /* For a stream cipher, all inputs are valid. For a block cipher,
373 * if the input is some aribtrary data rather than an actual
374 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200375 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200376 TEST_ASSERT( status == PSA_SUCCESS ||
377 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200378 else
379 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200380 }
381
382 return( 1 );
383
384exit:
385 psa_cipher_abort( &operation );
386 return( 0 );
387}
388
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100389static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200390 psa_key_usage_t usage,
391 psa_algorithm_t alg )
392{
393 unsigned char nonce[16] = {0};
394 size_t nonce_length = sizeof( nonce );
395 unsigned char plaintext[16] = "Hello, world...";
396 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
397 size_t ciphertext_length = sizeof( ciphertext );
398 size_t plaintext_length = sizeof( ciphertext );
399
400 if( usage & PSA_KEY_USAGE_ENCRYPT )
401 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100402 PSA_ASSERT( psa_aead_encrypt( handle, alg,
403 nonce, nonce_length,
404 NULL, 0,
405 plaintext, sizeof( plaintext ),
406 ciphertext, sizeof( ciphertext ),
407 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200408 }
409
410 if( usage & PSA_KEY_USAGE_DECRYPT )
411 {
412 psa_status_t verify_status =
413 ( usage & PSA_KEY_USAGE_ENCRYPT ?
414 PSA_SUCCESS :
415 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100416 TEST_EQUAL( psa_aead_decrypt( handle, alg,
417 nonce, nonce_length,
418 NULL, 0,
419 ciphertext, ciphertext_length,
420 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100421 &plaintext_length ),
422 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200423 }
424
425 return( 1 );
426
427exit:
428 return( 0 );
429}
430
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100431static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200432 psa_key_usage_t usage,
433 psa_algorithm_t alg )
434{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200435 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
436 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200437 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200438 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100439 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
440
441 /* If the policy allows signing with any hash, just pick one. */
442 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
443 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100444#if defined(KNOWN_SUPPORTED_HASH_ALG)
445 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
446 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100447#else
448 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100449 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100450#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100451 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200452
453 if( usage & PSA_KEY_USAGE_SIGN )
454 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200455 /* Some algorithms require the payload to have the size of
456 * the hash encoded in the algorithm. Use this input size
457 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200458 if( hash_alg != 0 )
459 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100460 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
461 payload, payload_length,
462 signature, sizeof( signature ),
463 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200464 }
465
466 if( usage & PSA_KEY_USAGE_VERIFY )
467 {
468 psa_status_t verify_status =
469 ( usage & PSA_KEY_USAGE_SIGN ?
470 PSA_SUCCESS :
471 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100472 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
473 payload, payload_length,
474 signature, signature_length ),
475 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200476 }
477
478 return( 1 );
479
480exit:
481 return( 0 );
482}
483
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100484static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200485 psa_key_usage_t usage,
486 psa_algorithm_t alg )
487{
488 unsigned char plaintext[256] = "Hello, world...";
489 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
490 size_t ciphertext_length = sizeof( ciphertext );
491 size_t plaintext_length = 16;
492
493 if( usage & PSA_KEY_USAGE_ENCRYPT )
494 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100495 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
496 plaintext, plaintext_length,
497 NULL, 0,
498 ciphertext, sizeof( ciphertext ),
499 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200500 }
501
502 if( usage & PSA_KEY_USAGE_DECRYPT )
503 {
504 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100505 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200506 ciphertext, ciphertext_length,
507 NULL, 0,
508 plaintext, sizeof( plaintext ),
509 &plaintext_length );
510 TEST_ASSERT( status == PSA_SUCCESS ||
511 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
512 ( status == PSA_ERROR_INVALID_ARGUMENT ||
513 status == PSA_ERROR_INVALID_PADDING ) ) );
514 }
515
516 return( 1 );
517
518exit:
519 return( 0 );
520}
Gilles Peskine02b75072018-07-01 22:31:34 +0200521
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100522static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200523 psa_key_usage_t usage,
524 psa_algorithm_t alg )
525{
526 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
527 unsigned char label[16] = "This is a label.";
528 size_t label_length = sizeof( label );
529 unsigned char seed[16] = "abcdefghijklmnop";
530 size_t seed_length = sizeof( seed );
531 unsigned char output[1];
532
533 if( usage & PSA_KEY_USAGE_DERIVE )
534 {
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100535 if( PSA_ALG_IS_HKDF( alg ) )
536 {
537 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
538 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
539 PSA_KDF_STEP_SALT,
540 label,
541 label_length ) );
542 PSA_ASSERT( psa_key_derivation_input_key( &generator,
543 PSA_KDF_STEP_SECRET,
544 handle ) );
545 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
546 PSA_KDF_STEP_INFO,
547 seed,
548 seed_length ) );
549 }
550 else
551 {
552 // legacy
553 PSA_ASSERT( psa_key_derivation( &generator,
554 handle, alg,
555 label, label_length,
556 seed, seed_length,
557 sizeof( output ) ) );
558 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100559 PSA_ASSERT( psa_generator_read( &generator,
560 output,
561 sizeof( output ) ) );
562 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200563 }
564
565 return( 1 );
566
567exit:
568 return( 0 );
569}
570
Gilles Peskinec7998b72018-11-07 18:45:02 +0100571/* We need two keys to exercise key agreement. Exercise the
572 * private key against its own public key. */
573static psa_status_t key_agreement_with_self( psa_crypto_generator_t *generator,
Gilles Peskine969c5d62019-01-16 15:53:06 +0100574 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100575{
576 psa_key_type_t private_key_type;
577 psa_key_type_t public_key_type;
578 size_t key_bits;
579 uint8_t *public_key = NULL;
580 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200581 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinec7998b72018-11-07 18:45:02 +0100582 * psa_key_agreement fails. This isn't fully satisfactory, but it's
583 * good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200584 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200585 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100586
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200587 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
588 private_key_type = psa_get_key_type( &attributes );
589 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100590 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
591 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
592 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100593 PSA_ASSERT( psa_export_public_key( handle,
594 public_key, public_key_length,
595 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100596
Gilles Peskine969c5d62019-01-16 15:53:06 +0100597 status = psa_key_agreement( generator, PSA_KDF_STEP_SECRET, handle,
598 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100599exit:
600 mbedtls_free( public_key );
601 return( status );
602}
603
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200604/* We need two keys to exercise key agreement. Exercise the
605 * private key against its own public key. */
606static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
607 psa_key_handle_t handle )
608{
609 psa_key_type_t private_key_type;
610 psa_key_type_t public_key_type;
611 size_t key_bits;
612 uint8_t *public_key = NULL;
613 size_t public_key_length;
614 uint8_t output[1024];
615 size_t output_length;
616 /* Return GENERIC_ERROR if something other than the final call to
617 * psa_key_agreement fails. This isn't fully satisfactory, but it's
618 * good enough: callers will report it as a failed test anyway. */
619 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200620 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200621
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200622 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
623 private_key_type = psa_get_key_type( &attributes );
624 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200625 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
626 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
627 ASSERT_ALLOC( public_key, public_key_length );
628 PSA_ASSERT( psa_export_public_key( handle,
629 public_key, public_key_length,
630 &public_key_length ) );
631
632 status = psa_key_agreement_raw_shared_secret(
633 alg, handle,
634 public_key, public_key_length,
635 output, sizeof( output ), &output_length );
636exit:
637 mbedtls_free( public_key );
638 return( status );
639}
640
641static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
642 psa_key_usage_t usage,
643 psa_algorithm_t alg )
644{
645 int ok = 0;
646
647 if( usage & PSA_KEY_USAGE_DERIVE )
648 {
649 /* We need two keys to exercise key agreement. Exercise the
650 * private key against its own public key. */
651 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
652 }
653 ok = 1;
654
655exit:
656 return( ok );
657}
658
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100659static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200660 psa_key_usage_t usage,
661 psa_algorithm_t alg )
662{
663 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200664 unsigned char output[1];
665 int ok = 0;
666
667 if( usage & PSA_KEY_USAGE_DERIVE )
668 {
669 /* We need two keys to exercise key agreement. Exercise the
670 * private key against its own public key. */
Gilles Peskine969c5d62019-01-16 15:53:06 +0100671 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
672 PSA_ASSERT( key_agreement_with_self( &generator, handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +0100673 PSA_ASSERT( psa_generator_read( &generator,
674 output,
675 sizeof( output ) ) );
676 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200677 }
678 ok = 1;
679
680exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200681 return( ok );
682}
683
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200684static int is_oid_of_key_type( psa_key_type_t type,
685 const uint8_t *oid, size_t oid_length )
686{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200687 const uint8_t *expected_oid = NULL;
688 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200689#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200690 if( PSA_KEY_TYPE_IS_RSA( type ) )
691 {
692 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
693 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
694 }
695 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200696#endif /* MBEDTLS_RSA_C */
697#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200698 if( PSA_KEY_TYPE_IS_ECC( type ) )
699 {
700 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
701 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
702 }
703 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200704#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200705 {
706 char message[40];
707 mbedtls_snprintf( message, sizeof( message ),
708 "OID not known for key type=0x%08lx",
709 (unsigned long) type );
710 test_fail( message, __LINE__, __FILE__ );
711 return( 0 );
712 }
713
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200714 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200715 return( 1 );
716
717exit:
718 return( 0 );
719}
720
721static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
722 size_t min_bits, size_t max_bits,
723 int must_be_odd )
724{
725 size_t len;
726 size_t actual_bits;
727 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100728 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100729 MBEDTLS_ASN1_INTEGER ),
730 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200731 /* Tolerate a slight departure from DER encoding:
732 * - 0 may be represented by an empty string or a 1-byte string.
733 * - The sign bit may be used as a value bit. */
734 if( ( len == 1 && ( *p )[0] == 0 ) ||
735 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
736 {
737 ++( *p );
738 --len;
739 }
740 if( min_bits == 0 && len == 0 )
741 return( 1 );
742 msb = ( *p )[0];
743 TEST_ASSERT( msb != 0 );
744 actual_bits = 8 * ( len - 1 );
745 while( msb != 0 )
746 {
747 msb >>= 1;
748 ++actual_bits;
749 }
750 TEST_ASSERT( actual_bits >= min_bits );
751 TEST_ASSERT( actual_bits <= max_bits );
752 if( must_be_odd )
753 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
754 *p += len;
755 return( 1 );
756exit:
757 return( 0 );
758}
759
760static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
761 size_t *len,
762 unsigned char n, unsigned char tag )
763{
764 int ret;
765 ret = mbedtls_asn1_get_tag( p, end, len,
766 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
767 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
768 if( ret != 0 )
769 return( ret );
770 end = *p + *len;
771 ret = mbedtls_asn1_get_tag( p, end, len, tag );
772 if( ret != 0 )
773 return( ret );
774 if( *p + *len != end )
775 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
776 return( 0 );
777}
778
779static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
780 uint8_t *exported, size_t exported_length )
781{
782 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100783 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200784 else
785 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200786
787#if defined(MBEDTLS_DES_C)
788 if( type == PSA_KEY_TYPE_DES )
789 {
790 /* Check the parity bits. */
791 unsigned i;
792 for( i = 0; i < bits / 8; i++ )
793 {
794 unsigned bit_count = 0;
795 unsigned m;
796 for( m = 1; m <= 0x100; m <<= 1 )
797 {
798 if( exported[i] & m )
799 ++bit_count;
800 }
801 TEST_ASSERT( bit_count % 2 != 0 );
802 }
803 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200804 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200805#endif
806
807#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
808 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
809 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200810 uint8_t *p = exported;
811 uint8_t *end = exported + exported_length;
812 size_t len;
813 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200814 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200815 * modulus INTEGER, -- n
816 * publicExponent INTEGER, -- e
817 * privateExponent INTEGER, -- d
818 * prime1 INTEGER, -- p
819 * prime2 INTEGER, -- q
820 * exponent1 INTEGER, -- d mod (p-1)
821 * exponent2 INTEGER, -- d mod (q-1)
822 * coefficient INTEGER, -- (inverse of q) mod p
823 * }
824 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100825 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
826 MBEDTLS_ASN1_SEQUENCE |
827 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
828 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200829 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
830 goto exit;
831 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
832 goto exit;
833 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
834 goto exit;
835 /* Require d to be at least half the size of n. */
836 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
837 goto exit;
838 /* Require p and q to be at most half the size of n, rounded up. */
839 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
840 goto exit;
841 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
842 goto exit;
843 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
844 goto exit;
845 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
846 goto exit;
847 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
848 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100849 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100850 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200851 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200852#endif /* MBEDTLS_RSA_C */
853
854#if defined(MBEDTLS_ECP_C)
855 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
856 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100857 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100858 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100859 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200860 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200861#endif /* MBEDTLS_ECP_C */
862
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200863 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
864 {
865 uint8_t *p = exported;
866 uint8_t *end = exported + exported_length;
867 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200868#if defined(MBEDTLS_RSA_C)
869 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
870 {
871 /* RSAPublicKey ::= SEQUENCE {
872 * modulus INTEGER, -- n
873 * publicExponent INTEGER } -- e
874 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100875 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
876 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100877 MBEDTLS_ASN1_CONSTRUCTED ),
878 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100879 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200880 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
881 goto exit;
882 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
883 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100884 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200885 }
886 else
887#endif /* MBEDTLS_RSA_C */
888#if defined(MBEDTLS_ECP_C)
889 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
890 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000891 /* The representation of an ECC public key is:
892 * - The byte 0x04;
893 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
894 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
895 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000896 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100897 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
898 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200899 }
900 else
901#endif /* MBEDTLS_ECP_C */
902 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100903 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200904 mbedtls_snprintf( message, sizeof( message ),
905 "No sanity check for public key type=0x%08lx",
906 (unsigned long) type );
907 test_fail( message, __LINE__, __FILE__ );
908 return( 0 );
909 }
910 }
911 else
912
913 {
914 /* No sanity checks for other types */
915 }
916
917 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200918
919exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200920 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200921}
922
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100923static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200924 psa_key_usage_t usage )
925{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200926 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200927 uint8_t *exported = NULL;
928 size_t exported_size = 0;
929 size_t exported_length = 0;
930 int ok = 0;
931
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200932 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200933
934 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200935 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200936 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100937 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
938 PSA_ERROR_NOT_PERMITTED );
Gilles Peskined14664a2018-08-10 19:07:32 +0200939 return( 1 );
940 }
941
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200942 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
943 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200944 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200945
Gilles Peskine8817f612018-12-18 00:18:46 +0100946 PSA_ASSERT( psa_export_key( handle,
947 exported, exported_size,
948 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200949 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
950 psa_get_key_bits( &attributes ),
951 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200952
953exit:
954 mbedtls_free( exported );
955 return( ok );
956}
957
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100958static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200959{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200960 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200961 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200962 uint8_t *exported = NULL;
963 size_t exported_size = 0;
964 size_t exported_length = 0;
965 int ok = 0;
966
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
968 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200969 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100970 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100971 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200972 return( 1 );
973 }
974
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200975 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
976 psa_get_key_type( &attributes ) );
977 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
978 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200979 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200980
Gilles Peskine8817f612018-12-18 00:18:46 +0100981 PSA_ASSERT( psa_export_public_key( handle,
982 exported, exported_size,
983 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200984 ok = exported_key_sanity_check( public_type,
985 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200986 exported, exported_length );
987
988exit:
989 mbedtls_free( exported );
990 return( ok );
991}
992
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100993/** Do smoke tests on a key.
994 *
995 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
996 * sign/verify, or derivation) that is permitted according to \p usage.
997 * \p usage and \p alg should correspond to the expected policy on the
998 * key.
999 *
1000 * Export the key if permitted by \p usage, and check that the output
1001 * looks sensible. If \p usage forbids export, check that
1002 * \p psa_export_key correctly rejects the attempt. If the key is
1003 * asymmetric, also check \p psa_export_public_key.
1004 *
1005 * If the key fails the tests, this function calls the test framework's
1006 * `test_fail` function and returns false. Otherwise this function returns
1007 * true. Therefore it should be used as follows:
1008 * ```
1009 * if( ! exercise_key( ... ) ) goto exit;
1010 * ```
1011 *
1012 * \param handle The key to exercise. It should be capable of performing
1013 * \p alg.
1014 * \param usage The usage flags to assume.
1015 * \param alg The algorithm to exercise.
1016 *
1017 * \retval 0 The key failed the smoke tests.
1018 * \retval 1 The key passed the smoke tests.
1019 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001020static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001021 psa_key_usage_t usage,
1022 psa_algorithm_t alg )
1023{
1024 int ok;
1025 if( alg == 0 )
1026 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1027 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001029 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001030 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001031 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001032 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001033 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001034 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001035 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001036 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001037 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001038 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001039 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1040 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001041 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001042 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001043 else
1044 {
1045 char message[40];
1046 mbedtls_snprintf( message, sizeof( message ),
1047 "No code to exercise alg=0x%08lx",
1048 (unsigned long) alg );
1049 test_fail( message, __LINE__, __FILE__ );
1050 ok = 0;
1051 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001052
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001053 ok = ok && exercise_export_key( handle, usage );
1054 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001055
Gilles Peskine02b75072018-07-01 22:31:34 +02001056 return( ok );
1057}
1058
Gilles Peskine10df3412018-10-25 22:35:43 +02001059static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1060 psa_algorithm_t alg )
1061{
1062 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1063 {
1064 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1065 PSA_KEY_USAGE_VERIFY :
1066 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1067 }
1068 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1069 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1070 {
1071 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1072 PSA_KEY_USAGE_ENCRYPT :
1073 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1074 }
1075 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1076 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1077 {
1078 return( PSA_KEY_USAGE_DERIVE );
1079 }
1080 else
1081 {
1082 return( 0 );
1083 }
1084
1085}
Darryl Green0c6575a2018-11-07 16:05:30 +00001086
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001087/* An overapproximation of the amount of storage needed for a key of the
1088 * given type and with the given content. The API doesn't make it easy
1089 * to find a good value for the size. The current implementation doesn't
1090 * care about the value anyway. */
1091#define KEY_BITS_FROM_DATA( type, data ) \
1092 ( data )->len
1093
Darryl Green0c6575a2018-11-07 16:05:30 +00001094typedef enum {
1095 IMPORT_KEY = 0,
1096 GENERATE_KEY = 1,
1097 DERIVE_KEY = 2
1098} generate_method;
1099
Gilles Peskinee59236f2018-01-27 23:32:46 +01001100/* END_HEADER */
1101
1102/* BEGIN_DEPENDENCIES
1103 * depends_on:MBEDTLS_PSA_CRYPTO_C
1104 * END_DEPENDENCIES
1105 */
1106
1107/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001108void static_checks( )
1109{
1110 size_t max_truncated_mac_size =
1111 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1112
1113 /* Check that the length for a truncated MAC always fits in the algorithm
1114 * encoding. The shifted mask is the maximum truncated value. The
1115 * untruncated algorithm may be one byte larger. */
1116 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1117}
1118/* END_CASE */
1119
1120/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001121void attributes_set_get( int id_arg, int lifetime_arg,
1122 int usage_flags_arg, int alg_arg,
1123 int type_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001124{
Gilles Peskine4747d192019-04-17 15:05:45 +02001125 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001126 psa_key_id_t id = id_arg;
1127 psa_key_lifetime_t lifetime = lifetime_arg;
1128 psa_key_usage_t usage_flags = usage_flags_arg;
1129 psa_algorithm_t alg = alg_arg;
1130 psa_key_type_t type = type_arg;
1131
1132 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1133 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1134 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1135 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1136 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1137
1138 psa_make_key_persistent( &attributes, id, lifetime );
1139 psa_set_key_usage_flags( &attributes, usage_flags );
1140 psa_set_key_algorithm( &attributes, alg );
1141 psa_set_key_type( &attributes, type );
1142
1143 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1144 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1145 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1146 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1147 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1148
1149 psa_reset_key_attributes( &attributes );
1150
1151 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1152 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1153 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1154 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1155 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1156}
1157/* END_CASE */
1158
1159/* BEGIN_CASE */
1160void import( data_t *data, int type_arg, int expected_status_arg )
1161{
1162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1163 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001164 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001165 psa_key_type_t type = type_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001166 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001167 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001168
Gilles Peskine8817f612018-12-18 00:18:46 +01001169 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001170
Gilles Peskine4747d192019-04-17 15:05:45 +02001171 psa_set_key_type( &attributes, type );
1172 status = psa_import_key( &attributes, &handle, data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001173 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001174 if( status != PSA_SUCCESS )
1175 goto exit;
1176
1177 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1178 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1179
1180 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001181
1182exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001183 psa_destroy_key( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001184 mbedtls_psa_crypto_free( );
1185}
1186/* END_CASE */
1187
1188/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001189void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1190{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001191 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001192 size_t bits = bits_arg;
1193 psa_status_t expected_status = expected_status_arg;
1194 psa_status_t status;
1195 psa_key_type_t type =
1196 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1197 size_t buffer_size = /* Slight overapproximations */
1198 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001199 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001200 unsigned char *p;
1201 int ret;
1202 size_t length;
1203
Gilles Peskine8817f612018-12-18 00:18:46 +01001204 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001205 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001206
1207 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1208 bits, keypair ) ) >= 0 );
1209 length = ret;
1210
1211 /* Try importing the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001212 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02001213 status = psa_import_key_to_handle( handle, type, p, length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001214 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001215 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001216 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001217
1218exit:
1219 mbedtls_free( buffer );
1220 mbedtls_psa_crypto_free( );
1221}
1222/* END_CASE */
1223
1224/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001225void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001226 int type_arg,
1227 int alg_arg,
1228 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001229 int expected_bits,
1230 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001231 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001232 int canonical_input )
1233{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001234 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001235 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001236 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001237 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001238 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001239 unsigned char *exported = NULL;
1240 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001241 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001242 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001243 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001244 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001245 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001246
Moran Pekercb088e72018-07-17 17:36:59 +03001247 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001248 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001249 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001250 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001251 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001252
Gilles Peskine4747d192019-04-17 15:05:45 +02001253 psa_set_key_usage_flags( &attributes, usage_arg );
1254 psa_set_key_algorithm( &attributes, alg );
1255 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001256
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001257 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001258 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001259
1260 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001261 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1262 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1263 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001264
1265 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001266 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001267 exported, export_size,
1268 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001269 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001270
1271 /* The exported length must be set by psa_export_key() to a value between 0
1272 * and export_size. On errors, the exported length must be 0. */
1273 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1274 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1275 TEST_ASSERT( exported_length <= export_size );
1276
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001277 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001278 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001279 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001280 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001281 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001282 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001283 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001284
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001285 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001286 goto exit;
1287
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001288 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001289 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001290 else
1291 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001292 psa_key_handle_t handle2;
Gilles Peskine4747d192019-04-17 15:05:45 +02001293 PSA_ASSERT( psa_import_key( &attributes, &handle2,
1294 exported, exported_length ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001295 PSA_ASSERT( psa_export_key( handle2,
1296 reexported,
1297 export_size,
1298 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001299 ASSERT_COMPARE( exported, exported_length,
1300 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001301 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001302 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001303 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001304
1305destroy:
1306 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001307 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01001308 TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
1309 PSA_ERROR_INVALID_HANDLE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001310
1311exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001312 mbedtls_free( exported );
1313 mbedtls_free( reexported );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001314 mbedtls_psa_crypto_free( );
1315}
1316/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001317
Moran Pekerf709f4a2018-06-06 17:26:04 +03001318/* BEGIN_CASE */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001319void export_invalid_handle( int handle, int expected_export_status_arg )
Moran Peker28a38e62018-11-07 16:18:24 +02001320{
1321 psa_status_t status;
1322 unsigned char *exported = NULL;
1323 size_t export_size = 0;
1324 size_t exported_length = INVALID_EXPORT_LENGTH;
1325 psa_status_t expected_export_status = expected_export_status_arg;
1326
Gilles Peskine8817f612018-12-18 00:18:46 +01001327 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker28a38e62018-11-07 16:18:24 +02001328
1329 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001330 status = psa_export_key( (psa_key_handle_t) handle,
Moran Peker28a38e62018-11-07 16:18:24 +02001331 exported, export_size,
1332 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001333 TEST_EQUAL( status, expected_export_status );
Moran Peker28a38e62018-11-07 16:18:24 +02001334
1335exit:
1336 mbedtls_psa_crypto_free( );
1337}
1338/* END_CASE */
1339
1340/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001341void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001342 int type_arg,
1343 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001344 int export_size_delta,
1345 int expected_export_status_arg,
1346 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001347{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001348 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001349 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001350 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001351 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001352 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001353 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001354 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001355 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001356 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001357
Gilles Peskine8817f612018-12-18 00:18:46 +01001358 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001359
Gilles Peskine4747d192019-04-17 15:05:45 +02001360 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1361 psa_set_key_algorithm( &attributes, alg );
1362 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001363
1364 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001365 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001366
Gilles Peskine49c25912018-10-29 15:15:31 +01001367 /* Export the public key */
1368 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001369 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001370 exported, export_size,
1371 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001372 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001373 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001374 {
1375 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1376 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001377 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1378 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001379 TEST_ASSERT( expected_public_key->len <=
1380 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001381 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1382 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001383 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001384
1385exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001386 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001387 psa_destroy_key( handle );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001388 mbedtls_psa_crypto_free( );
1389}
1390/* END_CASE */
1391
Gilles Peskine20035e32018-02-03 22:44:14 +01001392/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001393void import_and_exercise_key( data_t *data,
1394 int type_arg,
1395 int bits_arg,
1396 int alg_arg )
1397{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001398 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001399 psa_key_type_t type = type_arg;
1400 size_t bits = bits_arg;
1401 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001402 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001403 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001404 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001405
Gilles Peskine8817f612018-12-18 00:18:46 +01001406 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001407
Gilles Peskine4747d192019-04-17 15:05:45 +02001408 psa_set_key_usage_flags( &attributes, usage );
1409 psa_set_key_algorithm( &attributes, alg );
1410 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001411
1412 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001413 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001414
1415 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001416 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1417 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1418 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001419
1420 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001421 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001422 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001423
1424exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001425 psa_destroy_key( handle );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001426 mbedtls_psa_crypto_free( );
1427}
1428/* END_CASE */
1429
1430/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001431void key_policy( int usage_arg, int alg_arg )
1432{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001433 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001434 psa_algorithm_t alg = alg_arg;
1435 psa_key_usage_t usage = usage_arg;
1436 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1437 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001438 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001439
1440 memset( key, 0x2a, sizeof( key ) );
1441
Gilles Peskine8817f612018-12-18 00:18:46 +01001442 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001443
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001444 psa_set_key_usage_flags( &attributes, usage );
1445 psa_set_key_algorithm( &attributes, alg );
1446 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001447
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001448 PSA_ASSERT( psa_import_key( &attributes, &handle, key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001449
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001450 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1451 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1452 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1453 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001454
1455exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001456 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001457 mbedtls_psa_crypto_free( );
1458}
1459/* END_CASE */
1460
1461/* BEGIN_CASE */
Jaeden Amero70261c52019-01-04 11:47:20 +00001462void key_policy_init( )
1463{
1464 /* Test each valid way of initializing the object, except for `= {0}`, as
1465 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1466 * though it's OK by the C standard. We could test for this, but we'd need
1467 * to supress the Clang warning for the test. */
1468 psa_key_policy_t func = psa_key_policy_init( );
1469 psa_key_policy_t init = PSA_KEY_POLICY_INIT;
1470 psa_key_policy_t zero;
1471
1472 memset( &zero, 0, sizeof( zero ) );
1473
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001474 /* A default key policy should not permit any usage. */
1475 TEST_EQUAL( psa_key_policy_get_usage( &func ), 0 );
1476 TEST_EQUAL( psa_key_policy_get_usage( &init ), 0 );
1477 TEST_EQUAL( psa_key_policy_get_usage( &zero ), 0 );
1478
1479 /* A default key policy should not permit any algorithm. */
1480 TEST_EQUAL( psa_key_policy_get_algorithm( &func ), 0 );
1481 TEST_EQUAL( psa_key_policy_get_algorithm( &init ), 0 );
1482 TEST_EQUAL( psa_key_policy_get_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001483}
1484/* END_CASE */
1485
1486/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001487void mac_key_policy( int policy_usage,
1488 int policy_alg,
1489 int key_type,
1490 data_t *key_data,
1491 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001492{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001493 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001494 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001495 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001496 psa_status_t status;
1497 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001498
Gilles Peskine8817f612018-12-18 00:18:46 +01001499 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001500
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001501 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001502 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001503 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001504
Gilles Peskine87a5e562019-04-17 12:28:25 +02001505 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001506 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001507
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001508 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001509 if( policy_alg == exercise_alg &&
1510 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001511 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001512 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001513 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001514 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001515
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001516 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001517 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001518 if( policy_alg == exercise_alg &&
1519 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001520 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001521 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001522 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001523
1524exit:
1525 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001526 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001527 mbedtls_psa_crypto_free( );
1528}
1529/* END_CASE */
1530
1531/* BEGIN_CASE */
1532void cipher_key_policy( int policy_usage,
1533 int policy_alg,
1534 int key_type,
1535 data_t *key_data,
1536 int exercise_alg )
1537{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001538 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001539 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001540 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001541 psa_status_t status;
1542
Gilles Peskine8817f612018-12-18 00:18:46 +01001543 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001544
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001545 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001546 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001547 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001548
Gilles Peskine87a5e562019-04-17 12:28:25 +02001549 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001550 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001551
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001552 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001553 if( policy_alg == exercise_alg &&
1554 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001555 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001556 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001557 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001558 psa_cipher_abort( &operation );
1559
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001560 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001561 if( policy_alg == exercise_alg &&
1562 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001563 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001564 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001565 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001566
1567exit:
1568 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001569 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001570 mbedtls_psa_crypto_free( );
1571}
1572/* END_CASE */
1573
1574/* BEGIN_CASE */
1575void aead_key_policy( int policy_usage,
1576 int policy_alg,
1577 int key_type,
1578 data_t *key_data,
1579 int nonce_length_arg,
1580 int tag_length_arg,
1581 int exercise_alg )
1582{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001583 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001584 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001585 psa_status_t status;
1586 unsigned char nonce[16] = {0};
1587 size_t nonce_length = nonce_length_arg;
1588 unsigned char tag[16];
1589 size_t tag_length = tag_length_arg;
1590 size_t output_length;
1591
1592 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1593 TEST_ASSERT( tag_length <= sizeof( tag ) );
1594
Gilles Peskine8817f612018-12-18 00:18:46 +01001595 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001596
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001597 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001598 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001599 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001600
Gilles Peskine87a5e562019-04-17 12:28:25 +02001601 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001602 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001603
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001604 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001605 nonce, nonce_length,
1606 NULL, 0,
1607 NULL, 0,
1608 tag, tag_length,
1609 &output_length );
1610 if( policy_alg == exercise_alg &&
1611 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001612 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001613 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001614 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001615
1616 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001617 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001618 nonce, nonce_length,
1619 NULL, 0,
1620 tag, tag_length,
1621 NULL, 0,
1622 &output_length );
1623 if( policy_alg == exercise_alg &&
1624 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001625 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001626 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001627 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001628
1629exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001630 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001631 mbedtls_psa_crypto_free( );
1632}
1633/* END_CASE */
1634
1635/* BEGIN_CASE */
1636void asymmetric_encryption_key_policy( int policy_usage,
1637 int policy_alg,
1638 int key_type,
1639 data_t *key_data,
1640 int exercise_alg )
1641{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001642 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001643 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001644 psa_status_t status;
1645 size_t key_bits;
1646 size_t buffer_length;
1647 unsigned char *buffer = NULL;
1648 size_t output_length;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001649 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001650
Gilles Peskine8817f612018-12-18 00:18:46 +01001651 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001652
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001653 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001655 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001656
Gilles Peskine87a5e562019-04-17 12:28:25 +02001657 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001658 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001659
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001660 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1661 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001662 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1663 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001664 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001665
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001666 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001667 NULL, 0,
1668 NULL, 0,
1669 buffer, buffer_length,
1670 &output_length );
1671 if( policy_alg == exercise_alg &&
1672 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001673 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001674 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001675 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001676
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001677 if( buffer_length != 0 )
1678 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001679 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001680 buffer, buffer_length,
1681 NULL, 0,
1682 buffer, buffer_length,
1683 &output_length );
1684 if( policy_alg == exercise_alg &&
1685 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001686 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001687 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001688 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001689
1690exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001691 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692 mbedtls_psa_crypto_free( );
1693 mbedtls_free( buffer );
1694}
1695/* END_CASE */
1696
1697/* BEGIN_CASE */
1698void asymmetric_signature_key_policy( int policy_usage,
1699 int policy_alg,
1700 int key_type,
1701 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001702 int exercise_alg,
1703 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001704{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001705 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001706 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001707 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001708 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1709 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1710 * compatible with the policy and `payload_length_arg` is supposed to be
1711 * a valid input length to sign. If `payload_length_arg <= 0`,
1712 * `exercise_alg` is supposed to be forbidden by the policy. */
1713 int compatible_alg = payload_length_arg > 0;
1714 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001715 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1716 size_t signature_length;
1717
Gilles Peskine8817f612018-12-18 00:18:46 +01001718 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001719
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001720 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001721 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001722 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001723
Gilles Peskine87a5e562019-04-17 12:28:25 +02001724 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001725 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001726
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001727 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001728 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001729 signature, sizeof( signature ),
1730 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001731 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001732 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001733 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001734 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001735
1736 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001737 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001738 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001739 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001740 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001741 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001742 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001743 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001744
1745exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001746 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001747 mbedtls_psa_crypto_free( );
1748}
1749/* END_CASE */
1750
1751/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001752void derive_key_policy( int policy_usage,
1753 int policy_alg,
1754 int key_type,
1755 data_t *key_data,
1756 int exercise_alg )
1757{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001758 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001759 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001760 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1761 psa_status_t status;
1762
Gilles Peskine8817f612018-12-18 00:18:46 +01001763 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001764
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001765 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001766 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001767 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001768
Gilles Peskine87a5e562019-04-17 12:28:25 +02001769 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001770 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001771
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001772 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001773 exercise_alg,
1774 NULL, 0,
1775 NULL, 0,
1776 1 );
1777 if( policy_alg == exercise_alg &&
1778 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001779 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001780 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001781 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001782
1783exit:
1784 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001785 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001786 mbedtls_psa_crypto_free( );
1787}
1788/* END_CASE */
1789
1790/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001791void agreement_key_policy( int policy_usage,
1792 int policy_alg,
1793 int key_type_arg,
1794 data_t *key_data,
1795 int exercise_alg )
1796{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001797 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001798 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001799 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001800 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1801 psa_status_t status;
1802
Gilles Peskine8817f612018-12-18 00:18:46 +01001803 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001804
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001805 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001806 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001807 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001808
Gilles Peskine87a5e562019-04-17 12:28:25 +02001809 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001810 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001811
Gilles Peskine969c5d62019-01-16 15:53:06 +01001812 PSA_ASSERT( psa_key_derivation_setup( &generator, exercise_alg ) );
1813 status = key_agreement_with_self( &generator, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001814
Gilles Peskine01d718c2018-09-18 12:01:02 +02001815 if( policy_alg == exercise_alg &&
1816 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001817 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001818 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001819 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001820
1821exit:
1822 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001823 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001824 mbedtls_psa_crypto_free( );
1825}
1826/* END_CASE */
1827
1828/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001829void raw_agreement_key_policy( int policy_usage,
1830 int policy_alg,
1831 int key_type_arg,
1832 data_t *key_data,
1833 int exercise_alg )
1834{
1835 psa_key_handle_t handle = 0;
1836 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
1837 psa_key_type_t key_type = key_type_arg;
1838 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1839 psa_status_t status;
1840
1841 PSA_ASSERT( psa_crypto_init( ) );
1842
1843 PSA_ASSERT( psa_allocate_key( &handle ) );
1844 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
1845 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
1846
Gilles Peskine87a5e562019-04-17 12:28:25 +02001847 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001848 key_data->x, key_data->len ) );
1849
1850 status = raw_key_agreement_with_self( exercise_alg, handle );
1851
1852 if( policy_alg == exercise_alg &&
1853 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1854 PSA_ASSERT( status );
1855 else
1856 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1857
1858exit:
1859 psa_generator_abort( &generator );
1860 psa_destroy_key( handle );
1861 mbedtls_psa_crypto_free( );
1862}
1863/* END_CASE */
1864
1865/* BEGIN_CASE */
Gilles Peskine57ab7212019-01-28 13:03:09 +01001866void copy_key_policy( int source_usage_arg, int source_alg_arg,
1867 int type_arg, data_t *material,
1868 int target_usage_arg, int target_alg_arg,
1869 int constraint_usage_arg, int constraint_alg_arg,
1870 int expected_usage_arg, int expected_alg_arg )
1871{
1872 psa_key_usage_t source_usage = source_usage_arg;
1873 psa_algorithm_t source_alg = source_alg_arg;
1874 psa_key_handle_t source_handle = 0;
1875 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
1876 psa_key_type_t source_type = type_arg;
1877 size_t source_bits;
1878 psa_key_usage_t target_usage = target_usage_arg;
1879 psa_algorithm_t target_alg = target_alg_arg;
1880 psa_key_handle_t target_handle = 0;
1881 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
1882 psa_key_type_t target_type;
1883 size_t target_bits;
1884 psa_key_usage_t constraint_usage = constraint_usage_arg;
1885 psa_algorithm_t constraint_alg = constraint_alg_arg;
1886 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
1887 psa_key_policy_t *p_constraint = NULL;
1888 psa_key_usage_t expected_usage = expected_usage_arg;
1889 psa_algorithm_t expected_alg = expected_alg_arg;
1890 uint8_t *export_buffer = NULL;
1891
1892 if( constraint_usage_arg != -1 )
1893 {
1894 p_constraint = &constraint;
1895 psa_key_policy_set_usage( p_constraint,
1896 constraint_usage, constraint_alg );
1897 }
1898
1899 PSA_ASSERT( psa_crypto_init( ) );
1900
1901 /* Populate the source slot. */
1902 PSA_ASSERT( psa_allocate_key( &source_handle ) );
1903 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
1904 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02001905 PSA_ASSERT( psa_import_key_to_handle( source_handle, source_type,
Gilles Peskine57ab7212019-01-28 13:03:09 +01001906 material->x, material->len ) );
1907 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
1908
1909 /* Prepare the target slot. */
1910 PSA_ASSERT( psa_allocate_key( &target_handle ) );
1911 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
1912 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
1913 target_policy = psa_key_policy_init();
1914
1915 /* Copy the key. */
Gilles Peskine87a5e562019-04-17 12:28:25 +02001916 PSA_ASSERT( psa_copy_key_to_handle( source_handle, target_handle, p_constraint ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001917
1918 /* Destroy the source to ensure that this doesn't affect the target. */
1919 PSA_ASSERT( psa_destroy_key( source_handle ) );
1920
1921 /* Test that the target slot has the expected content and policy. */
1922 PSA_ASSERT( psa_get_key_information( target_handle,
1923 &target_type, &target_bits ) );
1924 TEST_EQUAL( source_type, target_type );
1925 TEST_EQUAL( source_bits, target_bits );
1926 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
1927 TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
1928 TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
1929 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1930 {
1931 size_t length;
1932 ASSERT_ALLOC( export_buffer, material->len );
1933 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1934 material->len, &length ) );
1935 ASSERT_COMPARE( material->x, material->len,
1936 export_buffer, length );
1937 }
1938 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1939 goto exit;
1940
1941 PSA_ASSERT( psa_close_key( target_handle ) );
1942
1943exit:
1944 mbedtls_psa_crypto_free( );
1945 mbedtls_free( export_buffer );
1946}
1947/* END_CASE */
1948
1949/* BEGIN_CASE */
1950void copy_fail( int source_usage_arg, int source_alg_arg,
1951 int type_arg, data_t *material,
1952 int target_usage_arg, int target_alg_arg,
1953 int constraint_usage_arg, int constraint_alg_arg,
1954 int expected_status_arg )
1955{
1956 /* Test copy failure into an empty slot. There is a test for copy failure
1957 * into an occupied slot in
1958 * test_suite_psa_crypto_slot_management.function. */
1959
1960 psa_key_usage_t source_usage = source_usage_arg;
1961 psa_algorithm_t source_alg = source_alg_arg;
1962 psa_key_handle_t source_handle = 0;
1963 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
1964 psa_key_type_t source_type = type_arg;
1965 size_t source_bits;
1966 psa_key_usage_t target_usage = target_usage_arg;
1967 psa_algorithm_t target_alg = target_alg_arg;
1968 psa_key_handle_t target_handle = 0;
1969 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
1970 psa_key_type_t target_type;
1971 size_t target_bits;
1972 psa_key_usage_t constraint_usage = constraint_usage_arg;
1973 psa_algorithm_t constraint_alg = constraint_alg_arg;
1974 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
1975 psa_key_policy_t *p_constraint = NULL;
1976 psa_status_t expected_status = expected_status_arg;
1977
1978 if( constraint_usage_arg != -1 )
1979 {
1980 p_constraint = &constraint;
1981 psa_key_policy_set_usage( p_constraint,
1982 constraint_usage, constraint_alg );
1983 }
1984
1985 PSA_ASSERT( psa_crypto_init( ) );
1986
1987 /* Populate the source slot. */
1988 PSA_ASSERT( psa_allocate_key( &source_handle ) );
1989 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
1990 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02001991 PSA_ASSERT( psa_import_key_to_handle( source_handle, source_type,
Gilles Peskine57ab7212019-01-28 13:03:09 +01001992 material->x, material->len ) );
1993 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
1994
1995 /* Prepare the target slot. */
1996 PSA_ASSERT( psa_allocate_key( &target_handle ) );
1997 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
1998 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
1999 target_policy = psa_key_policy_init();
2000
2001 /* Copy the key. */
Gilles Peskine87a5e562019-04-17 12:28:25 +02002002 TEST_EQUAL( psa_copy_key_to_handle( source_handle, target_handle, p_constraint ),
Gilles Peskine57ab7212019-01-28 13:03:09 +01002003 expected_status );
2004
2005 /* Test that the target slot is unaffected. */
2006 TEST_EQUAL( psa_get_key_information( target_handle,
2007 &target_type, &target_bits ),
David Saadab4ecc272019-02-14 13:48:10 +02002008 PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002009 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
2010 TEST_EQUAL( target_usage, psa_key_policy_get_usage( &target_policy ) );
2011 TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &target_policy ) );
2012
2013exit:
2014 mbedtls_psa_crypto_free( );
2015}
2016/* END_CASE */
2017
2018/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002019void hash_operation_init( )
2020{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002021 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002022 /* Test each valid way of initializing the object, except for `= {0}`, as
2023 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2024 * though it's OK by the C standard. We could test for this, but we'd need
2025 * to supress the Clang warning for the test. */
2026 psa_hash_operation_t func = psa_hash_operation_init( );
2027 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2028 psa_hash_operation_t zero;
2029
2030 memset( &zero, 0, sizeof( zero ) );
2031
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002032 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002033 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2034 PSA_ERROR_BAD_STATE );
2035 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2036 PSA_ERROR_BAD_STATE );
2037 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2038 PSA_ERROR_BAD_STATE );
2039
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002040 /* A default hash operation should be abortable without error. */
2041 PSA_ASSERT( psa_hash_abort( &func ) );
2042 PSA_ASSERT( psa_hash_abort( &init ) );
2043 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002044}
2045/* END_CASE */
2046
2047/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002048void hash_setup( int alg_arg,
2049 int expected_status_arg )
2050{
2051 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002052 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002053 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002054 psa_status_t status;
2055
Gilles Peskine8817f612018-12-18 00:18:46 +01002056 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002057
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002058 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002059 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002060
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002061 /* Whether setup succeeded or failed, abort must succeed. */
2062 PSA_ASSERT( psa_hash_abort( &operation ) );
2063
2064 /* If setup failed, reproduce the failure, so as to
2065 * test the resulting state of the operation object. */
2066 if( status != PSA_SUCCESS )
2067 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2068
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002069 /* Now the operation object should be reusable. */
2070#if defined(KNOWN_SUPPORTED_HASH_ALG)
2071 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2072 PSA_ASSERT( psa_hash_abort( &operation ) );
2073#endif
2074
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002075exit:
2076 mbedtls_psa_crypto_free( );
2077}
2078/* END_CASE */
2079
2080/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002081void hash_bad_order( )
2082{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002083 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002084 unsigned char input[] = "";
2085 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002086 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002087 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2088 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2089 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002090 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002091 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002092 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002093
Gilles Peskine8817f612018-12-18 00:18:46 +01002094 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002095
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002096 /* Call setup twice in a row. */
2097 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2098 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2099 PSA_ERROR_BAD_STATE );
2100 PSA_ASSERT( psa_hash_abort( &operation ) );
2101
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002102 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002103 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002104 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002105 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002106
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002107 /* Call update after finish. */
2108 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2109 PSA_ASSERT( psa_hash_finish( &operation,
2110 hash, sizeof( hash ), &hash_len ) );
2111 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002112 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002113 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002114
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002115 /* Call verify without calling setup beforehand. */
2116 TEST_EQUAL( psa_hash_verify( &operation,
2117 valid_hash, sizeof( valid_hash ) ),
2118 PSA_ERROR_BAD_STATE );
2119 PSA_ASSERT( psa_hash_abort( &operation ) );
2120
2121 /* Call verify after finish. */
2122 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2123 PSA_ASSERT( psa_hash_finish( &operation,
2124 hash, sizeof( hash ), &hash_len ) );
2125 TEST_EQUAL( psa_hash_verify( &operation,
2126 valid_hash, sizeof( valid_hash ) ),
2127 PSA_ERROR_BAD_STATE );
2128 PSA_ASSERT( psa_hash_abort( &operation ) );
2129
2130 /* Call verify twice in a row. */
2131 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2132 PSA_ASSERT( psa_hash_verify( &operation,
2133 valid_hash, sizeof( valid_hash ) ) );
2134 TEST_EQUAL( psa_hash_verify( &operation,
2135 valid_hash, sizeof( valid_hash ) ),
2136 PSA_ERROR_BAD_STATE );
2137 PSA_ASSERT( psa_hash_abort( &operation ) );
2138
2139 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002140 TEST_EQUAL( psa_hash_finish( &operation,
2141 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002142 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002143 PSA_ASSERT( psa_hash_abort( &operation ) );
2144
2145 /* Call finish twice in a row. */
2146 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2147 PSA_ASSERT( psa_hash_finish( &operation,
2148 hash, sizeof( hash ), &hash_len ) );
2149 TEST_EQUAL( psa_hash_finish( &operation,
2150 hash, sizeof( hash ), &hash_len ),
2151 PSA_ERROR_BAD_STATE );
2152 PSA_ASSERT( psa_hash_abort( &operation ) );
2153
2154 /* Call finish after calling verify. */
2155 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2156 PSA_ASSERT( psa_hash_verify( &operation,
2157 valid_hash, sizeof( valid_hash ) ) );
2158 TEST_EQUAL( psa_hash_finish( &operation,
2159 hash, sizeof( hash ), &hash_len ),
2160 PSA_ERROR_BAD_STATE );
2161 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002162
2163exit:
2164 mbedtls_psa_crypto_free( );
2165}
2166/* END_CASE */
2167
itayzafrir27e69452018-11-01 14:26:34 +02002168/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2169void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002170{
2171 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002172 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2173 * appended to it */
2174 unsigned char hash[] = {
2175 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2176 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2177 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002178 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002179 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002180
Gilles Peskine8817f612018-12-18 00:18:46 +01002181 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002182
itayzafrir27e69452018-11-01 14:26:34 +02002183 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002184 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002185 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002186 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002187
itayzafrir27e69452018-11-01 14:26:34 +02002188 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002189 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002190 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002191 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002192
itayzafrir27e69452018-11-01 14:26:34 +02002193 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002194 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002195 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002196 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002197
itayzafrirec93d302018-10-18 18:01:10 +03002198exit:
2199 mbedtls_psa_crypto_free( );
2200}
2201/* END_CASE */
2202
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002203/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2204void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002205{
2206 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002207 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002208 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002209 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002210 size_t hash_len;
2211
Gilles Peskine8817f612018-12-18 00:18:46 +01002212 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002213
itayzafrir58028322018-10-25 10:22:01 +03002214 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002215 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002216 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002217 hash, expected_size - 1, &hash_len ),
2218 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002219
2220exit:
2221 mbedtls_psa_crypto_free( );
2222}
2223/* END_CASE */
2224
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002225/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2226void hash_clone_source_state( )
2227{
2228 psa_algorithm_t alg = PSA_ALG_SHA_256;
2229 unsigned char hash[PSA_HASH_MAX_SIZE];
2230 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2231 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2232 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2233 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2234 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2235 size_t hash_len;
2236
2237 PSA_ASSERT( psa_crypto_init( ) );
2238 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2239
2240 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2241 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2242 PSA_ASSERT( psa_hash_finish( &op_finished,
2243 hash, sizeof( hash ), &hash_len ) );
2244 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2245 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2246
2247 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2248 PSA_ERROR_BAD_STATE );
2249
2250 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2251 PSA_ASSERT( psa_hash_finish( &op_init,
2252 hash, sizeof( hash ), &hash_len ) );
2253 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2254 PSA_ASSERT( psa_hash_finish( &op_finished,
2255 hash, sizeof( hash ), &hash_len ) );
2256 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2257 PSA_ASSERT( psa_hash_finish( &op_aborted,
2258 hash, sizeof( hash ), &hash_len ) );
2259
2260exit:
2261 psa_hash_abort( &op_source );
2262 psa_hash_abort( &op_init );
2263 psa_hash_abort( &op_setup );
2264 psa_hash_abort( &op_finished );
2265 psa_hash_abort( &op_aborted );
2266 mbedtls_psa_crypto_free( );
2267}
2268/* END_CASE */
2269
2270/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2271void hash_clone_target_state( )
2272{
2273 psa_algorithm_t alg = PSA_ALG_SHA_256;
2274 unsigned char hash[PSA_HASH_MAX_SIZE];
2275 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2276 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2277 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2278 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2279 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2280 size_t hash_len;
2281
2282 PSA_ASSERT( psa_crypto_init( ) );
2283
2284 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2285 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2286 PSA_ASSERT( psa_hash_finish( &op_finished,
2287 hash, sizeof( hash ), &hash_len ) );
2288 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2289 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2290
2291 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2292 PSA_ASSERT( psa_hash_finish( &op_target,
2293 hash, sizeof( hash ), &hash_len ) );
2294
2295 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2296 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2297 PSA_ERROR_BAD_STATE );
2298 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2299 PSA_ERROR_BAD_STATE );
2300
2301exit:
2302 psa_hash_abort( &op_target );
2303 psa_hash_abort( &op_init );
2304 psa_hash_abort( &op_setup );
2305 psa_hash_abort( &op_finished );
2306 psa_hash_abort( &op_aborted );
2307 mbedtls_psa_crypto_free( );
2308}
2309/* END_CASE */
2310
itayzafrir58028322018-10-25 10:22:01 +03002311/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002312void mac_operation_init( )
2313{
Jaeden Amero252ef282019-02-15 14:05:35 +00002314 const uint8_t input[1] = { 0 };
2315
Jaeden Amero769ce272019-01-04 11:48:03 +00002316 /* Test each valid way of initializing the object, except for `= {0}`, as
2317 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2318 * though it's OK by the C standard. We could test for this, but we'd need
2319 * to supress the Clang warning for the test. */
2320 psa_mac_operation_t func = psa_mac_operation_init( );
2321 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2322 psa_mac_operation_t zero;
2323
2324 memset( &zero, 0, sizeof( zero ) );
2325
Jaeden Amero252ef282019-02-15 14:05:35 +00002326 /* A freshly-initialized MAC operation should not be usable. */
2327 TEST_EQUAL( psa_mac_update( &func,
2328 input, sizeof( input ) ),
2329 PSA_ERROR_BAD_STATE );
2330 TEST_EQUAL( psa_mac_update( &init,
2331 input, sizeof( input ) ),
2332 PSA_ERROR_BAD_STATE );
2333 TEST_EQUAL( psa_mac_update( &zero,
2334 input, sizeof( input ) ),
2335 PSA_ERROR_BAD_STATE );
2336
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002337 /* A default MAC operation should be abortable without error. */
2338 PSA_ASSERT( psa_mac_abort( &func ) );
2339 PSA_ASSERT( psa_mac_abort( &init ) );
2340 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002341}
2342/* END_CASE */
2343
2344/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002345void mac_setup( int key_type_arg,
2346 data_t *key,
2347 int alg_arg,
2348 int expected_status_arg )
2349{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002350 psa_key_type_t key_type = key_type_arg;
2351 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002352 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002353 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002354 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2355#if defined(KNOWN_SUPPORTED_MAC_ALG)
2356 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2357#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002358
Gilles Peskine8817f612018-12-18 00:18:46 +01002359 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002360
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002361 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2362 &operation, &status ) )
2363 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002364 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002365
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002366 /* The operation object should be reusable. */
2367#if defined(KNOWN_SUPPORTED_MAC_ALG)
2368 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2369 smoke_test_key_data,
2370 sizeof( smoke_test_key_data ),
2371 KNOWN_SUPPORTED_MAC_ALG,
2372 &operation, &status ) )
2373 goto exit;
2374 TEST_EQUAL( status, PSA_SUCCESS );
2375#endif
2376
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002377exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002378 mbedtls_psa_crypto_free( );
2379}
2380/* END_CASE */
2381
2382/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002383void mac_bad_order( )
2384{
2385 psa_key_handle_t handle = 0;
2386 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2387 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2388 const uint8_t key[] = {
2389 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2390 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2391 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
2392 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2393 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2394 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2395 size_t sign_mac_length = 0;
2396 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2397 const uint8_t verify_mac[] = {
2398 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2399 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2400 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2401
2402 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir3e02b3b2018-06-12 17:06:52 +03002403 PSA_ASSERT( psa_allocate_key( &handle ) );
2404 psa_key_policy_set_usage( &policy,
2405 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002406 alg );
2407 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2408
Gilles Peskine87a5e562019-04-17 12:28:25 +02002409 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Jaeden Amero252ef282019-02-15 14:05:35 +00002410 key, sizeof(key) ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002411
Jaeden Amero252ef282019-02-15 14:05:35 +00002412 /* Call update without calling setup beforehand. */
2413 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2414 PSA_ERROR_BAD_STATE );
2415 PSA_ASSERT( psa_mac_abort( &operation ) );
2416
2417 /* Call sign finish without calling setup beforehand. */
2418 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2419 &sign_mac_length),
2420 PSA_ERROR_BAD_STATE );
2421 PSA_ASSERT( psa_mac_abort( &operation ) );
2422
2423 /* Call verify finish without calling setup beforehand. */
2424 TEST_EQUAL( psa_mac_verify_finish( &operation,
2425 verify_mac, sizeof( verify_mac ) ),
2426 PSA_ERROR_BAD_STATE );
2427 PSA_ASSERT( psa_mac_abort( &operation ) );
2428
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002429 /* Call setup twice in a row. */
2430 PSA_ASSERT( psa_mac_sign_setup( &operation,
2431 handle, alg ) );
2432 TEST_EQUAL( psa_mac_sign_setup( &operation,
2433 handle, alg ),
2434 PSA_ERROR_BAD_STATE );
2435 PSA_ASSERT( psa_mac_abort( &operation ) );
2436
Jaeden Amero252ef282019-02-15 14:05:35 +00002437 /* Call update after sign finish. */
2438 PSA_ASSERT( psa_mac_sign_setup( &operation,
2439 handle, alg ) );
2440 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2441 PSA_ASSERT( psa_mac_sign_finish( &operation,
2442 sign_mac, sizeof( sign_mac ),
2443 &sign_mac_length ) );
2444 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2445 PSA_ERROR_BAD_STATE );
2446 PSA_ASSERT( psa_mac_abort( &operation ) );
2447
2448 /* Call update after verify finish. */
2449 PSA_ASSERT( psa_mac_verify_setup( &operation,
2450 handle, alg ) );
2451 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2452 PSA_ASSERT( psa_mac_verify_finish( &operation,
2453 verify_mac, sizeof( verify_mac ) ) );
2454 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2455 PSA_ERROR_BAD_STATE );
2456 PSA_ASSERT( psa_mac_abort( &operation ) );
2457
2458 /* Call sign finish twice in a row. */
2459 PSA_ASSERT( psa_mac_sign_setup( &operation,
2460 handle, alg ) );
2461 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2462 PSA_ASSERT( psa_mac_sign_finish( &operation,
2463 sign_mac, sizeof( sign_mac ),
2464 &sign_mac_length ) );
2465 TEST_EQUAL( psa_mac_sign_finish( &operation,
2466 sign_mac, sizeof( sign_mac ),
2467 &sign_mac_length ),
2468 PSA_ERROR_BAD_STATE );
2469 PSA_ASSERT( psa_mac_abort( &operation ) );
2470
2471 /* Call verify finish twice in a row. */
2472 PSA_ASSERT( psa_mac_verify_setup( &operation,
2473 handle, alg ) );
2474 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2475 PSA_ASSERT( psa_mac_verify_finish( &operation,
2476 verify_mac, sizeof( verify_mac ) ) );
2477 TEST_EQUAL( psa_mac_verify_finish( &operation,
2478 verify_mac, sizeof( verify_mac ) ),
2479 PSA_ERROR_BAD_STATE );
2480 PSA_ASSERT( psa_mac_abort( &operation ) );
2481
2482 /* Setup sign but try verify. */
2483 PSA_ASSERT( psa_mac_sign_setup( &operation,
2484 handle, alg ) );
2485 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2486 TEST_EQUAL( psa_mac_verify_finish( &operation,
2487 verify_mac, sizeof( verify_mac ) ),
2488 PSA_ERROR_BAD_STATE );
2489 PSA_ASSERT( psa_mac_abort( &operation ) );
2490
2491 /* Setup verify but try sign. */
2492 PSA_ASSERT( psa_mac_verify_setup( &operation,
2493 handle, alg ) );
2494 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2495 TEST_EQUAL( psa_mac_sign_finish( &operation,
2496 sign_mac, sizeof( sign_mac ),
2497 &sign_mac_length ),
2498 PSA_ERROR_BAD_STATE );
2499 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002500
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002501exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002502 mbedtls_psa_crypto_free( );
2503}
2504/* END_CASE */
2505
2506/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002507void mac_sign( int key_type_arg,
2508 data_t *key,
2509 int alg_arg,
2510 data_t *input,
2511 data_t *expected_mac )
2512{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002513 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002514 psa_key_type_t key_type = key_type_arg;
2515 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002516 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002517 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002518 /* Leave a little extra room in the output buffer. At the end of the
2519 * test, we'll check that the implementation didn't overwrite onto
2520 * this extra room. */
2521 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2522 size_t mac_buffer_size =
2523 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2524 size_t mac_length = 0;
2525
2526 memset( actual_mac, '+', sizeof( actual_mac ) );
2527 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2528 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2529
Gilles Peskine8817f612018-12-18 00:18:46 +01002530 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002531
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002532 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002533 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002534 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002535
Gilles Peskine87a5e562019-04-17 12:28:25 +02002536 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002537 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002538
2539 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002540 PSA_ASSERT( psa_mac_sign_setup( &operation,
2541 handle, alg ) );
2542 PSA_ASSERT( psa_mac_update( &operation,
2543 input->x, input->len ) );
2544 PSA_ASSERT( psa_mac_sign_finish( &operation,
2545 actual_mac, mac_buffer_size,
2546 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002547
2548 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002549 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2550 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002551
2552 /* Verify that the end of the buffer is untouched. */
2553 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2554 sizeof( actual_mac ) - mac_length ) );
2555
2556exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002557 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002558 mbedtls_psa_crypto_free( );
2559}
2560/* END_CASE */
2561
2562/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002563void mac_verify( int key_type_arg,
2564 data_t *key,
2565 int alg_arg,
2566 data_t *input,
2567 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002568{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002569 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002570 psa_key_type_t key_type = key_type_arg;
2571 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002572 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002573 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002574
Gilles Peskine69c12672018-06-28 00:07:19 +02002575 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2576
Gilles Peskine8817f612018-12-18 00:18:46 +01002577 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002578
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002579 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002580 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002581 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad16036df908f2018-04-02 08:34:15 -07002582
Gilles Peskine87a5e562019-04-17 12:28:25 +02002583 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002584 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002585
Gilles Peskine8817f612018-12-18 00:18:46 +01002586 PSA_ASSERT( psa_mac_verify_setup( &operation,
2587 handle, alg ) );
2588 PSA_ASSERT( psa_destroy_key( handle ) );
2589 PSA_ASSERT( psa_mac_update( &operation,
2590 input->x, input->len ) );
2591 PSA_ASSERT( psa_mac_verify_finish( &operation,
2592 expected_mac->x,
2593 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002594
2595exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002596 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002597 mbedtls_psa_crypto_free( );
2598}
2599/* END_CASE */
2600
2601/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002602void cipher_operation_init( )
2603{
Jaeden Ameroab439972019-02-15 14:12:05 +00002604 const uint8_t input[1] = { 0 };
2605 unsigned char output[1] = { 0 };
2606 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002607 /* Test each valid way of initializing the object, except for `= {0}`, as
2608 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2609 * though it's OK by the C standard. We could test for this, but we'd need
2610 * to supress the Clang warning for the test. */
2611 psa_cipher_operation_t func = psa_cipher_operation_init( );
2612 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2613 psa_cipher_operation_t zero;
2614
2615 memset( &zero, 0, sizeof( zero ) );
2616
Jaeden Ameroab439972019-02-15 14:12:05 +00002617 /* A freshly-initialized cipher operation should not be usable. */
2618 TEST_EQUAL( psa_cipher_update( &func,
2619 input, sizeof( input ),
2620 output, sizeof( output ),
2621 &output_length ),
2622 PSA_ERROR_BAD_STATE );
2623 TEST_EQUAL( psa_cipher_update( &init,
2624 input, sizeof( input ),
2625 output, sizeof( output ),
2626 &output_length ),
2627 PSA_ERROR_BAD_STATE );
2628 TEST_EQUAL( psa_cipher_update( &zero,
2629 input, sizeof( input ),
2630 output, sizeof( output ),
2631 &output_length ),
2632 PSA_ERROR_BAD_STATE );
2633
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002634 /* A default cipher operation should be abortable without error. */
2635 PSA_ASSERT( psa_cipher_abort( &func ) );
2636 PSA_ASSERT( psa_cipher_abort( &init ) );
2637 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002638}
2639/* END_CASE */
2640
2641/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002642void cipher_setup( int key_type_arg,
2643 data_t *key,
2644 int alg_arg,
2645 int expected_status_arg )
2646{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002647 psa_key_type_t key_type = key_type_arg;
2648 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002649 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002650 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002651 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002652#if defined(KNOWN_SUPPORTED_MAC_ALG)
2653 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2654#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002655
Gilles Peskine8817f612018-12-18 00:18:46 +01002656 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002657
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002658 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2659 &operation, &status ) )
2660 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002661 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002662
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002663 /* The operation object should be reusable. */
2664#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2665 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2666 smoke_test_key_data,
2667 sizeof( smoke_test_key_data ),
2668 KNOWN_SUPPORTED_CIPHER_ALG,
2669 &operation, &status ) )
2670 goto exit;
2671 TEST_EQUAL( status, PSA_SUCCESS );
2672#endif
2673
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002674exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002675 mbedtls_psa_crypto_free( );
2676}
2677/* END_CASE */
2678
2679/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002680void cipher_bad_order( )
2681{
2682 psa_key_handle_t handle = 0;
2683 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2684 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
2685 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2686 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2687 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2688 const uint8_t key[] = {
2689 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2690 0xaa, 0xaa, 0xaa, 0xaa };
2691 const uint8_t text[] = {
2692 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2693 0xbb, 0xbb, 0xbb, 0xbb };
2694 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2695 size_t length = 0;
2696
2697 PSA_ASSERT( psa_crypto_init( ) );
2698 PSA_ASSERT( psa_allocate_key( &handle ) );
2699 psa_key_policy_set_usage( &policy,
2700 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
2701 alg );
2702 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02002703 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Jaeden Ameroab439972019-02-15 14:12:05 +00002704 key, sizeof(key) ) );
2705
2706
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002707 /* Call encrypt setup twice in a row. */
2708 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2709 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2710 PSA_ERROR_BAD_STATE );
2711 PSA_ASSERT( psa_cipher_abort( &operation ) );
2712
2713 /* Call decrypt setup twice in a row. */
2714 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2715 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2716 PSA_ERROR_BAD_STATE );
2717 PSA_ASSERT( psa_cipher_abort( &operation ) );
2718
Jaeden Ameroab439972019-02-15 14:12:05 +00002719 /* Generate an IV without calling setup beforehand. */
2720 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2721 buffer, sizeof( buffer ),
2722 &length ),
2723 PSA_ERROR_BAD_STATE );
2724 PSA_ASSERT( psa_cipher_abort( &operation ) );
2725
2726 /* Generate an IV twice in a row. */
2727 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2728 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2729 buffer, sizeof( buffer ),
2730 &length ) );
2731 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2732 buffer, sizeof( buffer ),
2733 &length ),
2734 PSA_ERROR_BAD_STATE );
2735 PSA_ASSERT( psa_cipher_abort( &operation ) );
2736
2737 /* Generate an IV after it's already set. */
2738 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2739 PSA_ASSERT( psa_cipher_set_iv( &operation,
2740 iv, sizeof( iv ) ) );
2741 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2742 buffer, sizeof( buffer ),
2743 &length ),
2744 PSA_ERROR_BAD_STATE );
2745 PSA_ASSERT( psa_cipher_abort( &operation ) );
2746
2747 /* Set an IV without calling setup beforehand. */
2748 TEST_EQUAL( psa_cipher_set_iv( &operation,
2749 iv, sizeof( iv ) ),
2750 PSA_ERROR_BAD_STATE );
2751 PSA_ASSERT( psa_cipher_abort( &operation ) );
2752
2753 /* Set an IV after it's already set. */
2754 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2755 PSA_ASSERT( psa_cipher_set_iv( &operation,
2756 iv, sizeof( iv ) ) );
2757 TEST_EQUAL( psa_cipher_set_iv( &operation,
2758 iv, sizeof( iv ) ),
2759 PSA_ERROR_BAD_STATE );
2760 PSA_ASSERT( psa_cipher_abort( &operation ) );
2761
2762 /* Set an IV after it's already generated. */
2763 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2764 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2765 buffer, sizeof( buffer ),
2766 &length ) );
2767 TEST_EQUAL( psa_cipher_set_iv( &operation,
2768 iv, sizeof( iv ) ),
2769 PSA_ERROR_BAD_STATE );
2770 PSA_ASSERT( psa_cipher_abort( &operation ) );
2771
2772 /* Call update without calling setup beforehand. */
2773 TEST_EQUAL( psa_cipher_update( &operation,
2774 text, sizeof( text ),
2775 buffer, sizeof( buffer ),
2776 &length ),
2777 PSA_ERROR_BAD_STATE );
2778 PSA_ASSERT( psa_cipher_abort( &operation ) );
2779
2780 /* Call update without an IV where an IV is required. */
2781 TEST_EQUAL( psa_cipher_update( &operation,
2782 text, sizeof( text ),
2783 buffer, sizeof( buffer ),
2784 &length ),
2785 PSA_ERROR_BAD_STATE );
2786 PSA_ASSERT( psa_cipher_abort( &operation ) );
2787
2788 /* Call update after finish. */
2789 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2790 PSA_ASSERT( psa_cipher_set_iv( &operation,
2791 iv, sizeof( iv ) ) );
2792 PSA_ASSERT( psa_cipher_finish( &operation,
2793 buffer, sizeof( buffer ), &length ) );
2794 TEST_EQUAL( psa_cipher_update( &operation,
2795 text, sizeof( text ),
2796 buffer, sizeof( buffer ),
2797 &length ),
2798 PSA_ERROR_BAD_STATE );
2799 PSA_ASSERT( psa_cipher_abort( &operation ) );
2800
2801 /* Call finish without calling setup beforehand. */
2802 TEST_EQUAL( psa_cipher_finish( &operation,
2803 buffer, sizeof( buffer ), &length ),
2804 PSA_ERROR_BAD_STATE );
2805 PSA_ASSERT( psa_cipher_abort( &operation ) );
2806
2807 /* Call finish without an IV where an IV is required. */
2808 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2809 /* Not calling update means we are encrypting an empty buffer, which is OK
2810 * for cipher modes with padding. */
2811 TEST_EQUAL( psa_cipher_finish( &operation,
2812 buffer, sizeof( buffer ), &length ),
2813 PSA_ERROR_BAD_STATE );
2814 PSA_ASSERT( psa_cipher_abort( &operation ) );
2815
2816 /* Call finish twice in a row. */
2817 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2818 PSA_ASSERT( psa_cipher_set_iv( &operation,
2819 iv, sizeof( iv ) ) );
2820 PSA_ASSERT( psa_cipher_finish( &operation,
2821 buffer, sizeof( buffer ), &length ) );
2822 TEST_EQUAL( psa_cipher_finish( &operation,
2823 buffer, sizeof( buffer ), &length ),
2824 PSA_ERROR_BAD_STATE );
2825 PSA_ASSERT( psa_cipher_abort( &operation ) );
2826
2827exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002828 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002829}
2830/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002831
Gilles Peskine50e586b2018-06-08 14:28:46 +02002832/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002833void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002834 data_t *key,
2835 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002836 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002837{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002838 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002839 psa_status_t status;
2840 psa_key_type_t key_type = key_type_arg;
2841 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002842 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002843 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002844 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002845 unsigned char *output = NULL;
2846 size_t output_buffer_size = 0;
2847 size_t function_output_length = 0;
2848 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002849 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002850 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002851
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002852 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2853 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002854
Gilles Peskine8817f612018-12-18 00:18:46 +01002855 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002856
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002857 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002858 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002859 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002860
Gilles Peskine87a5e562019-04-17 12:28:25 +02002861 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002862 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002863
Gilles Peskine8817f612018-12-18 00:18:46 +01002864 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2865 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002866
Gilles Peskine8817f612018-12-18 00:18:46 +01002867 PSA_ASSERT( psa_cipher_set_iv( &operation,
2868 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002869 output_buffer_size = ( (size_t) input->len +
2870 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002871 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002872
Gilles Peskine8817f612018-12-18 00:18:46 +01002873 PSA_ASSERT( psa_cipher_update( &operation,
2874 input->x, input->len,
2875 output, output_buffer_size,
2876 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002877 total_output_length += function_output_length;
2878 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002879 output + total_output_length,
2880 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002881 &function_output_length );
2882 total_output_length += function_output_length;
2883
Gilles Peskinefe11b722018-12-18 00:24:04 +01002884 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002885 if( expected_status == PSA_SUCCESS )
2886 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002887 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002888 ASSERT_COMPARE( expected_output->x, expected_output->len,
2889 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002890 }
2891
2892exit:
2893 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002894 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002895 mbedtls_psa_crypto_free( );
2896}
2897/* END_CASE */
2898
2899/* BEGIN_CASE */
2900void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
2901 data_t *key,
2902 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002903 int first_part_size_arg,
2904 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002905 data_t *expected_output )
2906{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002907 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002908 psa_key_type_t key_type = key_type_arg;
2909 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002910 size_t first_part_size = first_part_size_arg;
2911 size_t output1_length = output1_length_arg;
2912 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002913 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002914 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002915 unsigned char *output = NULL;
2916 size_t output_buffer_size = 0;
2917 size_t function_output_length = 0;
2918 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002919 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002920 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002921
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002922 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2923 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924
Gilles Peskine8817f612018-12-18 00:18:46 +01002925 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002926
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002927 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002928 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002929 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002930
Gilles Peskine87a5e562019-04-17 12:28:25 +02002931 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002932 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933
Gilles Peskine8817f612018-12-18 00:18:46 +01002934 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2935 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002936
Gilles Peskine8817f612018-12-18 00:18:46 +01002937 PSA_ASSERT( psa_cipher_set_iv( &operation,
2938 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002939 output_buffer_size = ( (size_t) input->len +
2940 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002941 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002942
Gilles Peskinee0866522019-02-19 19:44:00 +01002943 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002944 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2945 output, output_buffer_size,
2946 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002947 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002948 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002949 PSA_ASSERT( psa_cipher_update( &operation,
2950 input->x + first_part_size,
2951 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002952 output + total_output_length,
2953 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002954 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002955 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002956 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002957 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002958 output + total_output_length,
2959 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002960 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002961 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002962 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002963
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002964 ASSERT_COMPARE( expected_output->x, expected_output->len,
2965 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002966
2967exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002968 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002969 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002970 mbedtls_psa_crypto_free( );
2971}
2972/* END_CASE */
2973
2974/* BEGIN_CASE */
2975void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002976 data_t *key,
2977 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002978 int first_part_size_arg,
2979 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002980 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002981{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002982 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002983
2984 psa_key_type_t key_type = key_type_arg;
2985 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002986 size_t first_part_size = first_part_size_arg;
2987 size_t output1_length = output1_length_arg;
2988 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002989 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002990 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002991 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002992 size_t output_buffer_size = 0;
2993 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002994 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002995 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002996 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002997
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002998 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2999 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003000
Gilles Peskine8817f612018-12-18 00:18:46 +01003001 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003002
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003003 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003004 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003005 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003006
Gilles Peskine87a5e562019-04-17 12:28:25 +02003007 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003008 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003009
Gilles Peskine8817f612018-12-18 00:18:46 +01003010 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3011 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012
Gilles Peskine8817f612018-12-18 00:18:46 +01003013 PSA_ASSERT( psa_cipher_set_iv( &operation,
3014 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003015
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003016 output_buffer_size = ( (size_t) input->len +
3017 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003018 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003019
Gilles Peskinee0866522019-02-19 19:44:00 +01003020 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003021 PSA_ASSERT( psa_cipher_update( &operation,
3022 input->x, first_part_size,
3023 output, output_buffer_size,
3024 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003025 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003026 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003027 PSA_ASSERT( psa_cipher_update( &operation,
3028 input->x + first_part_size,
3029 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003030 output + total_output_length,
3031 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003032 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003033 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003034 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003035 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003036 output + total_output_length,
3037 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003038 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003039 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003040 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003042 ASSERT_COMPARE( expected_output->x, expected_output->len,
3043 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003044
3045exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003046 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003047 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003048 mbedtls_psa_crypto_free( );
3049}
3050/* END_CASE */
3051
Gilles Peskine50e586b2018-06-08 14:28:46 +02003052/* BEGIN_CASE */
3053void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003054 data_t *key,
3055 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003056 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003057{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003058 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003059 psa_status_t status;
3060 psa_key_type_t key_type = key_type_arg;
3061 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003062 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003063 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003064 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003065 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003066 size_t output_buffer_size = 0;
3067 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003068 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003069 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003070 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003071
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003072 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3073 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074
Gilles Peskine8817f612018-12-18 00:18:46 +01003075 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003076
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003077 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003078 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003079 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003080
Gilles Peskine87a5e562019-04-17 12:28:25 +02003081 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003082 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003083
Gilles Peskine8817f612018-12-18 00:18:46 +01003084 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3085 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086
Gilles Peskine8817f612018-12-18 00:18:46 +01003087 PSA_ASSERT( psa_cipher_set_iv( &operation,
3088 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003089
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003090 output_buffer_size = ( (size_t) input->len +
3091 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003092 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003093
Gilles Peskine8817f612018-12-18 00:18:46 +01003094 PSA_ASSERT( psa_cipher_update( &operation,
3095 input->x, input->len,
3096 output, output_buffer_size,
3097 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003098 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003099 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003100 output + total_output_length,
3101 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003102 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003103 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003104 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003105
3106 if( expected_status == PSA_SUCCESS )
3107 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003108 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003109 ASSERT_COMPARE( expected_output->x, expected_output->len,
3110 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003111 }
3112
Gilles Peskine50e586b2018-06-08 14:28:46 +02003113exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003114 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003115 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003116 mbedtls_psa_crypto_free( );
3117}
3118/* END_CASE */
3119
Gilles Peskine50e586b2018-06-08 14:28:46 +02003120/* BEGIN_CASE */
3121void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003122 data_t *key,
3123 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003124{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003125 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003126 psa_key_type_t key_type = key_type_arg;
3127 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003128 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003129 size_t iv_size = 16;
3130 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003131 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003132 size_t output1_size = 0;
3133 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003134 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003135 size_t output2_size = 0;
3136 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003137 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003138 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3139 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003140 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003141
Gilles Peskine8817f612018-12-18 00:18:46 +01003142 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003143
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003144 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003145 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003146 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003147
Gilles Peskine87a5e562019-04-17 12:28:25 +02003148 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003149 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003150
Gilles Peskine8817f612018-12-18 00:18:46 +01003151 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3152 handle, alg ) );
3153 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3154 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003155
Gilles Peskine8817f612018-12-18 00:18:46 +01003156 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3157 iv, iv_size,
3158 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003159 output1_size = ( (size_t) input->len +
3160 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003161 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003162
Gilles Peskine8817f612018-12-18 00:18:46 +01003163 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3164 output1, output1_size,
3165 &output1_length ) );
3166 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003167 output1 + output1_length,
3168 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003169 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003170
Gilles Peskine048b7f02018-06-08 14:20:49 +02003171 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003172
Gilles Peskine8817f612018-12-18 00:18:46 +01003173 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003174
3175 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003176 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003177
Gilles Peskine8817f612018-12-18 00:18:46 +01003178 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3179 iv, iv_length ) );
3180 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3181 output2, output2_size,
3182 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003183 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003184 PSA_ASSERT( psa_cipher_finish( &operation2,
3185 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003186 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003187 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003188
Gilles Peskine048b7f02018-06-08 14:20:49 +02003189 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003190
Gilles Peskine8817f612018-12-18 00:18:46 +01003191 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003192
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003193 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003194
3195exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003196 mbedtls_free( output1 );
3197 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003198 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003199 mbedtls_psa_crypto_free( );
3200}
3201/* END_CASE */
3202
3203/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003204void cipher_verify_output_multipart( int alg_arg,
3205 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003206 data_t *key,
3207 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003208 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003209{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003210 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003211 psa_key_type_t key_type = key_type_arg;
3212 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003213 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003214 unsigned char iv[16] = {0};
3215 size_t iv_size = 16;
3216 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003217 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003218 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003219 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003220 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003221 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003222 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003223 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003224 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3225 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003226 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003227
Gilles Peskine8817f612018-12-18 00:18:46 +01003228 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003229
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003230 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003231 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003232 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003233
Gilles Peskine87a5e562019-04-17 12:28:25 +02003234 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003235 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003236
Gilles Peskine8817f612018-12-18 00:18:46 +01003237 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3238 handle, alg ) );
3239 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3240 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003241
Gilles Peskine8817f612018-12-18 00:18:46 +01003242 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3243 iv, iv_size,
3244 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003245 output1_buffer_size = ( (size_t) input->len +
3246 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003247 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003248
Gilles Peskinee0866522019-02-19 19:44:00 +01003249 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003250
Gilles Peskine8817f612018-12-18 00:18:46 +01003251 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3252 output1, output1_buffer_size,
3253 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003254 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003255
Gilles Peskine8817f612018-12-18 00:18:46 +01003256 PSA_ASSERT( psa_cipher_update( &operation1,
3257 input->x + first_part_size,
3258 input->len - first_part_size,
3259 output1, output1_buffer_size,
3260 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003261 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003262
Gilles Peskine8817f612018-12-18 00:18:46 +01003263 PSA_ASSERT( psa_cipher_finish( &operation1,
3264 output1 + output1_length,
3265 output1_buffer_size - output1_length,
3266 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003267 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003268
Gilles Peskine8817f612018-12-18 00:18:46 +01003269 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003270
Gilles Peskine048b7f02018-06-08 14:20:49 +02003271 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003272 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003273
Gilles Peskine8817f612018-12-18 00:18:46 +01003274 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3275 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003276
Gilles Peskine8817f612018-12-18 00:18:46 +01003277 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3278 output2, output2_buffer_size,
3279 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003280 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003281
Gilles Peskine8817f612018-12-18 00:18:46 +01003282 PSA_ASSERT( psa_cipher_update( &operation2,
3283 output1 + first_part_size,
3284 output1_length - first_part_size,
3285 output2, output2_buffer_size,
3286 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003287 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003288
Gilles Peskine8817f612018-12-18 00:18:46 +01003289 PSA_ASSERT( psa_cipher_finish( &operation2,
3290 output2 + output2_length,
3291 output2_buffer_size - output2_length,
3292 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003293 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003294
Gilles Peskine8817f612018-12-18 00:18:46 +01003295 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003296
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003297 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003298
3299exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003300 mbedtls_free( output1 );
3301 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003302 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003303 mbedtls_psa_crypto_free( );
3304}
3305/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003306
Gilles Peskine20035e32018-02-03 22:44:14 +01003307/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003308void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003309 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003310 data_t *nonce,
3311 data_t *additional_data,
3312 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003313 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003314{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003315 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003316 psa_key_type_t key_type = key_type_arg;
3317 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003318 unsigned char *output_data = NULL;
3319 size_t output_size = 0;
3320 size_t output_length = 0;
3321 unsigned char *output_data2 = NULL;
3322 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003323 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003324 psa_status_t expected_result = expected_result_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003325 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003326
Gilles Peskine4abf7412018-06-18 16:35:34 +02003327 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003328 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003329
Gilles Peskine8817f612018-12-18 00:18:46 +01003330 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003331
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003332 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003333 psa_key_policy_set_usage( &policy,
3334 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
3335 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003336 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003337
Gilles Peskine87a5e562019-04-17 12:28:25 +02003338 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003339 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003340
Gilles Peskinefe11b722018-12-18 00:24:04 +01003341 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3342 nonce->x, nonce->len,
3343 additional_data->x,
3344 additional_data->len,
3345 input_data->x, input_data->len,
3346 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003347 &output_length ),
3348 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003349
3350 if( PSA_SUCCESS == expected_result )
3351 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003352 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003353
Gilles Peskinefe11b722018-12-18 00:24:04 +01003354 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3355 nonce->x, nonce->len,
3356 additional_data->x,
3357 additional_data->len,
3358 output_data, output_length,
3359 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003360 &output_length2 ),
3361 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003362
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003363 ASSERT_COMPARE( input_data->x, input_data->len,
3364 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003365 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003366
Gilles Peskinea1cac842018-06-11 19:33:02 +02003367exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003368 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003369 mbedtls_free( output_data );
3370 mbedtls_free( output_data2 );
3371 mbedtls_psa_crypto_free( );
3372}
3373/* END_CASE */
3374
3375/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003376void aead_encrypt( int key_type_arg, data_t *key_data,
3377 int alg_arg,
3378 data_t *nonce,
3379 data_t *additional_data,
3380 data_t *input_data,
3381 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003382{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003383 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003384 psa_key_type_t key_type = key_type_arg;
3385 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003386 unsigned char *output_data = NULL;
3387 size_t output_size = 0;
3388 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003389 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003390 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003391
Gilles Peskine4abf7412018-06-18 16:35:34 +02003392 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003393 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003394
Gilles Peskine8817f612018-12-18 00:18:46 +01003395 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003396
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003397 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003399 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400
Gilles Peskine87a5e562019-04-17 12:28:25 +02003401 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003402 key_data->x,
3403 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003404
Gilles Peskine8817f612018-12-18 00:18:46 +01003405 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3406 nonce->x, nonce->len,
3407 additional_data->x, additional_data->len,
3408 input_data->x, input_data->len,
3409 output_data, output_size,
3410 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003411
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003412 ASSERT_COMPARE( expected_result->x, expected_result->len,
3413 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003414
Gilles Peskinea1cac842018-06-11 19:33:02 +02003415exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003416 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003417 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418 mbedtls_psa_crypto_free( );
3419}
3420/* END_CASE */
3421
3422/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003423void aead_decrypt( int key_type_arg, data_t *key_data,
3424 int alg_arg,
3425 data_t *nonce,
3426 data_t *additional_data,
3427 data_t *input_data,
3428 data_t *expected_data,
3429 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003430{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003431 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003432 psa_key_type_t key_type = key_type_arg;
3433 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003434 unsigned char *output_data = NULL;
3435 size_t output_size = 0;
3436 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003437 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003438 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003439 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003440
Gilles Peskine4abf7412018-06-18 16:35:34 +02003441 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003442 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003443
Gilles Peskine8817f612018-12-18 00:18:46 +01003444 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003445
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003446 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003447 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003448 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003449
Gilles Peskine87a5e562019-04-17 12:28:25 +02003450 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003451 key_data->x,
3452 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003453
Gilles Peskinefe11b722018-12-18 00:24:04 +01003454 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3455 nonce->x, nonce->len,
3456 additional_data->x,
3457 additional_data->len,
3458 input_data->x, input_data->len,
3459 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003460 &output_length ),
3461 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003462
Gilles Peskine2d277862018-06-18 15:41:12 +02003463 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003464 ASSERT_COMPARE( expected_data->x, expected_data->len,
3465 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003466
Gilles Peskinea1cac842018-06-11 19:33:02 +02003467exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003468 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003469 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003470 mbedtls_psa_crypto_free( );
3471}
3472/* END_CASE */
3473
3474/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003475void signature_size( int type_arg,
3476 int bits,
3477 int alg_arg,
3478 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003479{
3480 psa_key_type_t type = type_arg;
3481 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003482 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003483 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003484exit:
3485 ;
3486}
3487/* END_CASE */
3488
3489/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003490void sign_deterministic( int key_type_arg, data_t *key_data,
3491 int alg_arg, data_t *input_data,
3492 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003493{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003494 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003495 psa_key_type_t key_type = key_type_arg;
3496 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003497 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003498 unsigned char *signature = NULL;
3499 size_t signature_size;
3500 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003501 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003502 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003503
Gilles Peskine8817f612018-12-18 00:18:46 +01003504 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003505
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003506 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003507 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003508 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003509
Gilles Peskine87a5e562019-04-17 12:28:25 +02003510 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003511 key_data->x,
3512 key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003513 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3514 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003515
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003516 /* Allocate a buffer which has the size advertized by the
3517 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003518 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3519 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003520 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003521 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003522 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003523
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003524 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003525 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3526 input_data->x, input_data->len,
3527 signature, signature_size,
3528 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003529 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003530 ASSERT_COMPARE( output_data->x, output_data->len,
3531 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003532
3533exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003534 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003535 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003536 mbedtls_psa_crypto_free( );
3537}
3538/* END_CASE */
3539
3540/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003541void sign_fail( int key_type_arg, data_t *key_data,
3542 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003543 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003544{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003545 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003546 psa_key_type_t key_type = key_type_arg;
3547 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003548 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003549 psa_status_t actual_status;
3550 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003551 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003552 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003553 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003554
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003555 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003556
Gilles Peskine8817f612018-12-18 00:18:46 +01003557 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003558
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003559 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003560 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003561 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003562
Gilles Peskine87a5e562019-04-17 12:28:25 +02003563 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003564 key_data->x,
3565 key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003566
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003567 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003568 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003569 signature, signature_size,
3570 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003571 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003572 /* The value of *signature_length is unspecified on error, but
3573 * whatever it is, it should be less than signature_size, so that
3574 * if the caller tries to read *signature_length bytes without
3575 * checking the error code then they don't overflow a buffer. */
3576 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003577
3578exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003579 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003580 mbedtls_free( signature );
3581 mbedtls_psa_crypto_free( );
3582}
3583/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003584
3585/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003586void sign_verify( int key_type_arg, data_t *key_data,
3587 int alg_arg, data_t *input_data )
3588{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003589 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003590 psa_key_type_t key_type = key_type_arg;
3591 psa_algorithm_t alg = alg_arg;
3592 size_t key_bits;
3593 unsigned char *signature = NULL;
3594 size_t signature_size;
3595 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003596 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003597 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003598
Gilles Peskine8817f612018-12-18 00:18:46 +01003599 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003600
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003601 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003602 psa_key_policy_set_usage( &policy,
3603 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
3604 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003605 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003606
Gilles Peskine87a5e562019-04-17 12:28:25 +02003607 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003608 key_data->x,
3609 key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003610 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3611 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003612
3613 /* Allocate a buffer which has the size advertized by the
3614 * library. */
3615 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3616 key_bits, alg );
3617 TEST_ASSERT( signature_size != 0 );
3618 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003619 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003620
3621 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003622 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3623 input_data->x, input_data->len,
3624 signature, signature_size,
3625 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003626 /* Check that the signature length looks sensible. */
3627 TEST_ASSERT( signature_length <= signature_size );
3628 TEST_ASSERT( signature_length > 0 );
3629
3630 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003631 PSA_ASSERT( psa_asymmetric_verify(
3632 handle, alg,
3633 input_data->x, input_data->len,
3634 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003635
3636 if( input_data->len != 0 )
3637 {
3638 /* Flip a bit in the input and verify that the signature is now
3639 * detected as invalid. Flip a bit at the beginning, not at the end,
3640 * because ECDSA may ignore the last few bits of the input. */
3641 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003642 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3643 input_data->x, input_data->len,
3644 signature, signature_length ),
3645 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003646 }
3647
3648exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003649 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003650 mbedtls_free( signature );
3651 mbedtls_psa_crypto_free( );
3652}
3653/* END_CASE */
3654
3655/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003656void asymmetric_verify( int key_type_arg, data_t *key_data,
3657 int alg_arg, data_t *hash_data,
3658 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003659{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003660 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003661 psa_key_type_t key_type = key_type_arg;
3662 psa_algorithm_t alg = alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003663 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003664
Gilles Peskine69c12672018-06-28 00:07:19 +02003665 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3666
Gilles Peskine8817f612018-12-18 00:18:46 +01003667 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003668
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003669 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003670 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003671 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
itayzafrir5c753392018-05-08 11:18:38 +03003672
Gilles Peskine87a5e562019-04-17 12:28:25 +02003673 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003674 key_data->x,
3675 key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003676
Gilles Peskine8817f612018-12-18 00:18:46 +01003677 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3678 hash_data->x, hash_data->len,
3679 signature_data->x,
3680 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003681exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003682 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003683 mbedtls_psa_crypto_free( );
3684}
3685/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003686
3687/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003688void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3689 int alg_arg, data_t *hash_data,
3690 data_t *signature_data,
3691 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003692{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003693 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003694 psa_key_type_t key_type = key_type_arg;
3695 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003696 psa_status_t actual_status;
3697 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003698 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003699
Gilles Peskine8817f612018-12-18 00:18:46 +01003700 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003701
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003702 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003703 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003704 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003705
Gilles Peskine87a5e562019-04-17 12:28:25 +02003706 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003707 key_data->x,
3708 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003709
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003710 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003711 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003712 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003713 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003714
Gilles Peskinefe11b722018-12-18 00:24:04 +01003715 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003716
3717exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003718 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003719 mbedtls_psa_crypto_free( );
3720}
3721/* END_CASE */
3722
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003723/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003724void asymmetric_encrypt( int key_type_arg,
3725 data_t *key_data,
3726 int alg_arg,
3727 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003728 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003729 int expected_output_length_arg,
3730 int expected_status_arg )
3731{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003732 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003733 psa_key_type_t key_type = key_type_arg;
3734 psa_algorithm_t alg = alg_arg;
3735 size_t expected_output_length = expected_output_length_arg;
3736 size_t key_bits;
3737 unsigned char *output = NULL;
3738 size_t output_size;
3739 size_t output_length = ~0;
3740 psa_status_t actual_status;
3741 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003742 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003743 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003744
Gilles Peskine8817f612018-12-18 00:18:46 +01003745 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003746
Gilles Peskine656896e2018-06-29 19:12:28 +02003747 /* Import the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003748 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003749 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003750 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02003751 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003752 key_data->x,
3753 key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003754
3755 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003756 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3757 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003758 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003759 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003760
3761 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003762 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003763 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003764 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003765 output, output_size,
3766 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003767 TEST_EQUAL( actual_status, expected_status );
3768 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003769
Gilles Peskine68428122018-06-30 18:42:41 +02003770 /* If the label is empty, the test framework puts a non-null pointer
3771 * in label->x. Test that a null pointer works as well. */
3772 if( label->len == 0 )
3773 {
3774 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003775 if( output_size != 0 )
3776 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003777 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003778 input_data->x, input_data->len,
3779 NULL, label->len,
3780 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 Peskine68428122018-06-30 18:42:41 +02003784 }
3785
Gilles Peskine656896e2018-06-29 19:12:28 +02003786exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003787 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003788 mbedtls_free( output );
3789 mbedtls_psa_crypto_free( );
3790}
3791/* END_CASE */
3792
3793/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003794void asymmetric_encrypt_decrypt( int key_type_arg,
3795 data_t *key_data,
3796 int alg_arg,
3797 data_t *input_data,
3798 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003799{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003800 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003801 psa_key_type_t key_type = key_type_arg;
3802 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003803 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003804 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003805 size_t output_size;
3806 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003807 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003808 size_t output2_size;
3809 size_t output2_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003810 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003811 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003812
Gilles Peskine8817f612018-12-18 00:18:46 +01003813 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003814
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003815 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003816 psa_key_policy_set_usage( &policy,
3817 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003818 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003819 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003820
Gilles Peskine87a5e562019-04-17 12:28:25 +02003821 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003822 key_data->x,
3823 key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003824
3825 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003826 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3827 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003828 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003829 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003830 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003831 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003832
Gilles Peskineeebd7382018-06-08 18:11:54 +02003833 /* We test encryption by checking that encrypt-then-decrypt gives back
3834 * the original plaintext because of the non-optional random
3835 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003836 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3837 input_data->x, input_data->len,
3838 label->x, label->len,
3839 output, output_size,
3840 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003841 /* We don't know what ciphertext length to expect, but check that
3842 * it looks sensible. */
3843 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003844
Gilles Peskine8817f612018-12-18 00:18:46 +01003845 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3846 output, output_length,
3847 label->x, label->len,
3848 output2, output2_size,
3849 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003850 ASSERT_COMPARE( input_data->x, input_data->len,
3851 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003852
3853exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003854 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003855 mbedtls_free( output );
3856 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003857 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003858}
3859/* END_CASE */
3860
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003861/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003862void asymmetric_decrypt( int key_type_arg,
3863 data_t *key_data,
3864 int alg_arg,
3865 data_t *input_data,
3866 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003867 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003868{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003869 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003870 psa_key_type_t key_type = key_type_arg;
3871 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003872 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003873 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003874 size_t output_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003875 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876
Jaeden Amero412654a2019-02-06 12:57:46 +00003877 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003878 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003879
Gilles Peskine8817f612018-12-18 00:18:46 +01003880 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003882 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003883 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003884 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003885
Gilles Peskine87a5e562019-04-17 12:28:25 +02003886 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003887 key_data->x,
3888 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003889
Gilles Peskine8817f612018-12-18 00:18:46 +01003890 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3891 input_data->x, input_data->len,
3892 label->x, label->len,
3893 output,
3894 output_size,
3895 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003896 ASSERT_COMPARE( expected_data->x, expected_data->len,
3897 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003898
Gilles Peskine68428122018-06-30 18:42:41 +02003899 /* If the label is empty, the test framework puts a non-null pointer
3900 * in label->x. Test that a null pointer works as well. */
3901 if( label->len == 0 )
3902 {
3903 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003904 if( output_size != 0 )
3905 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003906 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3907 input_data->x, input_data->len,
3908 NULL, label->len,
3909 output,
3910 output_size,
3911 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003912 ASSERT_COMPARE( expected_data->x, expected_data->len,
3913 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003914 }
3915
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003916exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003917 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003918 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003919 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003920}
3921/* END_CASE */
3922
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003923/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003924void asymmetric_decrypt_fail( int key_type_arg,
3925 data_t *key_data,
3926 int alg_arg,
3927 data_t *input_data,
3928 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003929 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003930 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003931{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003932 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003933 psa_key_type_t key_type = key_type_arg;
3934 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003935 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003936 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003937 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003938 psa_status_t actual_status;
3939 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003940 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003941
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003942 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003943
Gilles Peskine8817f612018-12-18 00:18:46 +01003944 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003945
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003946 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003947 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003948 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003949
Gilles Peskine87a5e562019-04-17 12:28:25 +02003950 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003951 key_data->x,
3952 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003953
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003954 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003955 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003956 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003957 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003958 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003959 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003960 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003961
Gilles Peskine68428122018-06-30 18:42:41 +02003962 /* If the label is empty, the test framework puts a non-null pointer
3963 * in label->x. Test that a null pointer works as well. */
3964 if( label->len == 0 )
3965 {
3966 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003967 if( output_size != 0 )
3968 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003969 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003970 input_data->x, input_data->len,
3971 NULL, label->len,
3972 output, output_size,
3973 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003974 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003975 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003976 }
3977
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003978exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003979 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003980 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003981 mbedtls_psa_crypto_free( );
3982}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003983/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003984
3985/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00003986void crypto_generator_init( )
3987{
3988 /* Test each valid way of initializing the object, except for `= {0}`, as
3989 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
3990 * though it's OK by the C standard. We could test for this, but we'd need
3991 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003992 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00003993 psa_crypto_generator_t func = psa_crypto_generator_init( );
3994 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
3995 psa_crypto_generator_t zero;
3996
3997 memset( &zero, 0, sizeof( zero ) );
3998
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003999 /* A default generator should not be able to report its capacity. */
4000 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
4001 PSA_ERROR_BAD_STATE );
4002 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
4003 PSA_ERROR_BAD_STATE );
4004 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
4005 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004006
4007 /* A default generator should be abortable without error. */
4008 PSA_ASSERT( psa_generator_abort(&func) );
4009 PSA_ASSERT( psa_generator_abort(&init) );
4010 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004011}
4012/* END_CASE */
4013
4014/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004015void derive_setup( int key_type_arg,
4016 data_t *key_data,
4017 int alg_arg,
4018 data_t *salt,
4019 data_t *label,
4020 int requested_capacity_arg,
4021 int expected_status_arg )
4022{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004023 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004024 size_t key_type = key_type_arg;
4025 psa_algorithm_t alg = alg_arg;
4026 size_t requested_capacity = requested_capacity_arg;
4027 psa_status_t expected_status = expected_status_arg;
4028 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004029 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004030
Gilles Peskine8817f612018-12-18 00:18:46 +01004031 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004032
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004033 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004034 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004035 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004036
Gilles Peskine87a5e562019-04-17 12:28:25 +02004037 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004038 key_data->x,
4039 key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004040
Gilles Peskinefe11b722018-12-18 00:24:04 +01004041 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4042 salt->x, salt->len,
4043 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004044 requested_capacity ),
4045 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004046
4047exit:
4048 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004049 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004050 mbedtls_psa_crypto_free( );
4051}
4052/* END_CASE */
4053
4054/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004055void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004056{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004057 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004058 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004059 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004060 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004061 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004062 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004063 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4064 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4065 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Jaeden Amero70261c52019-01-04 11:47:20 +00004066 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004067
Gilles Peskine8817f612018-12-18 00:18:46 +01004068 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004069
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004070 PSA_ASSERT( psa_allocate_key( &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004071 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004072 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004073
Gilles Peskine87a5e562019-04-17 12:28:25 +02004074 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004075 key_data,
4076 sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004077
4078 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004079 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4080 NULL, 0,
4081 NULL, 0,
4082 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004083
4084 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004085 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4086 NULL, 0,
4087 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004088 capacity ),
4089 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004090
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004091 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004092
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004093 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004094 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004095
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004096exit:
4097 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004098 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004099 mbedtls_psa_crypto_free( );
4100}
4101/* END_CASE */
4102
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004103/* BEGIN_CASE */
4104void test_derive_invalid_generator_tests( )
4105{
4106 uint8_t output_buffer[16];
4107 size_t buffer_size = 16;
4108 size_t capacity = 0;
4109 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4110
Nir Sonnenschein50789302018-10-31 12:16:38 +02004111 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004112 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004113
4114 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004115 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004116
Gilles Peskine8817f612018-12-18 00:18:46 +01004117 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004118
Nir Sonnenschein50789302018-10-31 12:16:38 +02004119 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004120 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004121
Nir Sonnenschein50789302018-10-31 12:16:38 +02004122 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004123 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004124
4125exit:
4126 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004127}
4128/* END_CASE */
4129
4130/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004131void derive_output( int alg_arg,
4132 data_t *key_data,
4133 data_t *salt,
4134 data_t *label,
4135 int requested_capacity_arg,
4136 data_t *expected_output1,
4137 data_t *expected_output2 )
4138{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004139 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004140 psa_algorithm_t alg = alg_arg;
4141 size_t requested_capacity = requested_capacity_arg;
4142 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4143 uint8_t *expected_outputs[2] =
4144 {expected_output1->x, expected_output2->x};
4145 size_t output_sizes[2] =
4146 {expected_output1->len, expected_output2->len};
4147 size_t output_buffer_size = 0;
4148 uint8_t *output_buffer = NULL;
4149 size_t expected_capacity;
4150 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004151 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004152 psa_status_t status;
4153 unsigned i;
4154
4155 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4156 {
4157 if( output_sizes[i] > output_buffer_size )
4158 output_buffer_size = output_sizes[i];
4159 if( output_sizes[i] == 0 )
4160 expected_outputs[i] = NULL;
4161 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004162 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004163 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004164
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004165 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4166 psa_set_key_algorithm( &attributes, alg );
4167 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004168
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004169 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004170 key_data->x,
4171 key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004172
4173 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004174 if( PSA_ALG_IS_HKDF( alg ) )
4175 {
4176 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4177 PSA_ASSERT( psa_set_generator_capacity( &generator,
4178 requested_capacity ) );
4179 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4180 PSA_KDF_STEP_SALT,
4181 salt->x, salt->len ) );
4182 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4183 PSA_KDF_STEP_SECRET,
4184 handle ) );
4185 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4186 PSA_KDF_STEP_INFO,
4187 label->x, label->len ) );
4188 }
4189 else
4190 {
4191 // legacy
4192 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4193 salt->x, salt->len,
4194 label->x, label->len,
4195 requested_capacity ) );
4196 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004197 PSA_ASSERT( psa_get_generator_capacity( &generator,
4198 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004199 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004200 expected_capacity = requested_capacity;
4201
4202 /* Expansion phase. */
4203 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4204 {
4205 /* Read some bytes. */
4206 status = psa_generator_read( &generator,
4207 output_buffer, output_sizes[i] );
4208 if( expected_capacity == 0 && output_sizes[i] == 0 )
4209 {
4210 /* Reading 0 bytes when 0 bytes are available can go either way. */
4211 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004212 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004213 continue;
4214 }
4215 else if( expected_capacity == 0 ||
4216 output_sizes[i] > expected_capacity )
4217 {
4218 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004219 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004220 expected_capacity = 0;
4221 continue;
4222 }
4223 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004224 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004225 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004226 ASSERT_COMPARE( output_buffer, output_sizes[i],
4227 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004228 /* Check the generator status. */
4229 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004230 PSA_ASSERT( psa_get_generator_capacity( &generator,
4231 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004232 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004233 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004234 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004235
4236exit:
4237 mbedtls_free( output_buffer );
4238 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004239 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004240 mbedtls_psa_crypto_free( );
4241}
4242/* END_CASE */
4243
4244/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004245void derive_full( int alg_arg,
4246 data_t *key_data,
4247 data_t *salt,
4248 data_t *label,
4249 int requested_capacity_arg )
4250{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004251 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004252 psa_algorithm_t alg = alg_arg;
4253 size_t requested_capacity = requested_capacity_arg;
4254 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4255 unsigned char output_buffer[16];
4256 size_t expected_capacity = requested_capacity;
4257 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004258 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004259
Gilles Peskine8817f612018-12-18 00:18:46 +01004260 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004261
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004262 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4263 psa_set_key_algorithm( &attributes, alg );
4264 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004265
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004266 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004267 key_data->x,
4268 key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004269
4270 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004271 if( PSA_ALG_IS_HKDF( alg ) )
4272 {
4273 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4274 PSA_ASSERT( psa_set_generator_capacity( &generator,
4275 requested_capacity ) );
4276 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4277 PSA_KDF_STEP_SALT,
4278 salt->x, salt->len ) );
4279 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4280 PSA_KDF_STEP_SECRET,
4281 handle ) );
4282 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4283 PSA_KDF_STEP_INFO,
4284 label->x, label->len ) );
4285 }
4286 else
4287 {
4288 // legacy
4289 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4290 salt->x, salt->len,
4291 label->x, label->len,
4292 requested_capacity ) );
4293 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004294 PSA_ASSERT( psa_get_generator_capacity( &generator,
4295 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004296 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004297
4298 /* Expansion phase. */
4299 while( current_capacity > 0 )
4300 {
4301 size_t read_size = sizeof( output_buffer );
4302 if( read_size > current_capacity )
4303 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004304 PSA_ASSERT( psa_generator_read( &generator,
4305 output_buffer,
4306 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004307 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004308 PSA_ASSERT( psa_get_generator_capacity( &generator,
4309 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004310 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004311 }
4312
4313 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004314 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004315 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004316
Gilles Peskine8817f612018-12-18 00:18:46 +01004317 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004318
4319exit:
4320 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004321 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004322 mbedtls_psa_crypto_free( );
4323}
4324/* END_CASE */
4325
4326/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004327void derive_key_exercise( int alg_arg,
4328 data_t *key_data,
4329 data_t *salt,
4330 data_t *label,
4331 int derived_type_arg,
4332 int derived_bits_arg,
4333 int derived_usage_arg,
4334 int derived_alg_arg )
4335{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004336 psa_key_handle_t base_handle = 0;
4337 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004338 psa_algorithm_t alg = alg_arg;
4339 psa_key_type_t derived_type = derived_type_arg;
4340 size_t derived_bits = derived_bits_arg;
4341 psa_key_usage_t derived_usage = derived_usage_arg;
4342 psa_algorithm_t derived_alg = derived_alg_arg;
4343 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4344 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004345 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004346 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004347
Gilles Peskine8817f612018-12-18 00:18:46 +01004348 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004349
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004350 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4351 psa_set_key_algorithm( &attributes, alg );
4352 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
4353 PSA_ASSERT( psa_import_key( &attributes, &base_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004354 key_data->x,
4355 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004356
4357 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004358 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4359 salt->x, salt->len,
4360 label->x, label->len,
4361 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004362 psa_set_key_usage_flags( &attributes, derived_usage );
4363 psa_set_key_algorithm( &attributes, derived_alg );
4364 psa_set_key_type( &attributes, derived_type );
4365 PSA_ASSERT( psa_generator_import_key( &attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004366 derived_bits,
4367 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004368
4369 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004370 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4371 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4372 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004373
4374 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004375 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004376 goto exit;
4377
4378exit:
4379 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004380 psa_destroy_key( base_handle );
4381 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004382 mbedtls_psa_crypto_free( );
4383}
4384/* END_CASE */
4385
4386/* BEGIN_CASE */
4387void derive_key_export( int alg_arg,
4388 data_t *key_data,
4389 data_t *salt,
4390 data_t *label,
4391 int bytes1_arg,
4392 int bytes2_arg )
4393{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004394 psa_key_handle_t base_handle = 0;
4395 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004396 psa_algorithm_t alg = alg_arg;
4397 size_t bytes1 = bytes1_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004398 size_t derived_bits = PSA_BYTES_TO_BITS( bytes1 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004399 size_t bytes2 = bytes2_arg;
4400 size_t capacity = bytes1 + bytes2;
4401 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004402 uint8_t *output_buffer = NULL;
4403 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004404 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4405 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004406 size_t length;
4407
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004408 ASSERT_ALLOC( output_buffer, capacity );
4409 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004410 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004411
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004412 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4413 psa_set_key_algorithm( &base_attributes, alg );
4414 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4415 PSA_ASSERT( psa_import_key( &base_attributes, &base_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004416 key_data->x,
4417 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004418
4419 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004420 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4421 salt->x, salt->len,
4422 label->x, label->len,
4423 capacity ) );
4424 PSA_ASSERT( psa_generator_read( &generator,
4425 output_buffer,
4426 capacity ) );
4427 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004428
4429 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004430 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4431 salt->x, salt->len,
4432 label->x, label->len,
4433 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004434 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4435 psa_set_key_algorithm( &derived_attributes, 0 );
4436 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
4437 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004438 derived_bits,
4439 &generator ) );
4440 PSA_ASSERT( psa_export_key( derived_handle,
4441 export_buffer, bytes1,
4442 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004443 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004444 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004445 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004446 PSA_BYTES_TO_BITS( bytes2 ),
4447 &generator ) );
4448 PSA_ASSERT( psa_export_key( derived_handle,
4449 export_buffer + bytes1, bytes2,
4450 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004451 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004452
4453 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004454 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4455 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004456
4457exit:
4458 mbedtls_free( output_buffer );
4459 mbedtls_free( export_buffer );
4460 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004461 psa_destroy_key( base_handle );
4462 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004463 mbedtls_psa_crypto_free( );
4464}
4465/* END_CASE */
4466
4467/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004468void key_agreement_setup( int alg_arg,
4469 int our_key_type_arg, data_t *our_key_data,
4470 data_t *peer_key_data,
4471 int expected_status_arg )
4472{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004473 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004474 psa_algorithm_t alg = alg_arg;
4475 psa_key_type_t our_key_type = our_key_type_arg;
4476 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004477 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004478 psa_status_t expected_status = expected_status_arg;
4479 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004480
Gilles Peskine8817f612018-12-18 00:18:46 +01004481 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004482
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004483 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4484 psa_set_key_algorithm( &attributes, alg );
4485 psa_set_key_type( &attributes, our_key_type );
4486 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004487 our_key_data->x,
4488 our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004489
Gilles Peskine77f40d82019-04-11 21:27:06 +02004490 /* The tests currently include inputs that should fail at either step.
4491 * Test cases that fail at the setup step should be changed to call
4492 * key_derivation_setup instead, and this function should be renamed
4493 * to key_agreement_fail. */
4494 status = psa_key_derivation_setup( &generator, alg );
4495 if( status == PSA_SUCCESS )
4496 {
4497 TEST_EQUAL( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
4498 our_key,
4499 peer_key_data->x, peer_key_data->len ),
4500 expected_status );
4501 }
4502 else
4503 {
4504 TEST_ASSERT( status == expected_status );
4505 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004506
4507exit:
4508 psa_generator_abort( &generator );
4509 psa_destroy_key( our_key );
4510 mbedtls_psa_crypto_free( );
4511}
4512/* END_CASE */
4513
4514/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004515void raw_key_agreement( int alg_arg,
4516 int our_key_type_arg, data_t *our_key_data,
4517 data_t *peer_key_data,
4518 data_t *expected_output )
4519{
4520 psa_key_handle_t our_key = 0;
4521 psa_algorithm_t alg = alg_arg;
4522 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004523 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004524 unsigned char *output = NULL;
4525 size_t output_length = ~0;
4526
4527 ASSERT_ALLOC( output, expected_output->len );
4528 PSA_ASSERT( psa_crypto_init( ) );
4529
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004530 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4531 psa_set_key_algorithm( &attributes, alg );
4532 psa_set_key_type( &attributes, our_key_type );
4533 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskinef0cba732019-04-11 22:12:38 +02004534 our_key_data->x,
4535 our_key_data->len ) );
4536
4537 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4538 alg, our_key,
4539 peer_key_data->x, peer_key_data->len,
4540 output, expected_output->len, &output_length ) );
4541 ASSERT_COMPARE( output, output_length,
4542 expected_output->x, expected_output->len );
4543
4544exit:
4545 mbedtls_free( output );
4546 psa_destroy_key( our_key );
4547 mbedtls_psa_crypto_free( );
4548}
4549/* END_CASE */
4550
4551/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004552void key_agreement_capacity( int alg_arg,
4553 int our_key_type_arg, data_t *our_key_data,
4554 data_t *peer_key_data,
4555 int expected_capacity_arg )
4556{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004557 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004558 psa_algorithm_t alg = alg_arg;
4559 psa_key_type_t our_key_type = our_key_type_arg;
4560 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004561 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004562 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004563 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004564
Gilles Peskine8817f612018-12-18 00:18:46 +01004565 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004566
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004567 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4568 psa_set_key_algorithm( &attributes, alg );
4569 psa_set_key_type( &attributes, our_key_type );
4570 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004571 our_key_data->x,
4572 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004573
Gilles Peskine969c5d62019-01-16 15:53:06 +01004574 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4575 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004576 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004577 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004578 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4579 {
4580 /* The test data is for info="" */
4581 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4582 PSA_KDF_STEP_INFO,
4583 NULL, 0 ) );
4584 }
Gilles Peskine59685592018-09-18 12:11:34 +02004585
Gilles Peskinebf491972018-10-25 22:36:12 +02004586 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004587 PSA_ASSERT( psa_get_generator_capacity(
4588 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004589 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004590
Gilles Peskinebf491972018-10-25 22:36:12 +02004591 /* Test the actual capacity by reading the output. */
4592 while( actual_capacity > sizeof( output ) )
4593 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004594 PSA_ASSERT( psa_generator_read( &generator,
4595 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004596 actual_capacity -= sizeof( output );
4597 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004598 PSA_ASSERT( psa_generator_read( &generator,
4599 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004600 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004601 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004602
Gilles Peskine59685592018-09-18 12:11:34 +02004603exit:
4604 psa_generator_abort( &generator );
4605 psa_destroy_key( our_key );
4606 mbedtls_psa_crypto_free( );
4607}
4608/* END_CASE */
4609
4610/* BEGIN_CASE */
4611void key_agreement_output( int alg_arg,
4612 int our_key_type_arg, data_t *our_key_data,
4613 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004614 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004615{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004616 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004617 psa_algorithm_t alg = alg_arg;
4618 psa_key_type_t our_key_type = our_key_type_arg;
4619 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004620 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004621 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004622
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004623 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4624 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004625
Gilles Peskine8817f612018-12-18 00:18:46 +01004626 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004627
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004628 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4629 psa_set_key_algorithm( &attributes, alg );
4630 psa_set_key_type( &attributes, our_key_type );
4631 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004632 our_key_data->x,
4633 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004634
Gilles Peskine969c5d62019-01-16 15:53:06 +01004635 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4636 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004637 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004638 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004639 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4640 {
4641 /* The test data is for info="" */
4642 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4643 PSA_KDF_STEP_INFO,
4644 NULL, 0 ) );
4645 }
Gilles Peskine59685592018-09-18 12:11:34 +02004646
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004647 PSA_ASSERT( psa_generator_read( &generator,
4648 actual_output,
4649 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004650 ASSERT_COMPARE( actual_output, expected_output1->len,
4651 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004652 if( expected_output2->len != 0 )
4653 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004654 PSA_ASSERT( psa_generator_read( &generator,
4655 actual_output,
4656 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004657 ASSERT_COMPARE( actual_output, expected_output2->len,
4658 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004659 }
Gilles Peskine59685592018-09-18 12:11:34 +02004660
4661exit:
4662 psa_generator_abort( &generator );
4663 psa_destroy_key( our_key );
4664 mbedtls_psa_crypto_free( );
4665 mbedtls_free( actual_output );
4666}
4667/* END_CASE */
4668
4669/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004670void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004671{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004672 size_t bytes = bytes_arg;
4673 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004674 unsigned char *output = NULL;
4675 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004676 size_t i;
4677 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004678
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004679 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4680 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004681 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004682
Gilles Peskine8817f612018-12-18 00:18:46 +01004683 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004684
Gilles Peskinea50d7392018-06-21 10:22:13 +02004685 /* Run several times, to ensure that every output byte will be
4686 * nonzero at least once with overwhelming probability
4687 * (2^(-8*number_of_runs)). */
4688 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004689 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004690 if( bytes != 0 )
4691 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004692 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004693
4694 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004695 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4696 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004697
4698 for( i = 0; i < bytes; i++ )
4699 {
4700 if( output[i] != 0 )
4701 ++changed[i];
4702 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004703 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004704
4705 /* Check that every byte was changed to nonzero at least once. This
4706 * validates that psa_generate_random is overwriting every byte of
4707 * the output buffer. */
4708 for( i = 0; i < bytes; i++ )
4709 {
4710 TEST_ASSERT( changed[i] != 0 );
4711 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004712
4713exit:
4714 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004715 mbedtls_free( output );
4716 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004717}
4718/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004719
4720/* BEGIN_CASE */
4721void generate_key( int type_arg,
4722 int bits_arg,
4723 int usage_arg,
4724 int alg_arg,
4725 int expected_status_arg )
4726{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004727 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004728 psa_key_type_t type = type_arg;
4729 psa_key_usage_t usage = usage_arg;
4730 size_t bits = bits_arg;
4731 psa_algorithm_t alg = alg_arg;
4732 psa_status_t expected_status = expected_status_arg;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004733 psa_status_t expected_info_status =
David Saadab4ecc272019-02-14 13:48:10 +02004734 expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004735 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004736 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004737
Gilles Peskine8817f612018-12-18 00:18:46 +01004738 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004739
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004740 psa_set_key_usage_flags( &attributes, usage );
4741 psa_set_key_algorithm( &attributes, alg );
4742 psa_set_key_type( &attributes, type );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004743
4744 /* Generate a key */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004745 TEST_EQUAL( psa_generate_key( &attributes, &handle, bits, NULL, 0 ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004746 expected_status );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004747 if( expected_info_status != PSA_SUCCESS )
4748 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004749
4750 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004751 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4752 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4753 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004754
Gilles Peskine818ca122018-06-20 18:16:48 +02004755 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004756 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004757 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004758
4759exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004760 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004761 mbedtls_psa_crypto_free( );
4762}
4763/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004764
Darryl Greend49a4992018-06-18 17:27:26 +01004765/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
4766void persistent_key_load_key_from_storage( data_t *data, int type_arg,
4767 int bits, int usage_arg,
Darryl Green0c6575a2018-11-07 16:05:30 +00004768 int alg_arg, int generation_method,
4769 int export_status )
Darryl Greend49a4992018-06-18 17:27:26 +01004770{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004771 psa_key_handle_t handle = 0;
4772 psa_key_handle_t base_key;
Darryl Greend49a4992018-06-18 17:27:26 +01004773 psa_key_type_t type = (psa_key_type_t) type_arg;
4774 psa_key_type_t type_get;
4775 size_t bits_get;
Jaeden Amero70261c52019-01-04 11:47:20 +00004776 psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT;
4777 psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004778 psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg;
4779 psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00004780 psa_key_policy_t base_policy_set = PSA_KEY_POLICY_INIT;
Darryl Green0c6575a2018-11-07 16:05:30 +00004781 psa_algorithm_t base_policy_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
4782 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004783 unsigned char *first_export = NULL;
4784 unsigned char *second_export = NULL;
4785 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4786 size_t first_exported_length;
4787 size_t second_exported_length;
4788
4789 ASSERT_ALLOC( first_export, export_size );
4790 ASSERT_ALLOC( second_export, export_size );
4791
Gilles Peskine8817f612018-12-18 00:18:46 +01004792 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004793
Gilles Peskine8817f612018-12-18 00:18:46 +01004794 PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
Gilles Peskine8817f612018-12-18 00:18:46 +01004795 &handle ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004796 psa_key_policy_set_usage( &policy_set, policy_usage,
4797 policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004798 PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004799
Darryl Green0c6575a2018-11-07 16:05:30 +00004800 switch( generation_method )
4801 {
4802 case IMPORT_KEY:
4803 /* Import the key */
Gilles Peskine87a5e562019-04-17 12:28:25 +02004804 PSA_ASSERT( psa_import_key_to_handle( handle, type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004805 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004806 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004807
Darryl Green0c6575a2018-11-07 16:05:30 +00004808 case GENERATE_KEY:
4809 /* Generate a key */
Gilles Peskine87a5e562019-04-17 12:28:25 +02004810 PSA_ASSERT( psa_generate_key_to_handle( handle, type, bits,
Gilles Peskine8817f612018-12-18 00:18:46 +01004811 NULL, 0 ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004812 break;
4813
4814 case DERIVE_KEY:
4815 /* Create base key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004816 PSA_ASSERT( psa_allocate_key( &base_key ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004817 psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE,
4818 base_policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004819 PSA_ASSERT( psa_set_key_policy(
4820 base_key, &base_policy_set ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02004821 PSA_ASSERT( psa_import_key_to_handle( base_key, PSA_KEY_TYPE_DERIVE,
Gilles Peskine8817f612018-12-18 00:18:46 +01004822 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004823 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004824 PSA_ASSERT( psa_key_derivation( &generator, base_key,
4825 base_policy_alg,
4826 NULL, 0, NULL, 0,
4827 export_size ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02004828 PSA_ASSERT( psa_generator_import_key_to_handle(
Gilles Peskine8817f612018-12-18 00:18:46 +01004829 handle, PSA_KEY_TYPE_RAW_DATA,
4830 bits, &generator ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004831 break;
4832 }
Darryl Greend49a4992018-06-18 17:27:26 +01004833
4834 /* Export the key */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004835 TEST_EQUAL( psa_export_key( handle,
4836 first_export, export_size,
4837 &first_exported_length ),
4838 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004839
4840 /* Shutdown and restart */
4841 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004842 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004843
Darryl Greend49a4992018-06-18 17:27:26 +01004844 /* Check key slot still contains key data */
Gilles Peskine8817f612018-12-18 00:18:46 +01004845 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
4846 &handle ) );
4847 PSA_ASSERT( psa_get_key_information(
4848 handle, &type_get, &bits_get ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004849 TEST_EQUAL( type_get, type );
4850 TEST_EQUAL( bits_get, (size_t) bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004851
Gilles Peskine8817f612018-12-18 00:18:46 +01004852 PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004853 TEST_EQUAL( psa_key_policy_get_usage( &policy_get ), policy_usage );
4854 TEST_EQUAL( psa_key_policy_get_algorithm( &policy_get ), policy_alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004855
4856 /* Export the key again */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004857 TEST_EQUAL( psa_export_key( handle,
4858 second_export, export_size,
4859 &second_exported_length ),
4860 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004861
Darryl Green0c6575a2018-11-07 16:05:30 +00004862 if( export_status == PSA_SUCCESS )
4863 {
4864 ASSERT_COMPARE( first_export, first_exported_length,
4865 second_export, second_exported_length );
Darryl Greend49a4992018-06-18 17:27:26 +01004866
Darryl Green0c6575a2018-11-07 16:05:30 +00004867 switch( generation_method )
4868 {
4869 case IMPORT_KEY:
4870 ASSERT_COMPARE( data->x, data->len,
4871 first_export, first_exported_length );
4872 break;
4873 default:
4874 break;
4875 }
4876 }
4877
4878 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004879 if( ! exercise_key( handle, policy_usage, policy_alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004880 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004881
4882exit:
4883 mbedtls_free( first_export );
4884 mbedtls_free( second_export );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004885 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004886 mbedtls_psa_crypto_free();
4887}
4888/* END_CASE */