blob: 1d67c6d613c5a7afb6faed80379419626bbaf843 [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;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100215
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200216 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
217 psa_set_key_algorithm( &attributes, alg );
218 psa_set_key_type( &attributes, key_type );
219 PSA_ASSERT( psa_import_key( &attributes, &handle, 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;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200248 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100249
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200250 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
251 psa_set_key_algorithm( &attributes, alg );
252 psa_set_key_type( &attributes, key_type );
253 PSA_ASSERT( psa_import_key( &attributes, &handle, 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 Peskine4cf3a432019-04-18 22:28:52 +02001087static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1088{
1089 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1090 uint8_t buffer[1];
1091 size_t length;
1092 int ok = 0;
1093
1094 psa_make_key_persistent( &attributes, 0x6964, PSA_KEY_LIFETIME_PERSISTENT );
1095 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1096 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1097 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1098 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1099 PSA_ERROR_INVALID_HANDLE );
1100 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001101 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001102 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1103 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1104 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1105 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1106
1107 TEST_EQUAL( psa_export_key( handle,
1108 buffer, sizeof( buffer ), &length ),
1109 PSA_ERROR_INVALID_HANDLE );
1110 TEST_EQUAL( psa_export_public_key( handle,
1111 buffer, sizeof( buffer ), &length ),
1112 PSA_ERROR_INVALID_HANDLE );
1113
1114 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1115 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1116
1117 ok = 1;
1118
1119exit:
1120 psa_reset_key_attributes( &attributes );
1121 return( ok );
1122}
1123
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001124/* An overapproximation of the amount of storage needed for a key of the
1125 * given type and with the given content. The API doesn't make it easy
1126 * to find a good value for the size. The current implementation doesn't
1127 * care about the value anyway. */
1128#define KEY_BITS_FROM_DATA( type, data ) \
1129 ( data )->len
1130
Darryl Green0c6575a2018-11-07 16:05:30 +00001131typedef enum {
1132 IMPORT_KEY = 0,
1133 GENERATE_KEY = 1,
1134 DERIVE_KEY = 2
1135} generate_method;
1136
Gilles Peskinee59236f2018-01-27 23:32:46 +01001137/* END_HEADER */
1138
1139/* BEGIN_DEPENDENCIES
1140 * depends_on:MBEDTLS_PSA_CRYPTO_C
1141 * END_DEPENDENCIES
1142 */
1143
1144/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001145void static_checks( )
1146{
1147 size_t max_truncated_mac_size =
1148 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1149
1150 /* Check that the length for a truncated MAC always fits in the algorithm
1151 * encoding. The shifted mask is the maximum truncated value. The
1152 * untruncated algorithm may be one byte larger. */
1153 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1154}
1155/* END_CASE */
1156
1157/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001158void attributes_set_get( int id_arg, int lifetime_arg,
1159 int usage_flags_arg, int alg_arg,
1160 int type_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001161{
Gilles Peskine4747d192019-04-17 15:05:45 +02001162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001163 psa_key_id_t id = id_arg;
1164 psa_key_lifetime_t lifetime = lifetime_arg;
1165 psa_key_usage_t usage_flags = usage_flags_arg;
1166 psa_algorithm_t alg = alg_arg;
1167 psa_key_type_t type = type_arg;
1168
1169 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1170 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1171 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1172 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1173 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1174
1175 psa_make_key_persistent( &attributes, id, lifetime );
1176 psa_set_key_usage_flags( &attributes, usage_flags );
1177 psa_set_key_algorithm( &attributes, alg );
1178 psa_set_key_type( &attributes, type );
1179
1180 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1181 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1182 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1183 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1184 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1185
1186 psa_reset_key_attributes( &attributes );
1187
1188 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1189 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1190 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1191 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1192 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1193}
1194/* END_CASE */
1195
1196/* BEGIN_CASE */
1197void import( data_t *data, int type_arg, int expected_status_arg )
1198{
1199 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1200 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001201 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001202 psa_key_type_t type = type_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001203 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001204 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001205
Gilles Peskine8817f612018-12-18 00:18:46 +01001206 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001207
Gilles Peskine4747d192019-04-17 15:05:45 +02001208 psa_set_key_type( &attributes, type );
1209 status = psa_import_key( &attributes, &handle, data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001210 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001211 if( status != PSA_SUCCESS )
1212 goto exit;
1213
1214 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1215 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1216
1217 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001218 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001219
1220exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001221 psa_destroy_key( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001222 mbedtls_psa_crypto_free( );
1223}
1224/* END_CASE */
1225
1226/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001227void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1228{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001229 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001230 size_t bits = bits_arg;
1231 psa_status_t expected_status = expected_status_arg;
1232 psa_status_t status;
1233 psa_key_type_t type =
1234 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1235 size_t buffer_size = /* Slight overapproximations */
1236 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001237 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001238 unsigned char *p;
1239 int ret;
1240 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001241 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001242
Gilles Peskine8817f612018-12-18 00:18:46 +01001243 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001244 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001245
1246 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1247 bits, keypair ) ) >= 0 );
1248 length = ret;
1249
1250 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001251 psa_set_key_type( &attributes, type );
1252 status = psa_import_key( &attributes, &handle, p, length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001253 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001254 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001255 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001256
1257exit:
1258 mbedtls_free( buffer );
1259 mbedtls_psa_crypto_free( );
1260}
1261/* END_CASE */
1262
1263/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001264void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001265 int type_arg,
1266 int alg_arg,
1267 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001268 int expected_bits,
1269 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001270 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001271 int canonical_input )
1272{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001273 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001274 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001275 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001276 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001277 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001278 unsigned char *exported = NULL;
1279 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001280 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001281 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001282 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001283 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001284 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001285
Moran Pekercb088e72018-07-17 17:36:59 +03001286 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001287 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001288 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001289 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001290 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001291
Gilles Peskine4747d192019-04-17 15:05:45 +02001292 psa_set_key_usage_flags( &attributes, usage_arg );
1293 psa_set_key_algorithm( &attributes, alg );
1294 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001295
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001296 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001297 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001298
1299 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001300 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1301 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1302 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001303
1304 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001305 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001306 exported, export_size,
1307 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001308 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001309
1310 /* The exported length must be set by psa_export_key() to a value between 0
1311 * and export_size. On errors, the exported length must be 0. */
1312 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1313 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1314 TEST_ASSERT( exported_length <= export_size );
1315
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001316 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001317 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001318 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001319 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001320 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001321 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001322 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001323
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001324 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001325 goto exit;
1326
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001327 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001328 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001329 else
1330 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001331 psa_key_handle_t handle2;
Gilles Peskine4747d192019-04-17 15:05:45 +02001332 PSA_ASSERT( psa_import_key( &attributes, &handle2,
1333 exported, exported_length ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001334 PSA_ASSERT( psa_export_key( handle2,
1335 reexported,
1336 export_size,
1337 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001338 ASSERT_COMPARE( exported, exported_length,
1339 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001340 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001341 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001342 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001343
1344destroy:
1345 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001346 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001347 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001348
1349exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001350 mbedtls_free( exported );
1351 mbedtls_free( reexported );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001352 mbedtls_psa_crypto_free( );
1353}
1354/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001355
Moran Pekerf709f4a2018-06-06 17:26:04 +03001356/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001357void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001358{
Gilles Peskine8817f612018-12-18 00:18:46 +01001359 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001360 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001361
1362exit:
1363 mbedtls_psa_crypto_free( );
1364}
1365/* END_CASE */
1366
1367/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001368void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001369 int type_arg,
1370 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001371 int export_size_delta,
1372 int expected_export_status_arg,
1373 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001374{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001375 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001376 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001377 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001378 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001379 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001380 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001381 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001382 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001383 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001384
Gilles Peskine8817f612018-12-18 00:18:46 +01001385 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001386
Gilles Peskine4747d192019-04-17 15:05:45 +02001387 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1388 psa_set_key_algorithm( &attributes, alg );
1389 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001390
1391 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001392 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001393
Gilles Peskine49c25912018-10-29 15:15:31 +01001394 /* Export the public key */
1395 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001396 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001397 exported, export_size,
1398 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001399 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001400 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001401 {
1402 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1403 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001404 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1405 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001406 TEST_ASSERT( expected_public_key->len <=
1407 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001408 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1409 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001410 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001411
1412exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001413 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001414 psa_destroy_key( handle );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001415 mbedtls_psa_crypto_free( );
1416}
1417/* END_CASE */
1418
Gilles Peskine20035e32018-02-03 22:44:14 +01001419/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001420void import_and_exercise_key( data_t *data,
1421 int type_arg,
1422 int bits_arg,
1423 int alg_arg )
1424{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001425 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001426 psa_key_type_t type = type_arg;
1427 size_t bits = bits_arg;
1428 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001429 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001430 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001431 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001432
Gilles Peskine8817f612018-12-18 00:18:46 +01001433 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001434
Gilles Peskine4747d192019-04-17 15:05:45 +02001435 psa_set_key_usage_flags( &attributes, usage );
1436 psa_set_key_algorithm( &attributes, alg );
1437 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001438
1439 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001440 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001441
1442 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001443 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1444 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1445 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001446
1447 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001448 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001449 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001450
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001451 PSA_ASSERT( psa_destroy_key( handle ) );
1452 test_operations_on_invalid_handle( handle );
1453
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001454exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001455 psa_destroy_key( handle );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001456 mbedtls_psa_crypto_free( );
1457}
1458/* END_CASE */
1459
1460/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001461void key_policy( int usage_arg, int alg_arg )
1462{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001463 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001464 psa_algorithm_t alg = alg_arg;
1465 psa_key_usage_t usage = usage_arg;
1466 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1467 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001468 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001469
1470 memset( key, 0x2a, sizeof( key ) );
1471
Gilles Peskine8817f612018-12-18 00:18:46 +01001472 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001473
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001474 psa_set_key_usage_flags( &attributes, usage );
1475 psa_set_key_algorithm( &attributes, alg );
1476 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001477
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001478 PSA_ASSERT( psa_import_key( &attributes, &handle, key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001479
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001480 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1481 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1482 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1483 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001484
1485exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001486 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001487 mbedtls_psa_crypto_free( );
1488}
1489/* END_CASE */
1490
1491/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001492void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001493{
1494 /* Test each valid way of initializing the object, except for `= {0}`, as
1495 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1496 * though it's OK by the C standard. We could test for this, but we'd need
1497 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001498 psa_key_attributes_t func = psa_key_attributes_init( );
1499 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1500 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001501
1502 memset( &zero, 0, sizeof( zero ) );
1503
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001504 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1505 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1506 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001507
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001508 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1509 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1510 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1511
1512 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1513 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1514 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1515
1516 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1517 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1518 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1519
1520 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1521 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1522 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001523}
1524/* END_CASE */
1525
1526/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001527void mac_key_policy( int policy_usage,
1528 int policy_alg,
1529 int key_type,
1530 data_t *key_data,
1531 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001532{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001533 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001534 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001535 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001536 psa_status_t status;
1537 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001538
Gilles Peskine8817f612018-12-18 00:18:46 +01001539 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001540
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001541 psa_set_key_usage_flags( &attributes, policy_usage );
1542 psa_set_key_algorithm( &attributes, policy_alg );
1543 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001544
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001545 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001546 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001547
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001548 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001549 if( policy_alg == exercise_alg &&
1550 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001551 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001552 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001553 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001554 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001555
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001556 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001557 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001558 if( policy_alg == exercise_alg &&
1559 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001560 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001561 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001562 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001563
1564exit:
1565 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001566 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001567 mbedtls_psa_crypto_free( );
1568}
1569/* END_CASE */
1570
1571/* BEGIN_CASE */
1572void cipher_key_policy( int policy_usage,
1573 int policy_alg,
1574 int key_type,
1575 data_t *key_data,
1576 int exercise_alg )
1577{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001578 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001579 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001580 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001581 psa_status_t status;
1582
Gilles Peskine8817f612018-12-18 00:18:46 +01001583 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001584
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001585 psa_set_key_usage_flags( &attributes, policy_usage );
1586 psa_set_key_algorithm( &attributes, policy_alg );
1587 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001588
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001589 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001590 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001591
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001592 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001593 if( policy_alg == exercise_alg &&
1594 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001595 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001596 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001597 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001598 psa_cipher_abort( &operation );
1599
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001600 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001601 if( policy_alg == exercise_alg &&
1602 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001603 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001604 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001605 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001606
1607exit:
1608 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001609 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001610 mbedtls_psa_crypto_free( );
1611}
1612/* END_CASE */
1613
1614/* BEGIN_CASE */
1615void aead_key_policy( int policy_usage,
1616 int policy_alg,
1617 int key_type,
1618 data_t *key_data,
1619 int nonce_length_arg,
1620 int tag_length_arg,
1621 int exercise_alg )
1622{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001623 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001624 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001625 psa_status_t status;
1626 unsigned char nonce[16] = {0};
1627 size_t nonce_length = nonce_length_arg;
1628 unsigned char tag[16];
1629 size_t tag_length = tag_length_arg;
1630 size_t output_length;
1631
1632 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1633 TEST_ASSERT( tag_length <= sizeof( tag ) );
1634
Gilles Peskine8817f612018-12-18 00:18:46 +01001635 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001636
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001637 psa_set_key_usage_flags( &attributes, policy_usage );
1638 psa_set_key_algorithm( &attributes, policy_alg );
1639 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001640
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001641 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001642 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001643
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001644 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001645 nonce, nonce_length,
1646 NULL, 0,
1647 NULL, 0,
1648 tag, tag_length,
1649 &output_length );
1650 if( policy_alg == exercise_alg &&
1651 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001652 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001653 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001654 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001655
1656 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001657 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001658 nonce, nonce_length,
1659 NULL, 0,
1660 tag, tag_length,
1661 NULL, 0,
1662 &output_length );
1663 if( policy_alg == exercise_alg &&
1664 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001665 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001666 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001667 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001668
1669exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001670 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001671 mbedtls_psa_crypto_free( );
1672}
1673/* END_CASE */
1674
1675/* BEGIN_CASE */
1676void asymmetric_encryption_key_policy( int policy_usage,
1677 int policy_alg,
1678 int key_type,
1679 data_t *key_data,
1680 int exercise_alg )
1681{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001682 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001683 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001684 psa_status_t status;
1685 size_t key_bits;
1686 size_t buffer_length;
1687 unsigned char *buffer = NULL;
1688 size_t output_length;
1689
Gilles Peskine8817f612018-12-18 00:18:46 +01001690 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001691
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001692 psa_set_key_usage_flags( &attributes, policy_usage );
1693 psa_set_key_algorithm( &attributes, policy_alg );
1694 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001695
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001696 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001697 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001698
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001699 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1700 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001701 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1702 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001703 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001704
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001705 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001706 NULL, 0,
1707 NULL, 0,
1708 buffer, buffer_length,
1709 &output_length );
1710 if( policy_alg == exercise_alg &&
1711 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001712 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001713 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001714 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001715
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001716 if( buffer_length != 0 )
1717 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001718 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001719 buffer, buffer_length,
1720 NULL, 0,
1721 buffer, buffer_length,
1722 &output_length );
1723 if( policy_alg == exercise_alg &&
1724 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001725 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001726 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001727 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001728
1729exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001730 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001731 mbedtls_psa_crypto_free( );
1732 mbedtls_free( buffer );
1733}
1734/* END_CASE */
1735
1736/* BEGIN_CASE */
1737void asymmetric_signature_key_policy( int policy_usage,
1738 int policy_alg,
1739 int key_type,
1740 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001741 int exercise_alg,
1742 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001743{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001744 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001745 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001746 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001747 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1748 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1749 * compatible with the policy and `payload_length_arg` is supposed to be
1750 * a valid input length to sign. If `payload_length_arg <= 0`,
1751 * `exercise_alg` is supposed to be forbidden by the policy. */
1752 int compatible_alg = payload_length_arg > 0;
1753 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001754 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1755 size_t signature_length;
1756
Gilles Peskine8817f612018-12-18 00:18:46 +01001757 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001759 psa_set_key_usage_flags( &attributes, policy_usage );
1760 psa_set_key_algorithm( &attributes, policy_alg );
1761 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001763 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001764 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001765
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001766 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001768 signature, sizeof( signature ),
1769 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001770 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001771 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001772 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001773 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001774
1775 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001776 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001777 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001778 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001779 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001780 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001781 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001782 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001783
1784exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001785 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001786 mbedtls_psa_crypto_free( );
1787}
1788/* END_CASE */
1789
1790/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001791void derive_key_policy( int policy_usage,
1792 int policy_alg,
1793 int key_type,
1794 data_t *key_data,
1795 int exercise_alg )
1796{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001797 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001798 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001799 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1800 psa_status_t status;
1801
Gilles Peskine8817f612018-12-18 00:18:46 +01001802 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001803
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001804 psa_set_key_usage_flags( &attributes, policy_usage );
1805 psa_set_key_algorithm( &attributes, policy_alg );
1806 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001807
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001808 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001809 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001810
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001811 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001812 exercise_alg,
1813 NULL, 0,
1814 NULL, 0,
1815 1 );
1816 if( policy_alg == exercise_alg &&
1817 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001818 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001819 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001820 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001821
1822exit:
1823 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001824 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001825 mbedtls_psa_crypto_free( );
1826}
1827/* END_CASE */
1828
1829/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001830void agreement_key_policy( int policy_usage,
1831 int policy_alg,
1832 int key_type_arg,
1833 data_t *key_data,
1834 int exercise_alg )
1835{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001836 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001837 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001838 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001839 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1840 psa_status_t status;
1841
Gilles Peskine8817f612018-12-18 00:18:46 +01001842 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001843
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001844 psa_set_key_usage_flags( &attributes, policy_usage );
1845 psa_set_key_algorithm( &attributes, policy_alg );
1846 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001847
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001848 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001849 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001850
Gilles Peskine969c5d62019-01-16 15:53:06 +01001851 PSA_ASSERT( psa_key_derivation_setup( &generator, exercise_alg ) );
1852 status = key_agreement_with_self( &generator, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001853
Gilles Peskine01d718c2018-09-18 12:01:02 +02001854 if( policy_alg == exercise_alg &&
1855 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001856 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001857 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001858 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001859
1860exit:
1861 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001862 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001863 mbedtls_psa_crypto_free( );
1864}
1865/* END_CASE */
1866
1867/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001868void raw_agreement_key_policy( int policy_usage,
1869 int policy_alg,
1870 int key_type_arg,
1871 data_t *key_data,
1872 int exercise_alg )
1873{
1874 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001875 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001876 psa_key_type_t key_type = key_type_arg;
1877 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1878 psa_status_t status;
1879
1880 PSA_ASSERT( psa_crypto_init( ) );
1881
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001882 psa_set_key_usage_flags( &attributes, policy_usage );
1883 psa_set_key_algorithm( &attributes, policy_alg );
1884 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001885
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001886 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001887 key_data->x, key_data->len ) );
1888
1889 status = raw_key_agreement_with_self( exercise_alg, handle );
1890
1891 if( policy_alg == exercise_alg &&
1892 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1893 PSA_ASSERT( status );
1894 else
1895 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1896
1897exit:
1898 psa_generator_abort( &generator );
1899 psa_destroy_key( handle );
1900 mbedtls_psa_crypto_free( );
1901}
1902/* END_CASE */
1903
1904/* BEGIN_CASE */
Gilles Peskineca25db92019-04-19 11:43:08 +02001905void copy_key( int source_usage_arg, int source_alg_arg,
1906 int type_arg, data_t *material,
1907 int copy_attributes,
1908 int target_usage_arg, int target_alg_arg,
1909 int expected_status_arg,
1910 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001911{
Gilles Peskineca25db92019-04-19 11:43:08 +02001912 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1913 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001914 psa_key_usage_t expected_usage = expected_usage_arg;
1915 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001916 psa_key_handle_t source_handle = 0;
1917 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001918 uint8_t *export_buffer = NULL;
1919
Gilles Peskine57ab7212019-01-28 13:03:09 +01001920 PSA_ASSERT( psa_crypto_init( ) );
1921
Gilles Peskineca25db92019-04-19 11:43:08 +02001922 /* Prepare the source key. */
1923 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1924 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1925 psa_set_key_type( &source_attributes, type_arg );
1926 PSA_ASSERT( psa_import_key( &source_attributes, &source_handle,
Gilles Peskine57ab7212019-01-28 13:03:09 +01001927 material->x, material->len ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001928 /* Retrieve the key size. */
1929 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001930
Gilles Peskineca25db92019-04-19 11:43:08 +02001931 /* Prepare the target attributes. */
1932 if( copy_attributes )
1933 target_attributes = source_attributes;
1934 if( target_usage_arg != -1 )
1935 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1936 if( target_alg_arg != -1 )
1937 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001938
1939 /* Copy the key. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001940 TEST_EQUAL( psa_copy_key( source_handle,
1941 &target_attributes, &target_handle ),
1942 expected_status_arg );
1943 if( expected_status_arg != PSA_SUCCESS )
1944 {
1945 TEST_EQUAL( target_handle, 0 );
1946 goto exit;
1947 }
Gilles Peskine57ab7212019-01-28 13:03:09 +01001948
1949 /* Destroy the source to ensure that this doesn't affect the target. */
1950 PSA_ASSERT( psa_destroy_key( source_handle ) );
1951
1952 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001953 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1954 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1955 psa_get_key_type( &target_attributes ) );
1956 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1957 psa_get_key_bits( &target_attributes ) );
1958 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
1959 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001960 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1961 {
1962 size_t length;
1963 ASSERT_ALLOC( export_buffer, material->len );
1964 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1965 material->len, &length ) );
1966 ASSERT_COMPARE( material->x, material->len,
1967 export_buffer, length );
1968 }
1969 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1970 goto exit;
1971
1972 PSA_ASSERT( psa_close_key( target_handle ) );
1973
1974exit:
1975 mbedtls_psa_crypto_free( );
1976 mbedtls_free( export_buffer );
1977}
1978/* END_CASE */
1979
1980/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00001981void hash_operation_init( )
1982{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00001983 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00001984 /* Test each valid way of initializing the object, except for `= {0}`, as
1985 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1986 * though it's OK by the C standard. We could test for this, but we'd need
1987 * to supress the Clang warning for the test. */
1988 psa_hash_operation_t func = psa_hash_operation_init( );
1989 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
1990 psa_hash_operation_t zero;
1991
1992 memset( &zero, 0, sizeof( zero ) );
1993
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00001994 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00001995 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
1996 PSA_ERROR_BAD_STATE );
1997 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
1998 PSA_ERROR_BAD_STATE );
1999 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2000 PSA_ERROR_BAD_STATE );
2001
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002002 /* A default hash operation should be abortable without error. */
2003 PSA_ASSERT( psa_hash_abort( &func ) );
2004 PSA_ASSERT( psa_hash_abort( &init ) );
2005 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002006}
2007/* END_CASE */
2008
2009/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002010void hash_setup( int alg_arg,
2011 int expected_status_arg )
2012{
2013 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002014 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002015 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002016 psa_status_t status;
2017
Gilles Peskine8817f612018-12-18 00:18:46 +01002018 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002019
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002020 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002021 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002022
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002023 /* Whether setup succeeded or failed, abort must succeed. */
2024 PSA_ASSERT( psa_hash_abort( &operation ) );
2025
2026 /* If setup failed, reproduce the failure, so as to
2027 * test the resulting state of the operation object. */
2028 if( status != PSA_SUCCESS )
2029 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2030
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002031 /* Now the operation object should be reusable. */
2032#if defined(KNOWN_SUPPORTED_HASH_ALG)
2033 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2034 PSA_ASSERT( psa_hash_abort( &operation ) );
2035#endif
2036
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002037exit:
2038 mbedtls_psa_crypto_free( );
2039}
2040/* END_CASE */
2041
2042/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002043void hash_bad_order( )
2044{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002045 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002046 unsigned char input[] = "";
2047 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002048 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002049 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2050 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2051 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002052 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002053 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002054 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002055
Gilles Peskine8817f612018-12-18 00:18:46 +01002056 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002057
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002058 /* Call setup twice in a row. */
2059 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2060 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2061 PSA_ERROR_BAD_STATE );
2062 PSA_ASSERT( psa_hash_abort( &operation ) );
2063
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002064 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002065 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002066 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002067 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002068
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002069 /* Call update after finish. */
2070 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2071 PSA_ASSERT( psa_hash_finish( &operation,
2072 hash, sizeof( hash ), &hash_len ) );
2073 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002074 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002075 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002076
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002077 /* Call verify without calling setup beforehand. */
2078 TEST_EQUAL( psa_hash_verify( &operation,
2079 valid_hash, sizeof( valid_hash ) ),
2080 PSA_ERROR_BAD_STATE );
2081 PSA_ASSERT( psa_hash_abort( &operation ) );
2082
2083 /* Call verify after finish. */
2084 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2085 PSA_ASSERT( psa_hash_finish( &operation,
2086 hash, sizeof( hash ), &hash_len ) );
2087 TEST_EQUAL( psa_hash_verify( &operation,
2088 valid_hash, sizeof( valid_hash ) ),
2089 PSA_ERROR_BAD_STATE );
2090 PSA_ASSERT( psa_hash_abort( &operation ) );
2091
2092 /* Call verify twice in a row. */
2093 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2094 PSA_ASSERT( psa_hash_verify( &operation,
2095 valid_hash, sizeof( valid_hash ) ) );
2096 TEST_EQUAL( psa_hash_verify( &operation,
2097 valid_hash, sizeof( valid_hash ) ),
2098 PSA_ERROR_BAD_STATE );
2099 PSA_ASSERT( psa_hash_abort( &operation ) );
2100
2101 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002102 TEST_EQUAL( psa_hash_finish( &operation,
2103 hash, sizeof( hash ), &hash_len ),
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 ) );
2106
2107 /* Call finish twice in a row. */
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_finish( &operation,
2112 hash, sizeof( hash ), &hash_len ),
2113 PSA_ERROR_BAD_STATE );
2114 PSA_ASSERT( psa_hash_abort( &operation ) );
2115
2116 /* Call finish after calling verify. */
2117 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2118 PSA_ASSERT( psa_hash_verify( &operation,
2119 valid_hash, sizeof( valid_hash ) ) );
2120 TEST_EQUAL( psa_hash_finish( &operation,
2121 hash, sizeof( hash ), &hash_len ),
2122 PSA_ERROR_BAD_STATE );
2123 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002124
2125exit:
2126 mbedtls_psa_crypto_free( );
2127}
2128/* END_CASE */
2129
itayzafrir27e69452018-11-01 14:26:34 +02002130/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2131void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002132{
2133 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002134 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2135 * appended to it */
2136 unsigned char hash[] = {
2137 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2138 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2139 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002140 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002141 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002142
Gilles Peskine8817f612018-12-18 00:18:46 +01002143 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002144
itayzafrir27e69452018-11-01 14:26:34 +02002145 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002146 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002147 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002148 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002149
itayzafrir27e69452018-11-01 14:26:34 +02002150 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002151 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002152 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002153 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002154
itayzafrir27e69452018-11-01 14:26:34 +02002155 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002156 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002157 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002158 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002159
itayzafrirec93d302018-10-18 18:01:10 +03002160exit:
2161 mbedtls_psa_crypto_free( );
2162}
2163/* END_CASE */
2164
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002165/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2166void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002167{
2168 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002169 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002170 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002171 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002172 size_t hash_len;
2173
Gilles Peskine8817f612018-12-18 00:18:46 +01002174 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002175
itayzafrir58028322018-10-25 10:22:01 +03002176 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002177 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002178 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002179 hash, expected_size - 1, &hash_len ),
2180 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002181
2182exit:
2183 mbedtls_psa_crypto_free( );
2184}
2185/* END_CASE */
2186
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002187/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2188void hash_clone_source_state( )
2189{
2190 psa_algorithm_t alg = PSA_ALG_SHA_256;
2191 unsigned char hash[PSA_HASH_MAX_SIZE];
2192 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2193 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2194 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2195 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2196 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2197 size_t hash_len;
2198
2199 PSA_ASSERT( psa_crypto_init( ) );
2200 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2201
2202 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2203 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2204 PSA_ASSERT( psa_hash_finish( &op_finished,
2205 hash, sizeof( hash ), &hash_len ) );
2206 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2207 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2208
2209 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2210 PSA_ERROR_BAD_STATE );
2211
2212 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2213 PSA_ASSERT( psa_hash_finish( &op_init,
2214 hash, sizeof( hash ), &hash_len ) );
2215 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2216 PSA_ASSERT( psa_hash_finish( &op_finished,
2217 hash, sizeof( hash ), &hash_len ) );
2218 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2219 PSA_ASSERT( psa_hash_finish( &op_aborted,
2220 hash, sizeof( hash ), &hash_len ) );
2221
2222exit:
2223 psa_hash_abort( &op_source );
2224 psa_hash_abort( &op_init );
2225 psa_hash_abort( &op_setup );
2226 psa_hash_abort( &op_finished );
2227 psa_hash_abort( &op_aborted );
2228 mbedtls_psa_crypto_free( );
2229}
2230/* END_CASE */
2231
2232/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2233void hash_clone_target_state( )
2234{
2235 psa_algorithm_t alg = PSA_ALG_SHA_256;
2236 unsigned char hash[PSA_HASH_MAX_SIZE];
2237 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2238 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2239 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2240 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2241 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2242 size_t hash_len;
2243
2244 PSA_ASSERT( psa_crypto_init( ) );
2245
2246 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2247 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2248 PSA_ASSERT( psa_hash_finish( &op_finished,
2249 hash, sizeof( hash ), &hash_len ) );
2250 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2251 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2252
2253 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2254 PSA_ASSERT( psa_hash_finish( &op_target,
2255 hash, sizeof( hash ), &hash_len ) );
2256
2257 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2258 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2259 PSA_ERROR_BAD_STATE );
2260 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2261 PSA_ERROR_BAD_STATE );
2262
2263exit:
2264 psa_hash_abort( &op_target );
2265 psa_hash_abort( &op_init );
2266 psa_hash_abort( &op_setup );
2267 psa_hash_abort( &op_finished );
2268 psa_hash_abort( &op_aborted );
2269 mbedtls_psa_crypto_free( );
2270}
2271/* END_CASE */
2272
itayzafrir58028322018-10-25 10:22:01 +03002273/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002274void mac_operation_init( )
2275{
Jaeden Amero252ef282019-02-15 14:05:35 +00002276 const uint8_t input[1] = { 0 };
2277
Jaeden Amero769ce272019-01-04 11:48:03 +00002278 /* Test each valid way of initializing the object, except for `= {0}`, as
2279 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2280 * though it's OK by the C standard. We could test for this, but we'd need
2281 * to supress the Clang warning for the test. */
2282 psa_mac_operation_t func = psa_mac_operation_init( );
2283 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2284 psa_mac_operation_t zero;
2285
2286 memset( &zero, 0, sizeof( zero ) );
2287
Jaeden Amero252ef282019-02-15 14:05:35 +00002288 /* A freshly-initialized MAC operation should not be usable. */
2289 TEST_EQUAL( psa_mac_update( &func,
2290 input, sizeof( input ) ),
2291 PSA_ERROR_BAD_STATE );
2292 TEST_EQUAL( psa_mac_update( &init,
2293 input, sizeof( input ) ),
2294 PSA_ERROR_BAD_STATE );
2295 TEST_EQUAL( psa_mac_update( &zero,
2296 input, sizeof( input ) ),
2297 PSA_ERROR_BAD_STATE );
2298
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002299 /* A default MAC operation should be abortable without error. */
2300 PSA_ASSERT( psa_mac_abort( &func ) );
2301 PSA_ASSERT( psa_mac_abort( &init ) );
2302 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002303}
2304/* END_CASE */
2305
2306/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002307void mac_setup( int key_type_arg,
2308 data_t *key,
2309 int alg_arg,
2310 int expected_status_arg )
2311{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002312 psa_key_type_t key_type = key_type_arg;
2313 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002314 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002315 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002316 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2317#if defined(KNOWN_SUPPORTED_MAC_ALG)
2318 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2319#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002320
Gilles Peskine8817f612018-12-18 00:18:46 +01002321 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002322
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002323 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2324 &operation, &status ) )
2325 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002326 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002327
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002328 /* The operation object should be reusable. */
2329#if defined(KNOWN_SUPPORTED_MAC_ALG)
2330 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2331 smoke_test_key_data,
2332 sizeof( smoke_test_key_data ),
2333 KNOWN_SUPPORTED_MAC_ALG,
2334 &operation, &status ) )
2335 goto exit;
2336 TEST_EQUAL( status, PSA_SUCCESS );
2337#endif
2338
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002339exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002340 mbedtls_psa_crypto_free( );
2341}
2342/* END_CASE */
2343
2344/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002345void mac_bad_order( )
2346{
2347 psa_key_handle_t handle = 0;
2348 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2349 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2350 const uint8_t key[] = {
2351 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2352 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2353 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002354 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002355 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2356 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2357 size_t sign_mac_length = 0;
2358 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2359 const uint8_t verify_mac[] = {
2360 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2361 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2362 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2363
2364 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002365 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2366 psa_set_key_algorithm( &attributes, alg );
2367 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002368
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002369 PSA_ASSERT( psa_import_key( &attributes, &handle,
Jaeden Amero252ef282019-02-15 14:05:35 +00002370 key, sizeof(key) ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002371
Jaeden Amero252ef282019-02-15 14:05:35 +00002372 /* Call update without calling setup beforehand. */
2373 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2374 PSA_ERROR_BAD_STATE );
2375 PSA_ASSERT( psa_mac_abort( &operation ) );
2376
2377 /* Call sign finish without calling setup beforehand. */
2378 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2379 &sign_mac_length),
2380 PSA_ERROR_BAD_STATE );
2381 PSA_ASSERT( psa_mac_abort( &operation ) );
2382
2383 /* Call verify finish without calling setup beforehand. */
2384 TEST_EQUAL( psa_mac_verify_finish( &operation,
2385 verify_mac, sizeof( verify_mac ) ),
2386 PSA_ERROR_BAD_STATE );
2387 PSA_ASSERT( psa_mac_abort( &operation ) );
2388
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002389 /* Call setup twice in a row. */
2390 PSA_ASSERT( psa_mac_sign_setup( &operation,
2391 handle, alg ) );
2392 TEST_EQUAL( psa_mac_sign_setup( &operation,
2393 handle, alg ),
2394 PSA_ERROR_BAD_STATE );
2395 PSA_ASSERT( psa_mac_abort( &operation ) );
2396
Jaeden Amero252ef282019-02-15 14:05:35 +00002397 /* Call update after sign finish. */
2398 PSA_ASSERT( psa_mac_sign_setup( &operation,
2399 handle, alg ) );
2400 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2401 PSA_ASSERT( psa_mac_sign_finish( &operation,
2402 sign_mac, sizeof( sign_mac ),
2403 &sign_mac_length ) );
2404 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2405 PSA_ERROR_BAD_STATE );
2406 PSA_ASSERT( psa_mac_abort( &operation ) );
2407
2408 /* Call update after verify finish. */
2409 PSA_ASSERT( psa_mac_verify_setup( &operation,
2410 handle, alg ) );
2411 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2412 PSA_ASSERT( psa_mac_verify_finish( &operation,
2413 verify_mac, sizeof( verify_mac ) ) );
2414 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2415 PSA_ERROR_BAD_STATE );
2416 PSA_ASSERT( psa_mac_abort( &operation ) );
2417
2418 /* Call sign finish twice in a row. */
2419 PSA_ASSERT( psa_mac_sign_setup( &operation,
2420 handle, alg ) );
2421 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2422 PSA_ASSERT( psa_mac_sign_finish( &operation,
2423 sign_mac, sizeof( sign_mac ),
2424 &sign_mac_length ) );
2425 TEST_EQUAL( psa_mac_sign_finish( &operation,
2426 sign_mac, sizeof( sign_mac ),
2427 &sign_mac_length ),
2428 PSA_ERROR_BAD_STATE );
2429 PSA_ASSERT( psa_mac_abort( &operation ) );
2430
2431 /* Call verify finish twice in a row. */
2432 PSA_ASSERT( psa_mac_verify_setup( &operation,
2433 handle, alg ) );
2434 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2435 PSA_ASSERT( psa_mac_verify_finish( &operation,
2436 verify_mac, sizeof( verify_mac ) ) );
2437 TEST_EQUAL( psa_mac_verify_finish( &operation,
2438 verify_mac, sizeof( verify_mac ) ),
2439 PSA_ERROR_BAD_STATE );
2440 PSA_ASSERT( psa_mac_abort( &operation ) );
2441
2442 /* Setup sign but try verify. */
2443 PSA_ASSERT( psa_mac_sign_setup( &operation,
2444 handle, alg ) );
2445 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2446 TEST_EQUAL( psa_mac_verify_finish( &operation,
2447 verify_mac, sizeof( verify_mac ) ),
2448 PSA_ERROR_BAD_STATE );
2449 PSA_ASSERT( psa_mac_abort( &operation ) );
2450
2451 /* Setup verify but try sign. */
2452 PSA_ASSERT( psa_mac_verify_setup( &operation,
2453 handle, alg ) );
2454 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2455 TEST_EQUAL( psa_mac_sign_finish( &operation,
2456 sign_mac, sizeof( sign_mac ),
2457 &sign_mac_length ),
2458 PSA_ERROR_BAD_STATE );
2459 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002460
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002461exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002462 mbedtls_psa_crypto_free( );
2463}
2464/* END_CASE */
2465
2466/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002467void mac_sign( int key_type_arg,
2468 data_t *key,
2469 int alg_arg,
2470 data_t *input,
2471 data_t *expected_mac )
2472{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002473 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002474 psa_key_type_t key_type = key_type_arg;
2475 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002476 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002477 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002478 /* Leave a little extra room in the output buffer. At the end of the
2479 * test, we'll check that the implementation didn't overwrite onto
2480 * this extra room. */
2481 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2482 size_t mac_buffer_size =
2483 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2484 size_t mac_length = 0;
2485
2486 memset( actual_mac, '+', sizeof( actual_mac ) );
2487 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2488 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2489
Gilles Peskine8817f612018-12-18 00:18:46 +01002490 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002491
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002492 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2493 psa_set_key_algorithm( &attributes, alg );
2494 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002495
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002496 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002497 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002498
2499 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002500 PSA_ASSERT( psa_mac_sign_setup( &operation,
2501 handle, alg ) );
2502 PSA_ASSERT( psa_mac_update( &operation,
2503 input->x, input->len ) );
2504 PSA_ASSERT( psa_mac_sign_finish( &operation,
2505 actual_mac, mac_buffer_size,
2506 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002507
2508 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002509 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2510 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002511
2512 /* Verify that the end of the buffer is untouched. */
2513 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2514 sizeof( actual_mac ) - mac_length ) );
2515
2516exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002517 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002518 mbedtls_psa_crypto_free( );
2519}
2520/* END_CASE */
2521
2522/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002523void mac_verify( int key_type_arg,
2524 data_t *key,
2525 int alg_arg,
2526 data_t *input,
2527 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002528{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002529 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002530 psa_key_type_t key_type = key_type_arg;
2531 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002532 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002533 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002534
Gilles Peskine69c12672018-06-28 00:07:19 +02002535 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2536
Gilles Peskine8817f612018-12-18 00:18:46 +01002537 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002538
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002539 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2540 psa_set_key_algorithm( &attributes, alg );
2541 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002542
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002543 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002544 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002545
Gilles Peskine8817f612018-12-18 00:18:46 +01002546 PSA_ASSERT( psa_mac_verify_setup( &operation,
2547 handle, alg ) );
2548 PSA_ASSERT( psa_destroy_key( handle ) );
2549 PSA_ASSERT( psa_mac_update( &operation,
2550 input->x, input->len ) );
2551 PSA_ASSERT( psa_mac_verify_finish( &operation,
2552 expected_mac->x,
2553 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002554
2555exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002556 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002557 mbedtls_psa_crypto_free( );
2558}
2559/* END_CASE */
2560
2561/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002562void cipher_operation_init( )
2563{
Jaeden Ameroab439972019-02-15 14:12:05 +00002564 const uint8_t input[1] = { 0 };
2565 unsigned char output[1] = { 0 };
2566 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002567 /* Test each valid way of initializing the object, except for `= {0}`, as
2568 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2569 * though it's OK by the C standard. We could test for this, but we'd need
2570 * to supress the Clang warning for the test. */
2571 psa_cipher_operation_t func = psa_cipher_operation_init( );
2572 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2573 psa_cipher_operation_t zero;
2574
2575 memset( &zero, 0, sizeof( zero ) );
2576
Jaeden Ameroab439972019-02-15 14:12:05 +00002577 /* A freshly-initialized cipher operation should not be usable. */
2578 TEST_EQUAL( psa_cipher_update( &func,
2579 input, sizeof( input ),
2580 output, sizeof( output ),
2581 &output_length ),
2582 PSA_ERROR_BAD_STATE );
2583 TEST_EQUAL( psa_cipher_update( &init,
2584 input, sizeof( input ),
2585 output, sizeof( output ),
2586 &output_length ),
2587 PSA_ERROR_BAD_STATE );
2588 TEST_EQUAL( psa_cipher_update( &zero,
2589 input, sizeof( input ),
2590 output, sizeof( output ),
2591 &output_length ),
2592 PSA_ERROR_BAD_STATE );
2593
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002594 /* A default cipher operation should be abortable without error. */
2595 PSA_ASSERT( psa_cipher_abort( &func ) );
2596 PSA_ASSERT( psa_cipher_abort( &init ) );
2597 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002598}
2599/* END_CASE */
2600
2601/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002602void cipher_setup( int key_type_arg,
2603 data_t *key,
2604 int alg_arg,
2605 int expected_status_arg )
2606{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002607 psa_key_type_t key_type = key_type_arg;
2608 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002609 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002610 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002611 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002612#if defined(KNOWN_SUPPORTED_MAC_ALG)
2613 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2614#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002615
Gilles Peskine8817f612018-12-18 00:18:46 +01002616 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002617
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002618 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2619 &operation, &status ) )
2620 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002621 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002622
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002623 /* The operation object should be reusable. */
2624#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2625 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2626 smoke_test_key_data,
2627 sizeof( smoke_test_key_data ),
2628 KNOWN_SUPPORTED_CIPHER_ALG,
2629 &operation, &status ) )
2630 goto exit;
2631 TEST_EQUAL( status, PSA_SUCCESS );
2632#endif
2633
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002634exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002635 mbedtls_psa_crypto_free( );
2636}
2637/* END_CASE */
2638
2639/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002640void cipher_bad_order( )
2641{
2642 psa_key_handle_t handle = 0;
2643 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2644 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002645 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002646 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2647 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2648 const uint8_t key[] = {
2649 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2650 0xaa, 0xaa, 0xaa, 0xaa };
2651 const uint8_t text[] = {
2652 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2653 0xbb, 0xbb, 0xbb, 0xbb };
2654 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2655 size_t length = 0;
2656
2657 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002658 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2659 psa_set_key_algorithm( &attributes, alg );
2660 psa_set_key_type( &attributes, key_type );
2661 PSA_ASSERT( psa_import_key( &attributes, &handle,
Jaeden Ameroab439972019-02-15 14:12:05 +00002662 key, sizeof(key) ) );
2663
2664
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002665 /* Call encrypt setup twice in a row. */
2666 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2667 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2668 PSA_ERROR_BAD_STATE );
2669 PSA_ASSERT( psa_cipher_abort( &operation ) );
2670
2671 /* Call decrypt setup twice in a row. */
2672 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2673 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2674 PSA_ERROR_BAD_STATE );
2675 PSA_ASSERT( psa_cipher_abort( &operation ) );
2676
Jaeden Ameroab439972019-02-15 14:12:05 +00002677 /* Generate an IV without calling setup beforehand. */
2678 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2679 buffer, sizeof( buffer ),
2680 &length ),
2681 PSA_ERROR_BAD_STATE );
2682 PSA_ASSERT( psa_cipher_abort( &operation ) );
2683
2684 /* Generate an IV twice in a row. */
2685 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2686 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2687 buffer, sizeof( buffer ),
2688 &length ) );
2689 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2690 buffer, sizeof( buffer ),
2691 &length ),
2692 PSA_ERROR_BAD_STATE );
2693 PSA_ASSERT( psa_cipher_abort( &operation ) );
2694
2695 /* Generate an IV after it's already set. */
2696 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2697 PSA_ASSERT( psa_cipher_set_iv( &operation,
2698 iv, sizeof( iv ) ) );
2699 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2700 buffer, sizeof( buffer ),
2701 &length ),
2702 PSA_ERROR_BAD_STATE );
2703 PSA_ASSERT( psa_cipher_abort( &operation ) );
2704
2705 /* Set an IV without calling setup beforehand. */
2706 TEST_EQUAL( psa_cipher_set_iv( &operation,
2707 iv, sizeof( iv ) ),
2708 PSA_ERROR_BAD_STATE );
2709 PSA_ASSERT( psa_cipher_abort( &operation ) );
2710
2711 /* Set an IV after it's already set. */
2712 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2713 PSA_ASSERT( psa_cipher_set_iv( &operation,
2714 iv, sizeof( iv ) ) );
2715 TEST_EQUAL( psa_cipher_set_iv( &operation,
2716 iv, sizeof( iv ) ),
2717 PSA_ERROR_BAD_STATE );
2718 PSA_ASSERT( psa_cipher_abort( &operation ) );
2719
2720 /* Set an IV after it's already generated. */
2721 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2722 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2723 buffer, sizeof( buffer ),
2724 &length ) );
2725 TEST_EQUAL( psa_cipher_set_iv( &operation,
2726 iv, sizeof( iv ) ),
2727 PSA_ERROR_BAD_STATE );
2728 PSA_ASSERT( psa_cipher_abort( &operation ) );
2729
2730 /* Call update without calling setup beforehand. */
2731 TEST_EQUAL( psa_cipher_update( &operation,
2732 text, sizeof( text ),
2733 buffer, sizeof( buffer ),
2734 &length ),
2735 PSA_ERROR_BAD_STATE );
2736 PSA_ASSERT( psa_cipher_abort( &operation ) );
2737
2738 /* Call update without an IV where an IV is required. */
2739 TEST_EQUAL( psa_cipher_update( &operation,
2740 text, sizeof( text ),
2741 buffer, sizeof( buffer ),
2742 &length ),
2743 PSA_ERROR_BAD_STATE );
2744 PSA_ASSERT( psa_cipher_abort( &operation ) );
2745
2746 /* Call update after finish. */
2747 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2748 PSA_ASSERT( psa_cipher_set_iv( &operation,
2749 iv, sizeof( iv ) ) );
2750 PSA_ASSERT( psa_cipher_finish( &operation,
2751 buffer, sizeof( buffer ), &length ) );
2752 TEST_EQUAL( psa_cipher_update( &operation,
2753 text, sizeof( text ),
2754 buffer, sizeof( buffer ),
2755 &length ),
2756 PSA_ERROR_BAD_STATE );
2757 PSA_ASSERT( psa_cipher_abort( &operation ) );
2758
2759 /* Call finish without calling setup beforehand. */
2760 TEST_EQUAL( psa_cipher_finish( &operation,
2761 buffer, sizeof( buffer ), &length ),
2762 PSA_ERROR_BAD_STATE );
2763 PSA_ASSERT( psa_cipher_abort( &operation ) );
2764
2765 /* Call finish without an IV where an IV is required. */
2766 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2767 /* Not calling update means we are encrypting an empty buffer, which is OK
2768 * for cipher modes with padding. */
2769 TEST_EQUAL( psa_cipher_finish( &operation,
2770 buffer, sizeof( buffer ), &length ),
2771 PSA_ERROR_BAD_STATE );
2772 PSA_ASSERT( psa_cipher_abort( &operation ) );
2773
2774 /* Call finish twice in a row. */
2775 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2776 PSA_ASSERT( psa_cipher_set_iv( &operation,
2777 iv, sizeof( iv ) ) );
2778 PSA_ASSERT( psa_cipher_finish( &operation,
2779 buffer, sizeof( buffer ), &length ) );
2780 TEST_EQUAL( psa_cipher_finish( &operation,
2781 buffer, sizeof( buffer ), &length ),
2782 PSA_ERROR_BAD_STATE );
2783 PSA_ASSERT( psa_cipher_abort( &operation ) );
2784
2785exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002786 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002787}
2788/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002789
Gilles Peskine50e586b2018-06-08 14:28:46 +02002790/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002791void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002792 data_t *key,
2793 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002794 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002795{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002796 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002797 psa_status_t status;
2798 psa_key_type_t key_type = key_type_arg;
2799 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002800 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002801 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002802 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002803 unsigned char *output = NULL;
2804 size_t output_buffer_size = 0;
2805 size_t function_output_length = 0;
2806 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002807 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002808 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002809
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002810 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2811 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002812
Gilles Peskine8817f612018-12-18 00:18:46 +01002813 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002814
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002815 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2816 psa_set_key_algorithm( &attributes, alg );
2817 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002818
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002819 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002820 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002821
Gilles Peskine8817f612018-12-18 00:18:46 +01002822 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2823 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002824
Gilles Peskine8817f612018-12-18 00:18:46 +01002825 PSA_ASSERT( psa_cipher_set_iv( &operation,
2826 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002827 output_buffer_size = ( (size_t) input->len +
2828 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002829 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002830
Gilles Peskine8817f612018-12-18 00:18:46 +01002831 PSA_ASSERT( psa_cipher_update( &operation,
2832 input->x, input->len,
2833 output, output_buffer_size,
2834 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002835 total_output_length += function_output_length;
2836 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002837 output + total_output_length,
2838 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002839 &function_output_length );
2840 total_output_length += function_output_length;
2841
Gilles Peskinefe11b722018-12-18 00:24:04 +01002842 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002843 if( expected_status == PSA_SUCCESS )
2844 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002845 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002846 ASSERT_COMPARE( expected_output->x, expected_output->len,
2847 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002848 }
2849
2850exit:
2851 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002852 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002853 mbedtls_psa_crypto_free( );
2854}
2855/* END_CASE */
2856
2857/* BEGIN_CASE */
2858void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
2859 data_t *key,
2860 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002861 int first_part_size_arg,
2862 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002863 data_t *expected_output )
2864{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002865 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002866 psa_key_type_t key_type = key_type_arg;
2867 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002868 size_t first_part_size = first_part_size_arg;
2869 size_t output1_length = output1_length_arg;
2870 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002871 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002872 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002873 unsigned char *output = NULL;
2874 size_t output_buffer_size = 0;
2875 size_t function_output_length = 0;
2876 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002877 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002878 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002879
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002880 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2881 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002882
Gilles Peskine8817f612018-12-18 00:18:46 +01002883 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002884
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002885 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2886 psa_set_key_algorithm( &attributes, alg );
2887 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002888
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002889 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002890 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002891
Gilles Peskine8817f612018-12-18 00:18:46 +01002892 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2893 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002894
Gilles Peskine8817f612018-12-18 00:18:46 +01002895 PSA_ASSERT( psa_cipher_set_iv( &operation,
2896 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002897 output_buffer_size = ( (size_t) input->len +
2898 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002899 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002900
Gilles Peskinee0866522019-02-19 19:44:00 +01002901 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002902 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2903 output, output_buffer_size,
2904 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002905 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002906 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002907 PSA_ASSERT( psa_cipher_update( &operation,
2908 input->x + first_part_size,
2909 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002910 output + total_output_length,
2911 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002912 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002913 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002914 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002915 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002916 output + total_output_length,
2917 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002918 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002919 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002920 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002921
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002922 ASSERT_COMPARE( expected_output->x, expected_output->len,
2923 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924
2925exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002926 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002927 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002928 mbedtls_psa_crypto_free( );
2929}
2930/* END_CASE */
2931
2932/* BEGIN_CASE */
2933void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002934 data_t *key,
2935 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002936 int first_part_size_arg,
2937 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002938 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002939{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002940 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002941
2942 psa_key_type_t key_type = key_type_arg;
2943 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002944 size_t first_part_size = first_part_size_arg;
2945 size_t output1_length = output1_length_arg;
2946 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002947 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002948 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002949 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002950 size_t output_buffer_size = 0;
2951 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002952 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002953 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002954 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002955
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002956 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2957 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002958
Gilles Peskine8817f612018-12-18 00:18:46 +01002959 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002960
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002961 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
2962 psa_set_key_algorithm( &attributes, alg );
2963 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002964
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002965 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002966 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002967
Gilles Peskine8817f612018-12-18 00:18:46 +01002968 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
2969 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002970
Gilles Peskine8817f612018-12-18 00:18:46 +01002971 PSA_ASSERT( psa_cipher_set_iv( &operation,
2972 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002973
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002974 output_buffer_size = ( (size_t) input->len +
2975 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002976 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002977
Gilles Peskinee0866522019-02-19 19:44:00 +01002978 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002979 PSA_ASSERT( psa_cipher_update( &operation,
2980 input->x, first_part_size,
2981 output, output_buffer_size,
2982 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002983 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002984 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002985 PSA_ASSERT( psa_cipher_update( &operation,
2986 input->x + first_part_size,
2987 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002988 output + total_output_length,
2989 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002990 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002991 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002992 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002993 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002994 output + total_output_length,
2995 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002996 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002997 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002998 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002999
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003000 ASSERT_COMPARE( expected_output->x, expected_output->len,
3001 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003002
3003exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003004 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003005 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003006 mbedtls_psa_crypto_free( );
3007}
3008/* END_CASE */
3009
Gilles Peskine50e586b2018-06-08 14:28:46 +02003010/* BEGIN_CASE */
3011void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003012 data_t *key,
3013 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003014 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003015{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003016 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003017 psa_status_t status;
3018 psa_key_type_t key_type = key_type_arg;
3019 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003020 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003021 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003022 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003023 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003024 size_t output_buffer_size = 0;
3025 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003026 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003027 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003028 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003029
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003030 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3031 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003032
Gilles Peskine8817f612018-12-18 00:18:46 +01003033 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003034
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003035 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3036 psa_set_key_algorithm( &attributes, alg );
3037 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003038
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003039 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003040 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041
Gilles Peskine8817f612018-12-18 00:18:46 +01003042 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3043 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003044
Gilles Peskine8817f612018-12-18 00:18:46 +01003045 PSA_ASSERT( psa_cipher_set_iv( &operation,
3046 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003047
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003048 output_buffer_size = ( (size_t) input->len +
3049 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003050 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003051
Gilles Peskine8817f612018-12-18 00:18:46 +01003052 PSA_ASSERT( psa_cipher_update( &operation,
3053 input->x, input->len,
3054 output, output_buffer_size,
3055 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003056 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003057 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003058 output + total_output_length,
3059 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003060 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003061 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003062 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003063
3064 if( expected_status == PSA_SUCCESS )
3065 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003066 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003067 ASSERT_COMPARE( expected_output->x, expected_output->len,
3068 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003069 }
3070
Gilles Peskine50e586b2018-06-08 14:28:46 +02003071exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003072 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003073 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074 mbedtls_psa_crypto_free( );
3075}
3076/* END_CASE */
3077
Gilles Peskine50e586b2018-06-08 14:28:46 +02003078/* BEGIN_CASE */
3079void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003080 data_t *key,
3081 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003082{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003083 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003084 psa_key_type_t key_type = key_type_arg;
3085 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003086 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003087 size_t iv_size = 16;
3088 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003089 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003090 size_t output1_size = 0;
3091 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003092 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003093 size_t output2_size = 0;
3094 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003095 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003096 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3097 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003098 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003099
Gilles Peskine8817f612018-12-18 00:18:46 +01003100 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003101
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003102 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3103 psa_set_key_algorithm( &attributes, alg );
3104 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003105
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003106 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003107 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003108
Gilles Peskine8817f612018-12-18 00:18:46 +01003109 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3110 handle, alg ) );
3111 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3112 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003113
Gilles Peskine8817f612018-12-18 00:18:46 +01003114 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3115 iv, iv_size,
3116 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003117 output1_size = ( (size_t) input->len +
3118 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003119 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003120
Gilles Peskine8817f612018-12-18 00:18:46 +01003121 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3122 output1, output1_size,
3123 &output1_length ) );
3124 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003125 output1 + output1_length,
3126 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003127 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003128
Gilles Peskine048b7f02018-06-08 14:20:49 +02003129 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003130
Gilles Peskine8817f612018-12-18 00:18:46 +01003131 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003132
3133 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003134 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003135
Gilles Peskine8817f612018-12-18 00:18:46 +01003136 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3137 iv, iv_length ) );
3138 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3139 output2, output2_size,
3140 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003141 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003142 PSA_ASSERT( psa_cipher_finish( &operation2,
3143 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003144 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003145 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003146
Gilles Peskine048b7f02018-06-08 14:20:49 +02003147 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003148
Gilles Peskine8817f612018-12-18 00:18:46 +01003149 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003150
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003151 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003152
3153exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003154 mbedtls_free( output1 );
3155 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003156 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003157 mbedtls_psa_crypto_free( );
3158}
3159/* END_CASE */
3160
3161/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003162void cipher_verify_output_multipart( int alg_arg,
3163 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003164 data_t *key,
3165 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003166 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003167{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003168 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003169 psa_key_type_t key_type = key_type_arg;
3170 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003171 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003172 unsigned char iv[16] = {0};
3173 size_t iv_size = 16;
3174 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003175 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003176 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003177 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003178 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003179 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003180 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003181 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003182 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3183 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003184 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003185
Gilles Peskine8817f612018-12-18 00:18:46 +01003186 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003187
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003188 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3189 psa_set_key_algorithm( &attributes, alg );
3190 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003191
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003192 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003193 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003194
Gilles Peskine8817f612018-12-18 00:18:46 +01003195 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3196 handle, alg ) );
3197 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3198 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003199
Gilles Peskine8817f612018-12-18 00:18:46 +01003200 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3201 iv, iv_size,
3202 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003203 output1_buffer_size = ( (size_t) input->len +
3204 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003205 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003206
Gilles Peskinee0866522019-02-19 19:44:00 +01003207 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003208
Gilles Peskine8817f612018-12-18 00:18:46 +01003209 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3210 output1, output1_buffer_size,
3211 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003212 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003213
Gilles Peskine8817f612018-12-18 00:18:46 +01003214 PSA_ASSERT( psa_cipher_update( &operation1,
3215 input->x + first_part_size,
3216 input->len - first_part_size,
3217 output1, output1_buffer_size,
3218 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003219 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003220
Gilles Peskine8817f612018-12-18 00:18:46 +01003221 PSA_ASSERT( psa_cipher_finish( &operation1,
3222 output1 + output1_length,
3223 output1_buffer_size - output1_length,
3224 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003225 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003226
Gilles Peskine8817f612018-12-18 00:18:46 +01003227 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003228
Gilles Peskine048b7f02018-06-08 14:20:49 +02003229 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003230 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003231
Gilles Peskine8817f612018-12-18 00:18:46 +01003232 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3233 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003234
Gilles Peskine8817f612018-12-18 00:18:46 +01003235 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3236 output2, output2_buffer_size,
3237 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003238 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003239
Gilles Peskine8817f612018-12-18 00:18:46 +01003240 PSA_ASSERT( psa_cipher_update( &operation2,
3241 output1 + first_part_size,
3242 output1_length - first_part_size,
3243 output2, output2_buffer_size,
3244 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003245 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003246
Gilles Peskine8817f612018-12-18 00:18:46 +01003247 PSA_ASSERT( psa_cipher_finish( &operation2,
3248 output2 + output2_length,
3249 output2_buffer_size - output2_length,
3250 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003251 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003252
Gilles Peskine8817f612018-12-18 00:18:46 +01003253 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003254
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003255 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003256
3257exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003258 mbedtls_free( output1 );
3259 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003260 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003261 mbedtls_psa_crypto_free( );
3262}
3263/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003264
Gilles Peskine20035e32018-02-03 22:44:14 +01003265/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003266void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003267 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003268 data_t *nonce,
3269 data_t *additional_data,
3270 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003271 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003272{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003273 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003274 psa_key_type_t key_type = key_type_arg;
3275 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003276 unsigned char *output_data = NULL;
3277 size_t output_size = 0;
3278 size_t output_length = 0;
3279 unsigned char *output_data2 = NULL;
3280 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003281 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003282 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003283 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003284
Gilles Peskine4abf7412018-06-18 16:35:34 +02003285 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003286 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003287
Gilles Peskine8817f612018-12-18 00:18:46 +01003288 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003289
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003290 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3291 psa_set_key_algorithm( &attributes, alg );
3292 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003293
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003294 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003295 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003296
Gilles Peskinefe11b722018-12-18 00:24:04 +01003297 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3298 nonce->x, nonce->len,
3299 additional_data->x,
3300 additional_data->len,
3301 input_data->x, input_data->len,
3302 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003303 &output_length ),
3304 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003305
3306 if( PSA_SUCCESS == expected_result )
3307 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003308 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003309
Gilles Peskinefe11b722018-12-18 00:24:04 +01003310 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3311 nonce->x, nonce->len,
3312 additional_data->x,
3313 additional_data->len,
3314 output_data, output_length,
3315 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003316 &output_length2 ),
3317 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003318
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003319 ASSERT_COMPARE( input_data->x, input_data->len,
3320 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003321 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003322
Gilles Peskinea1cac842018-06-11 19:33:02 +02003323exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003324 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003325 mbedtls_free( output_data );
3326 mbedtls_free( output_data2 );
3327 mbedtls_psa_crypto_free( );
3328}
3329/* END_CASE */
3330
3331/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003332void aead_encrypt( int key_type_arg, data_t *key_data,
3333 int alg_arg,
3334 data_t *nonce,
3335 data_t *additional_data,
3336 data_t *input_data,
3337 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003338{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003339 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003340 psa_key_type_t key_type = key_type_arg;
3341 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003342 unsigned char *output_data = NULL;
3343 size_t output_size = 0;
3344 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003345 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003346 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003347
Gilles Peskine4abf7412018-06-18 16:35:34 +02003348 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003349 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003350
Gilles Peskine8817f612018-12-18 00:18:46 +01003351 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003352
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003353 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3354 psa_set_key_algorithm( &attributes, alg );
3355 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003356
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003357 PSA_ASSERT( psa_import_key( &attributes, &handle,
3358 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003359
Gilles Peskine8817f612018-12-18 00:18:46 +01003360 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3361 nonce->x, nonce->len,
3362 additional_data->x, additional_data->len,
3363 input_data->x, input_data->len,
3364 output_data, output_size,
3365 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003366
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003367 ASSERT_COMPARE( expected_result->x, expected_result->len,
3368 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003369
Gilles Peskinea1cac842018-06-11 19:33:02 +02003370exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003371 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003372 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003373 mbedtls_psa_crypto_free( );
3374}
3375/* END_CASE */
3376
3377/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003378void aead_decrypt( int key_type_arg, data_t *key_data,
3379 int alg_arg,
3380 data_t *nonce,
3381 data_t *additional_data,
3382 data_t *input_data,
3383 data_t *expected_data,
3384 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003385{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003386 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003387 psa_key_type_t key_type = key_type_arg;
3388 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003389 unsigned char *output_data = NULL;
3390 size_t output_size = 0;
3391 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003392 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003393 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003394 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003395
Gilles Peskine4abf7412018-06-18 16:35:34 +02003396 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003397 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003398
Gilles Peskine8817f612018-12-18 00:18:46 +01003399 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003401 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3402 psa_set_key_algorithm( &attributes, alg );
3403 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003404
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003405 PSA_ASSERT( psa_import_key( &attributes, &handle,
3406 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003407
Gilles Peskinefe11b722018-12-18 00:24:04 +01003408 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3409 nonce->x, nonce->len,
3410 additional_data->x,
3411 additional_data->len,
3412 input_data->x, input_data->len,
3413 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003414 &output_length ),
3415 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003416
Gilles Peskine2d277862018-06-18 15:41:12 +02003417 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003418 ASSERT_COMPARE( expected_data->x, expected_data->len,
3419 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003420
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003422 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003423 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003424 mbedtls_psa_crypto_free( );
3425}
3426/* END_CASE */
3427
3428/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003429void signature_size( int type_arg,
3430 int bits,
3431 int alg_arg,
3432 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003433{
3434 psa_key_type_t type = type_arg;
3435 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003436 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003437 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003438exit:
3439 ;
3440}
3441/* END_CASE */
3442
3443/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003444void sign_deterministic( int key_type_arg, data_t *key_data,
3445 int alg_arg, data_t *input_data,
3446 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003447{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003448 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003449 psa_key_type_t key_type = key_type_arg;
3450 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003451 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003452 unsigned char *signature = NULL;
3453 size_t signature_size;
3454 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003455 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003456
Gilles Peskine8817f612018-12-18 00:18:46 +01003457 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003458
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003459 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3460 psa_set_key_algorithm( &attributes, alg );
3461 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003462
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003463 PSA_ASSERT( psa_import_key( &attributes, &handle,
3464 key_data->x, key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003465 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3466 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003467
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003468 /* Allocate a buffer which has the size advertized by the
3469 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003470 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3471 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003472 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003473 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003474 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003475
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003476 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003477 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3478 input_data->x, input_data->len,
3479 signature, signature_size,
3480 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003481 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003482 ASSERT_COMPARE( output_data->x, output_data->len,
3483 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003484
3485exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003486 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003487 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003488 mbedtls_psa_crypto_free( );
3489}
3490/* END_CASE */
3491
3492/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003493void sign_fail( int key_type_arg, data_t *key_data,
3494 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003495 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003496{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003497 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003498 psa_key_type_t key_type = key_type_arg;
3499 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003500 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003501 psa_status_t actual_status;
3502 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003503 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003504 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003505 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003506
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003507 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003508
Gilles Peskine8817f612018-12-18 00:18:46 +01003509 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003510
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003511 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3512 psa_set_key_algorithm( &attributes, alg );
3513 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003514
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003515 PSA_ASSERT( psa_import_key( &attributes, &handle,
3516 key_data->x, key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003517
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003518 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003519 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003520 signature, signature_size,
3521 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003522 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003523 /* The value of *signature_length is unspecified on error, but
3524 * whatever it is, it should be less than signature_size, so that
3525 * if the caller tries to read *signature_length bytes without
3526 * checking the error code then they don't overflow a buffer. */
3527 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003528
3529exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003530 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003531 mbedtls_free( signature );
3532 mbedtls_psa_crypto_free( );
3533}
3534/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003535
3536/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003537void sign_verify( int key_type_arg, data_t *key_data,
3538 int alg_arg, data_t *input_data )
3539{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003540 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003541 psa_key_type_t key_type = key_type_arg;
3542 psa_algorithm_t alg = alg_arg;
3543 size_t key_bits;
3544 unsigned char *signature = NULL;
3545 size_t signature_size;
3546 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003547 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003548
Gilles Peskine8817f612018-12-18 00:18:46 +01003549 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003550
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003551 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3552 psa_set_key_algorithm( &attributes, alg );
3553 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003554
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003555 PSA_ASSERT( psa_import_key( &attributes, &handle,
3556 key_data->x, key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003557 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3558 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003559
3560 /* Allocate a buffer which has the size advertized by the
3561 * library. */
3562 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3563 key_bits, alg );
3564 TEST_ASSERT( signature_size != 0 );
3565 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003566 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003567
3568 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003569 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3570 input_data->x, input_data->len,
3571 signature, signature_size,
3572 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003573 /* Check that the signature length looks sensible. */
3574 TEST_ASSERT( signature_length <= signature_size );
3575 TEST_ASSERT( signature_length > 0 );
3576
3577 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003578 PSA_ASSERT( psa_asymmetric_verify(
3579 handle, alg,
3580 input_data->x, input_data->len,
3581 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003582
3583 if( input_data->len != 0 )
3584 {
3585 /* Flip a bit in the input and verify that the signature is now
3586 * detected as invalid. Flip a bit at the beginning, not at the end,
3587 * because ECDSA may ignore the last few bits of the input. */
3588 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003589 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3590 input_data->x, input_data->len,
3591 signature, signature_length ),
3592 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003593 }
3594
3595exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003596 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003597 mbedtls_free( signature );
3598 mbedtls_psa_crypto_free( );
3599}
3600/* END_CASE */
3601
3602/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003603void asymmetric_verify( int key_type_arg, data_t *key_data,
3604 int alg_arg, data_t *hash_data,
3605 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003606{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003607 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003608 psa_key_type_t key_type = key_type_arg;
3609 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003610 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003611
Gilles Peskine69c12672018-06-28 00:07:19 +02003612 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3613
Gilles Peskine8817f612018-12-18 00:18:46 +01003614 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003615
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003616 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3617 psa_set_key_algorithm( &attributes, alg );
3618 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003619
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003620 PSA_ASSERT( psa_import_key( &attributes, &handle,
3621 key_data->x, key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003622
Gilles Peskine8817f612018-12-18 00:18:46 +01003623 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3624 hash_data->x, hash_data->len,
3625 signature_data->x,
3626 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003627exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003628 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003629 mbedtls_psa_crypto_free( );
3630}
3631/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003632
3633/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003634void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3635 int alg_arg, data_t *hash_data,
3636 data_t *signature_data,
3637 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003638{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003639 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003640 psa_key_type_t key_type = key_type_arg;
3641 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003642 psa_status_t actual_status;
3643 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003644 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003645
Gilles Peskine8817f612018-12-18 00:18:46 +01003646 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003647
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003648 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3649 psa_set_key_algorithm( &attributes, alg );
3650 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003651
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003652 PSA_ASSERT( psa_import_key( &attributes, &handle,
3653 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003654
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003655 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003656 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003657 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003658 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003659
Gilles Peskinefe11b722018-12-18 00:24:04 +01003660 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003661
3662exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003663 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003664 mbedtls_psa_crypto_free( );
3665}
3666/* END_CASE */
3667
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003668/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003669void asymmetric_encrypt( int key_type_arg,
3670 data_t *key_data,
3671 int alg_arg,
3672 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003673 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003674 int expected_output_length_arg,
3675 int expected_status_arg )
3676{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003677 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003678 psa_key_type_t key_type = key_type_arg;
3679 psa_algorithm_t alg = alg_arg;
3680 size_t expected_output_length = expected_output_length_arg;
3681 size_t key_bits;
3682 unsigned char *output = NULL;
3683 size_t output_size;
3684 size_t output_length = ~0;
3685 psa_status_t actual_status;
3686 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003687 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003688
Gilles Peskine8817f612018-12-18 00:18:46 +01003689 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003690
Gilles Peskine656896e2018-06-29 19:12:28 +02003691 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003692 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3693 psa_set_key_algorithm( &attributes, alg );
3694 psa_set_key_type( &attributes, key_type );
3695 PSA_ASSERT( psa_import_key( &attributes, &handle,
3696 key_data->x, key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003697
3698 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003699 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3700 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003701 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003702 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003703
3704 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003705 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003706 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003707 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003708 output, output_size,
3709 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003710 TEST_EQUAL( actual_status, expected_status );
3711 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003712
Gilles Peskine68428122018-06-30 18:42:41 +02003713 /* If the label is empty, the test framework puts a non-null pointer
3714 * in label->x. Test that a null pointer works as well. */
3715 if( label->len == 0 )
3716 {
3717 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003718 if( output_size != 0 )
3719 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003720 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003721 input_data->x, input_data->len,
3722 NULL, label->len,
3723 output, output_size,
3724 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003725 TEST_EQUAL( actual_status, expected_status );
3726 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003727 }
3728
Gilles Peskine656896e2018-06-29 19:12:28 +02003729exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003730 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003731 mbedtls_free( output );
3732 mbedtls_psa_crypto_free( );
3733}
3734/* END_CASE */
3735
3736/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003737void asymmetric_encrypt_decrypt( int key_type_arg,
3738 data_t *key_data,
3739 int alg_arg,
3740 data_t *input_data,
3741 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003742{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003743 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003744 psa_key_type_t key_type = key_type_arg;
3745 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003746 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003747 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003748 size_t output_size;
3749 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003750 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003751 size_t output2_size;
3752 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003753 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003754
Gilles Peskine8817f612018-12-18 00:18:46 +01003755 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003756
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003757 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3758 psa_set_key_algorithm( &attributes, alg );
3759 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003760
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003761 PSA_ASSERT( psa_import_key( &attributes, &handle,
3762 key_data->x, key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003763
3764 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003765 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3766 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003767 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003768 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003769 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003770 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003771
Gilles Peskineeebd7382018-06-08 18:11:54 +02003772 /* We test encryption by checking that encrypt-then-decrypt gives back
3773 * the original plaintext because of the non-optional random
3774 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003775 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3776 input_data->x, input_data->len,
3777 label->x, label->len,
3778 output, output_size,
3779 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003780 /* We don't know what ciphertext length to expect, but check that
3781 * it looks sensible. */
3782 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003783
Gilles Peskine8817f612018-12-18 00:18:46 +01003784 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3785 output, output_length,
3786 label->x, label->len,
3787 output2, output2_size,
3788 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003789 ASSERT_COMPARE( input_data->x, input_data->len,
3790 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003791
3792exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003793 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003794 mbedtls_free( output );
3795 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003796 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003797}
3798/* END_CASE */
3799
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003800/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003801void asymmetric_decrypt( int key_type_arg,
3802 data_t *key_data,
3803 int alg_arg,
3804 data_t *input_data,
3805 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003806 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003807{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003808 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003809 psa_key_type_t key_type = key_type_arg;
3810 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003811 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003812 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003813 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003814 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003815
Jaeden Amero412654a2019-02-06 12:57:46 +00003816 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003817 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003818
Gilles Peskine8817f612018-12-18 00:18:46 +01003819 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003820
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003821 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3822 psa_set_key_algorithm( &attributes, alg );
3823 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003824
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003825 PSA_ASSERT( psa_import_key( &attributes, &handle,
3826 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003827
Gilles Peskine8817f612018-12-18 00:18:46 +01003828 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3829 input_data->x, input_data->len,
3830 label->x, label->len,
3831 output,
3832 output_size,
3833 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003834 ASSERT_COMPARE( expected_data->x, expected_data->len,
3835 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003836
Gilles Peskine68428122018-06-30 18:42:41 +02003837 /* If the label is empty, the test framework puts a non-null pointer
3838 * in label->x. Test that a null pointer works as well. */
3839 if( label->len == 0 )
3840 {
3841 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003842 if( output_size != 0 )
3843 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003844 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3845 input_data->x, input_data->len,
3846 NULL, label->len,
3847 output,
3848 output_size,
3849 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003850 ASSERT_COMPARE( expected_data->x, expected_data->len,
3851 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003852 }
3853
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003854exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003855 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003856 mbedtls_free( output );
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_fail( int key_type_arg,
3863 data_t *key_data,
3864 int alg_arg,
3865 data_t *input_data,
3866 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003867 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003868 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003869{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003870 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871 psa_key_type_t key_type = key_type_arg;
3872 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003873 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003874 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003875 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876 psa_status_t actual_status;
3877 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003878 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003879
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003880 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003881
Gilles Peskine8817f612018-12-18 00:18:46 +01003882 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003884 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3885 psa_set_key_algorithm( &attributes, alg );
3886 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003887
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003888 PSA_ASSERT( psa_import_key( &attributes, &handle,
3889 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003890
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003891 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003892 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003893 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003894 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003895 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003896 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003897 TEST_ASSERT( output_length <= output_size );
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 Peskinebdf309c2018-12-03 15:36:32 +01003906 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003907 input_data->x, input_data->len,
3908 NULL, label->len,
3909 output, output_size,
3910 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003911 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003912 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003913 }
3914
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003915exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003916 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003917 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003918 mbedtls_psa_crypto_free( );
3919}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003920/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003921
3922/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00003923void crypto_generator_init( )
3924{
3925 /* Test each valid way of initializing the object, except for `= {0}`, as
3926 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
3927 * though it's OK by the C standard. We could test for this, but we'd need
3928 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003929 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00003930 psa_crypto_generator_t func = psa_crypto_generator_init( );
3931 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
3932 psa_crypto_generator_t zero;
3933
3934 memset( &zero, 0, sizeof( zero ) );
3935
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003936 /* A default generator should not be able to report its capacity. */
3937 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
3938 PSA_ERROR_BAD_STATE );
3939 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
3940 PSA_ERROR_BAD_STATE );
3941 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
3942 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003943
3944 /* A default generator should be abortable without error. */
3945 PSA_ASSERT( psa_generator_abort(&func) );
3946 PSA_ASSERT( psa_generator_abort(&init) );
3947 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00003948}
3949/* END_CASE */
3950
3951/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02003952void derive_setup( int key_type_arg,
3953 data_t *key_data,
3954 int alg_arg,
3955 data_t *salt,
3956 data_t *label,
3957 int requested_capacity_arg,
3958 int expected_status_arg )
3959{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003960 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003961 size_t key_type = key_type_arg;
3962 psa_algorithm_t alg = alg_arg;
3963 size_t requested_capacity = requested_capacity_arg;
3964 psa_status_t expected_status = expected_status_arg;
3965 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003966 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003967
Gilles Peskine8817f612018-12-18 00:18:46 +01003968 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003969
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003970 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
3971 psa_set_key_algorithm( &attributes, alg );
3972 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003973
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003974 PSA_ASSERT( psa_import_key( &attributes, &handle,
3975 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003976
Gilles Peskinefe11b722018-12-18 00:24:04 +01003977 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
3978 salt->x, salt->len,
3979 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003980 requested_capacity ),
3981 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003982
3983exit:
3984 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003985 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003986 mbedtls_psa_crypto_free( );
3987}
3988/* END_CASE */
3989
3990/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02003991void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03003992{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003993 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02003994 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03003995 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02003996 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03003997 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02003998 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02003999 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4000 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4001 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004002 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004003
Gilles Peskine8817f612018-12-18 00:18:46 +01004004 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004005
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004006 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4007 psa_set_key_algorithm( &attributes, alg );
4008 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004009
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004010 PSA_ASSERT( psa_import_key( &attributes, &handle,
4011 key_data, sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004012
4013 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004014 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4015 NULL, 0,
4016 NULL, 0,
4017 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004018
4019 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004020 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4021 NULL, 0,
4022 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004023 capacity ),
4024 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004025
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004026 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004027
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004028 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004029 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004030
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004031exit:
4032 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004033 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004034 mbedtls_psa_crypto_free( );
4035}
4036/* END_CASE */
4037
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004038/* BEGIN_CASE */
4039void test_derive_invalid_generator_tests( )
4040{
4041 uint8_t output_buffer[16];
4042 size_t buffer_size = 16;
4043 size_t capacity = 0;
4044 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4045
Nir Sonnenschein50789302018-10-31 12:16:38 +02004046 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004047 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004048
4049 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004050 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004051
Gilles Peskine8817f612018-12-18 00:18:46 +01004052 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004053
Nir Sonnenschein50789302018-10-31 12:16:38 +02004054 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004055 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004056
Nir Sonnenschein50789302018-10-31 12:16:38 +02004057 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004058 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004059
4060exit:
4061 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004062}
4063/* END_CASE */
4064
4065/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004066void derive_output( int alg_arg,
4067 data_t *key_data,
4068 data_t *salt,
4069 data_t *label,
4070 int requested_capacity_arg,
4071 data_t *expected_output1,
4072 data_t *expected_output2 )
4073{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004074 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004075 psa_algorithm_t alg = alg_arg;
4076 size_t requested_capacity = requested_capacity_arg;
4077 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4078 uint8_t *expected_outputs[2] =
4079 {expected_output1->x, expected_output2->x};
4080 size_t output_sizes[2] =
4081 {expected_output1->len, expected_output2->len};
4082 size_t output_buffer_size = 0;
4083 uint8_t *output_buffer = NULL;
4084 size_t expected_capacity;
4085 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004086 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004087 psa_status_t status;
4088 unsigned i;
4089
4090 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4091 {
4092 if( output_sizes[i] > output_buffer_size )
4093 output_buffer_size = output_sizes[i];
4094 if( output_sizes[i] == 0 )
4095 expected_outputs[i] = NULL;
4096 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004097 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004098 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004099
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004100 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4101 psa_set_key_algorithm( &attributes, alg );
4102 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004103
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004104 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004105 key_data->x, key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004106
4107 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004108 if( PSA_ALG_IS_HKDF( alg ) )
4109 {
4110 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4111 PSA_ASSERT( psa_set_generator_capacity( &generator,
4112 requested_capacity ) );
4113 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4114 PSA_KDF_STEP_SALT,
4115 salt->x, salt->len ) );
4116 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4117 PSA_KDF_STEP_SECRET,
4118 handle ) );
4119 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4120 PSA_KDF_STEP_INFO,
4121 label->x, label->len ) );
4122 }
4123 else
4124 {
4125 // legacy
4126 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4127 salt->x, salt->len,
4128 label->x, label->len,
4129 requested_capacity ) );
4130 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004131 PSA_ASSERT( psa_get_generator_capacity( &generator,
4132 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004133 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004134 expected_capacity = requested_capacity;
4135
4136 /* Expansion phase. */
4137 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4138 {
4139 /* Read some bytes. */
4140 status = psa_generator_read( &generator,
4141 output_buffer, output_sizes[i] );
4142 if( expected_capacity == 0 && output_sizes[i] == 0 )
4143 {
4144 /* Reading 0 bytes when 0 bytes are available can go either way. */
4145 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004146 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004147 continue;
4148 }
4149 else if( expected_capacity == 0 ||
4150 output_sizes[i] > expected_capacity )
4151 {
4152 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004153 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004154 expected_capacity = 0;
4155 continue;
4156 }
4157 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004158 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004159 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004160 ASSERT_COMPARE( output_buffer, output_sizes[i],
4161 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004162 /* Check the generator status. */
4163 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004164 PSA_ASSERT( psa_get_generator_capacity( &generator,
4165 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004166 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004167 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004168 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004169
4170exit:
4171 mbedtls_free( output_buffer );
4172 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004173 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004174 mbedtls_psa_crypto_free( );
4175}
4176/* END_CASE */
4177
4178/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004179void derive_full( int alg_arg,
4180 data_t *key_data,
4181 data_t *salt,
4182 data_t *label,
4183 int requested_capacity_arg )
4184{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004185 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004186 psa_algorithm_t alg = alg_arg;
4187 size_t requested_capacity = requested_capacity_arg;
4188 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4189 unsigned char output_buffer[16];
4190 size_t expected_capacity = requested_capacity;
4191 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004192 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004193
Gilles Peskine8817f612018-12-18 00:18:46 +01004194 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004195
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004196 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4197 psa_set_key_algorithm( &attributes, alg );
4198 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004199
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004200 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004201 key_data->x, key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004202
4203 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004204 if( PSA_ALG_IS_HKDF( alg ) )
4205 {
4206 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4207 PSA_ASSERT( psa_set_generator_capacity( &generator,
4208 requested_capacity ) );
4209 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4210 PSA_KDF_STEP_SALT,
4211 salt->x, salt->len ) );
4212 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4213 PSA_KDF_STEP_SECRET,
4214 handle ) );
4215 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4216 PSA_KDF_STEP_INFO,
4217 label->x, label->len ) );
4218 }
4219 else
4220 {
4221 // legacy
4222 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4223 salt->x, salt->len,
4224 label->x, label->len,
4225 requested_capacity ) );
4226 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004227 PSA_ASSERT( psa_get_generator_capacity( &generator,
4228 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004229 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004230
4231 /* Expansion phase. */
4232 while( current_capacity > 0 )
4233 {
4234 size_t read_size = sizeof( output_buffer );
4235 if( read_size > current_capacity )
4236 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004237 PSA_ASSERT( psa_generator_read( &generator,
4238 output_buffer,
4239 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004240 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004241 PSA_ASSERT( psa_get_generator_capacity( &generator,
4242 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004243 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004244 }
4245
4246 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004247 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004248 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004249
Gilles Peskine8817f612018-12-18 00:18:46 +01004250 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004251
4252exit:
4253 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004254 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004255 mbedtls_psa_crypto_free( );
4256}
4257/* END_CASE */
4258
4259/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004260void derive_key_exercise( int alg_arg,
4261 data_t *key_data,
4262 data_t *salt,
4263 data_t *label,
4264 int derived_type_arg,
4265 int derived_bits_arg,
4266 int derived_usage_arg,
4267 int derived_alg_arg )
4268{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004269 psa_key_handle_t base_handle = 0;
4270 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004271 psa_algorithm_t alg = alg_arg;
4272 psa_key_type_t derived_type = derived_type_arg;
4273 size_t derived_bits = derived_bits_arg;
4274 psa_key_usage_t derived_usage = derived_usage_arg;
4275 psa_algorithm_t derived_alg = derived_alg_arg;
4276 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4277 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004278 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004279 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004280
Gilles Peskine8817f612018-12-18 00:18:46 +01004281 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004282
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004283 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4284 psa_set_key_algorithm( &attributes, alg );
4285 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
4286 PSA_ASSERT( psa_import_key( &attributes, &base_handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004287 key_data->x, key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004288
4289 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004290 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4291 salt->x, salt->len,
4292 label->x, label->len,
4293 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004294 psa_set_key_usage_flags( &attributes, derived_usage );
4295 psa_set_key_algorithm( &attributes, derived_alg );
4296 psa_set_key_type( &attributes, derived_type );
4297 PSA_ASSERT( psa_generator_import_key( &attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004298 derived_bits,
4299 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004300
4301 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004302 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4303 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4304 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004305
4306 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004307 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004308 goto exit;
4309
4310exit:
4311 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004312 psa_destroy_key( base_handle );
4313 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004314 mbedtls_psa_crypto_free( );
4315}
4316/* END_CASE */
4317
4318/* BEGIN_CASE */
4319void derive_key_export( int alg_arg,
4320 data_t *key_data,
4321 data_t *salt,
4322 data_t *label,
4323 int bytes1_arg,
4324 int bytes2_arg )
4325{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004326 psa_key_handle_t base_handle = 0;
4327 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004328 psa_algorithm_t alg = alg_arg;
4329 size_t bytes1 = bytes1_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004330 size_t derived_bits = PSA_BYTES_TO_BITS( bytes1 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004331 size_t bytes2 = bytes2_arg;
4332 size_t capacity = bytes1 + bytes2;
4333 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004334 uint8_t *output_buffer = NULL;
4335 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004336 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4337 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004338 size_t length;
4339
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004340 ASSERT_ALLOC( output_buffer, capacity );
4341 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004342 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004343
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004344 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4345 psa_set_key_algorithm( &base_attributes, alg );
4346 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4347 PSA_ASSERT( psa_import_key( &base_attributes, &base_handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004348 key_data->x, key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004349
4350 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004351 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4352 salt->x, salt->len,
4353 label->x, label->len,
4354 capacity ) );
4355 PSA_ASSERT( psa_generator_read( &generator,
4356 output_buffer,
4357 capacity ) );
4358 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004359
4360 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004361 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4362 salt->x, salt->len,
4363 label->x, label->len,
4364 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004365 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4366 psa_set_key_algorithm( &derived_attributes, 0 );
4367 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
4368 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004369 derived_bits,
4370 &generator ) );
4371 PSA_ASSERT( psa_export_key( derived_handle,
4372 export_buffer, bytes1,
4373 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004374 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004375 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004376 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004377 PSA_BYTES_TO_BITS( bytes2 ),
4378 &generator ) );
4379 PSA_ASSERT( psa_export_key( derived_handle,
4380 export_buffer + bytes1, bytes2,
4381 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004382 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004383
4384 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004385 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4386 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004387
4388exit:
4389 mbedtls_free( output_buffer );
4390 mbedtls_free( export_buffer );
4391 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004392 psa_destroy_key( base_handle );
4393 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004394 mbedtls_psa_crypto_free( );
4395}
4396/* END_CASE */
4397
4398/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004399void key_agreement_setup( int alg_arg,
4400 int our_key_type_arg, data_t *our_key_data,
4401 data_t *peer_key_data,
4402 int expected_status_arg )
4403{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004404 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004405 psa_algorithm_t alg = alg_arg;
4406 psa_key_type_t our_key_type = our_key_type_arg;
4407 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004408 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004409 psa_status_t expected_status = expected_status_arg;
4410 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004411
Gilles Peskine8817f612018-12-18 00:18:46 +01004412 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004413
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004414 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4415 psa_set_key_algorithm( &attributes, alg );
4416 psa_set_key_type( &attributes, our_key_type );
4417 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004418 our_key_data->x, our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004419
Gilles Peskine77f40d82019-04-11 21:27:06 +02004420 /* The tests currently include inputs that should fail at either step.
4421 * Test cases that fail at the setup step should be changed to call
4422 * key_derivation_setup instead, and this function should be renamed
4423 * to key_agreement_fail. */
4424 status = psa_key_derivation_setup( &generator, alg );
4425 if( status == PSA_SUCCESS )
4426 {
4427 TEST_EQUAL( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
4428 our_key,
4429 peer_key_data->x, peer_key_data->len ),
4430 expected_status );
4431 }
4432 else
4433 {
4434 TEST_ASSERT( status == expected_status );
4435 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004436
4437exit:
4438 psa_generator_abort( &generator );
4439 psa_destroy_key( our_key );
4440 mbedtls_psa_crypto_free( );
4441}
4442/* END_CASE */
4443
4444/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004445void raw_key_agreement( int alg_arg,
4446 int our_key_type_arg, data_t *our_key_data,
4447 data_t *peer_key_data,
4448 data_t *expected_output )
4449{
4450 psa_key_handle_t our_key = 0;
4451 psa_algorithm_t alg = alg_arg;
4452 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004453 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004454 unsigned char *output = NULL;
4455 size_t output_length = ~0;
4456
4457 ASSERT_ALLOC( output, expected_output->len );
4458 PSA_ASSERT( psa_crypto_init( ) );
4459
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004460 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4461 psa_set_key_algorithm( &attributes, alg );
4462 psa_set_key_type( &attributes, our_key_type );
4463 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004464 our_key_data->x, our_key_data->len ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004465
4466 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4467 alg, our_key,
4468 peer_key_data->x, peer_key_data->len,
4469 output, expected_output->len, &output_length ) );
4470 ASSERT_COMPARE( output, output_length,
4471 expected_output->x, expected_output->len );
4472
4473exit:
4474 mbedtls_free( output );
4475 psa_destroy_key( our_key );
4476 mbedtls_psa_crypto_free( );
4477}
4478/* END_CASE */
4479
4480/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004481void key_agreement_capacity( int alg_arg,
4482 int our_key_type_arg, data_t *our_key_data,
4483 data_t *peer_key_data,
4484 int expected_capacity_arg )
4485{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004486 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004487 psa_algorithm_t alg = alg_arg;
4488 psa_key_type_t our_key_type = our_key_type_arg;
4489 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004490 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004491 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004492 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004493
Gilles Peskine8817f612018-12-18 00:18:46 +01004494 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004495
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004496 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4497 psa_set_key_algorithm( &attributes, alg );
4498 psa_set_key_type( &attributes, our_key_type );
4499 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004500 our_key_data->x, our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004501
Gilles Peskine969c5d62019-01-16 15:53:06 +01004502 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4503 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004504 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004505 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004506 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4507 {
4508 /* The test data is for info="" */
4509 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4510 PSA_KDF_STEP_INFO,
4511 NULL, 0 ) );
4512 }
Gilles Peskine59685592018-09-18 12:11:34 +02004513
Gilles Peskinebf491972018-10-25 22:36:12 +02004514 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004515 PSA_ASSERT( psa_get_generator_capacity(
4516 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004517 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004518
Gilles Peskinebf491972018-10-25 22:36:12 +02004519 /* Test the actual capacity by reading the output. */
4520 while( actual_capacity > sizeof( output ) )
4521 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004522 PSA_ASSERT( psa_generator_read( &generator,
4523 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004524 actual_capacity -= sizeof( output );
4525 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004526 PSA_ASSERT( psa_generator_read( &generator,
4527 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004528 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004529 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004530
Gilles Peskine59685592018-09-18 12:11:34 +02004531exit:
4532 psa_generator_abort( &generator );
4533 psa_destroy_key( our_key );
4534 mbedtls_psa_crypto_free( );
4535}
4536/* END_CASE */
4537
4538/* BEGIN_CASE */
4539void key_agreement_output( int alg_arg,
4540 int our_key_type_arg, data_t *our_key_data,
4541 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004542 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004543{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004544 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004545 psa_algorithm_t alg = alg_arg;
4546 psa_key_type_t our_key_type = our_key_type_arg;
4547 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004548 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004549 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004550
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004551 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4552 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004553
Gilles Peskine8817f612018-12-18 00:18:46 +01004554 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004555
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004556 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4557 psa_set_key_algorithm( &attributes, alg );
4558 psa_set_key_type( &attributes, our_key_type );
4559 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004560 our_key_data->x, our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004561
Gilles Peskine969c5d62019-01-16 15:53:06 +01004562 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4563 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004564 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004565 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004566 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4567 {
4568 /* The test data is for info="" */
4569 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4570 PSA_KDF_STEP_INFO,
4571 NULL, 0 ) );
4572 }
Gilles Peskine59685592018-09-18 12:11:34 +02004573
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004574 PSA_ASSERT( psa_generator_read( &generator,
4575 actual_output,
4576 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004577 ASSERT_COMPARE( actual_output, expected_output1->len,
4578 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004579 if( expected_output2->len != 0 )
4580 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004581 PSA_ASSERT( psa_generator_read( &generator,
4582 actual_output,
4583 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004584 ASSERT_COMPARE( actual_output, expected_output2->len,
4585 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004586 }
Gilles Peskine59685592018-09-18 12:11:34 +02004587
4588exit:
4589 psa_generator_abort( &generator );
4590 psa_destroy_key( our_key );
4591 mbedtls_psa_crypto_free( );
4592 mbedtls_free( actual_output );
4593}
4594/* END_CASE */
4595
4596/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004597void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004598{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004599 size_t bytes = bytes_arg;
4600 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004601 unsigned char *output = NULL;
4602 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004603 size_t i;
4604 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004605
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004606 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4607 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004608 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004609
Gilles Peskine8817f612018-12-18 00:18:46 +01004610 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004611
Gilles Peskinea50d7392018-06-21 10:22:13 +02004612 /* Run several times, to ensure that every output byte will be
4613 * nonzero at least once with overwhelming probability
4614 * (2^(-8*number_of_runs)). */
4615 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004616 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004617 if( bytes != 0 )
4618 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004619 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004620
4621 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004622 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4623 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004624
4625 for( i = 0; i < bytes; i++ )
4626 {
4627 if( output[i] != 0 )
4628 ++changed[i];
4629 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004630 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004631
4632 /* Check that every byte was changed to nonzero at least once. This
4633 * validates that psa_generate_random is overwriting every byte of
4634 * the output buffer. */
4635 for( i = 0; i < bytes; i++ )
4636 {
4637 TEST_ASSERT( changed[i] != 0 );
4638 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004639
4640exit:
4641 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004642 mbedtls_free( output );
4643 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004644}
4645/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004646
4647/* BEGIN_CASE */
4648void generate_key( int type_arg,
4649 int bits_arg,
4650 int usage_arg,
4651 int alg_arg,
4652 int expected_status_arg )
4653{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004654 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004655 psa_key_type_t type = type_arg;
4656 psa_key_usage_t usage = usage_arg;
4657 size_t bits = bits_arg;
4658 psa_algorithm_t alg = alg_arg;
4659 psa_status_t expected_status = expected_status_arg;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004660 psa_status_t expected_info_status =
David Saadab4ecc272019-02-14 13:48:10 +02004661 expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004662 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004663 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004664
Gilles Peskine8817f612018-12-18 00:18:46 +01004665 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004666
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004667 psa_set_key_usage_flags( &attributes, usage );
4668 psa_set_key_algorithm( &attributes, alg );
4669 psa_set_key_type( &attributes, type );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004670
4671 /* Generate a key */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004672 TEST_EQUAL( psa_generate_key( &attributes, &handle, bits, NULL, 0 ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004673 expected_status );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004674 if( expected_info_status != PSA_SUCCESS )
4675 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004676
4677 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004678 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4679 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4680 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004681
Gilles Peskine818ca122018-06-20 18:16:48 +02004682 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004683 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004684 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004685
4686exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004687 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004688 mbedtls_psa_crypto_free( );
4689}
4690/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004691
Darryl Greend49a4992018-06-18 17:27:26 +01004692/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004693void persistent_key_load_key_from_storage( data_t *data,
4694 int type_arg, int bits_arg,
4695 int usage_flags_arg, int alg_arg,
4696 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004697{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004698 psa_key_id_t key_id = 1;
4699 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004700 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004701 psa_key_handle_t base_key = 0;
4702 psa_key_type_t type = type_arg;
4703 size_t bits = bits_arg;
4704 psa_key_usage_t usage_flags = usage_flags_arg;
4705 psa_algorithm_t alg = alg_arg;
Darryl Green0c6575a2018-11-07 16:05:30 +00004706 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004707 unsigned char *first_export = NULL;
4708 unsigned char *second_export = NULL;
4709 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4710 size_t first_exported_length;
4711 size_t second_exported_length;
4712
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004713 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4714 {
4715 ASSERT_ALLOC( first_export, export_size );
4716 ASSERT_ALLOC( second_export, export_size );
4717 }
Darryl Greend49a4992018-06-18 17:27:26 +01004718
Gilles Peskine8817f612018-12-18 00:18:46 +01004719 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004720
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004721 psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT );
4722 psa_set_key_usage_flags( &attributes, usage_flags );
4723 psa_set_key_algorithm( &attributes, alg );
4724 psa_set_key_type( &attributes, type );
Darryl Greend49a4992018-06-18 17:27:26 +01004725
Darryl Green0c6575a2018-11-07 16:05:30 +00004726 switch( generation_method )
4727 {
4728 case IMPORT_KEY:
4729 /* Import the key */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004730 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004731 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004732 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004733
Darryl Green0c6575a2018-11-07 16:05:30 +00004734 case GENERATE_KEY:
4735 /* Generate a key */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004736 PSA_ASSERT( psa_generate_key( &attributes, &handle,
4737 bits, NULL, 0 ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004738 break;
4739
4740 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004741 {
4742 /* Create base key */
4743 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4744 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4745 psa_set_key_usage_flags( &base_attributes,
4746 PSA_KEY_USAGE_DERIVE );
4747 psa_set_key_algorithm( &base_attributes, derive_alg );
4748 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4749 PSA_ASSERT( psa_import_key( &base_attributes, &base_key,
4750 data->x, data->len ) );
4751 /* Derive a key. */
4752 PSA_ASSERT( psa_key_derivation_setup( &generator, derive_alg ) );
4753 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4754 PSA_KDF_STEP_SECRET,
4755 base_key ) );
4756 PSA_ASSERT( psa_key_derivation_input_bytes(
4757 &generator, PSA_KDF_STEP_INFO,
4758 NULL, 0 ) );
4759 PSA_ASSERT( psa_generator_import_key( &attributes, &handle,
4760 bits, &generator ) );
4761 PSA_ASSERT( psa_generator_abort( &generator ) );
4762 PSA_ASSERT( psa_destroy_key( base_key ) );
4763 base_key = 0;
4764 }
Darryl Green0c6575a2018-11-07 16:05:30 +00004765 break;
4766 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004767 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004768
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004769 /* Export the key if permitted by the key policy. */
4770 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4771 {
4772 PSA_ASSERT( psa_export_key( handle,
4773 first_export, export_size,
4774 &first_exported_length ) );
4775 if( generation_method == IMPORT_KEY )
4776 ASSERT_COMPARE( data->x, data->len,
4777 first_export, first_exported_length );
4778 }
Darryl Greend49a4992018-06-18 17:27:26 +01004779
4780 /* Shutdown and restart */
4781 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004782 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004783
Darryl Greend49a4992018-06-18 17:27:26 +01004784 /* Check key slot still contains key data */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004785 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
Gilles Peskine8817f612018-12-18 00:18:46 +01004786 &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004787 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4788 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4789 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4790 PSA_KEY_LIFETIME_PERSISTENT );
4791 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4792 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4793 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4794 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004795
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004796 /* Export the key again if permitted by the key policy. */
4797 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004798 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004799 PSA_ASSERT( psa_export_key( handle,
4800 second_export, export_size,
4801 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004802 ASSERT_COMPARE( first_export, first_exported_length,
4803 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004804 }
4805
4806 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004807 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004808 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004809
4810exit:
4811 mbedtls_free( first_export );
4812 mbedtls_free( second_export );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004813 psa_generator_abort( &generator );
4814 psa_destroy_key( base_key );
4815 if( handle == 0 )
4816 {
4817 /* In case there was a test failure after creating the persistent key
4818 * but while it was not open, try to re-open the persistent key
4819 * to delete it. */
4820 psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle );
4821 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004822 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004823 mbedtls_psa_crypto_free();
4824}
4825/* END_CASE */