blob: 4c28b80a60be0b1875d5a09f9336ea84bc2480c0 [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 );
Gilles Peskine049c7532019-05-15 20:22:09 +0200219 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
220 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100221
222 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100223 /* Whether setup succeeded or failed, abort must succeed. */
224 PSA_ASSERT( psa_mac_abort( operation ) );
225 /* If setup failed, reproduce the failure, so that the caller can
226 * test the resulting state of the operation object. */
227 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100228 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100229 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
230 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100231 }
232
233 psa_destroy_key( handle );
234 return( 1 );
235
236exit:
237 psa_destroy_key( handle );
238 return( 0 );
239}
240
241int exercise_cipher_setup( psa_key_type_t key_type,
242 const unsigned char *key_bytes,
243 size_t key_length,
244 psa_algorithm_t alg,
245 psa_cipher_operation_t *operation,
246 psa_status_t *status )
247{
248 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200249 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100250
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200251 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
252 psa_set_key_algorithm( &attributes, alg );
253 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200254 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
255 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100256
257 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100258 /* Whether setup succeeded or failed, abort must succeed. */
259 PSA_ASSERT( psa_cipher_abort( operation ) );
260 /* If setup failed, reproduce the failure, so that the caller can
261 * test the resulting state of the operation object. */
262 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100263 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100264 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
265 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100266 }
267
268 psa_destroy_key( handle );
269 return( 1 );
270
271exit:
272 psa_destroy_key( handle );
273 return( 0 );
274}
275
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100276static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200277 psa_key_usage_t usage,
278 psa_algorithm_t alg )
279{
Jaeden Amero769ce272019-01-04 11:48:03 +0000280 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200281 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200282 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200283 size_t mac_length = sizeof( mac );
284
285 if( usage & PSA_KEY_USAGE_SIGN )
286 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100287 PSA_ASSERT( psa_mac_sign_setup( &operation,
288 handle, alg ) );
289 PSA_ASSERT( psa_mac_update( &operation,
290 input, sizeof( input ) ) );
291 PSA_ASSERT( psa_mac_sign_finish( &operation,
292 mac, sizeof( mac ),
293 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200294 }
295
296 if( usage & PSA_KEY_USAGE_VERIFY )
297 {
298 psa_status_t verify_status =
299 ( usage & PSA_KEY_USAGE_SIGN ?
300 PSA_SUCCESS :
301 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100302 PSA_ASSERT( psa_mac_verify_setup( &operation,
303 handle, alg ) );
304 PSA_ASSERT( psa_mac_update( &operation,
305 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100306 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
307 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200308 }
309
310 return( 1 );
311
312exit:
313 psa_mac_abort( &operation );
314 return( 0 );
315}
316
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100317static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200318 psa_key_usage_t usage,
319 psa_algorithm_t alg )
320{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000321 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200322 unsigned char iv[16] = {0};
323 size_t iv_length = sizeof( iv );
324 const unsigned char plaintext[16] = "Hello, world...";
325 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
326 size_t ciphertext_length = sizeof( ciphertext );
327 unsigned char decrypted[sizeof( ciphertext )];
328 size_t part_length;
329
330 if( usage & PSA_KEY_USAGE_ENCRYPT )
331 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100332 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
333 handle, alg ) );
334 PSA_ASSERT( psa_cipher_generate_iv( &operation,
335 iv, sizeof( iv ),
336 &iv_length ) );
337 PSA_ASSERT( psa_cipher_update( &operation,
338 plaintext, sizeof( plaintext ),
339 ciphertext, sizeof( ciphertext ),
340 &ciphertext_length ) );
341 PSA_ASSERT( psa_cipher_finish( &operation,
342 ciphertext + ciphertext_length,
343 sizeof( ciphertext ) - ciphertext_length,
344 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200345 ciphertext_length += part_length;
346 }
347
348 if( usage & PSA_KEY_USAGE_DECRYPT )
349 {
350 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200351 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200352 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
353 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200354 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
355 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
356 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
357 * have this macro yet. */
358 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
359 psa_get_key_type( &attributes ) );
360 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200361 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100362 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
363 handle, alg ) );
364 PSA_ASSERT( psa_cipher_set_iv( &operation,
365 iv, iv_length ) );
366 PSA_ASSERT( psa_cipher_update( &operation,
367 ciphertext, ciphertext_length,
368 decrypted, sizeof( decrypted ),
369 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200370 status = psa_cipher_finish( &operation,
371 decrypted + part_length,
372 sizeof( decrypted ) - part_length,
373 &part_length );
374 /* For a stream cipher, all inputs are valid. For a block cipher,
375 * if the input is some aribtrary data rather than an actual
376 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200377 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200378 TEST_ASSERT( status == PSA_SUCCESS ||
379 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200380 else
381 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200382 }
383
384 return( 1 );
385
386exit:
387 psa_cipher_abort( &operation );
388 return( 0 );
389}
390
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100391static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200392 psa_key_usage_t usage,
393 psa_algorithm_t alg )
394{
395 unsigned char nonce[16] = {0};
396 size_t nonce_length = sizeof( nonce );
397 unsigned char plaintext[16] = "Hello, world...";
398 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
399 size_t ciphertext_length = sizeof( ciphertext );
400 size_t plaintext_length = sizeof( ciphertext );
401
402 if( usage & PSA_KEY_USAGE_ENCRYPT )
403 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100404 PSA_ASSERT( psa_aead_encrypt( handle, alg,
405 nonce, nonce_length,
406 NULL, 0,
407 plaintext, sizeof( plaintext ),
408 ciphertext, sizeof( ciphertext ),
409 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200410 }
411
412 if( usage & PSA_KEY_USAGE_DECRYPT )
413 {
414 psa_status_t verify_status =
415 ( usage & PSA_KEY_USAGE_ENCRYPT ?
416 PSA_SUCCESS :
417 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100418 TEST_EQUAL( psa_aead_decrypt( handle, alg,
419 nonce, nonce_length,
420 NULL, 0,
421 ciphertext, ciphertext_length,
422 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100423 &plaintext_length ),
424 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200425 }
426
427 return( 1 );
428
429exit:
430 return( 0 );
431}
432
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100433static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200434 psa_key_usage_t usage,
435 psa_algorithm_t alg )
436{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200437 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
438 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200439 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200440 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100441 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
442
443 /* If the policy allows signing with any hash, just pick one. */
444 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
445 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100446#if defined(KNOWN_SUPPORTED_HASH_ALG)
447 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
448 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100449#else
450 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100451 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100452#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100453 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200454
455 if( usage & PSA_KEY_USAGE_SIGN )
456 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200457 /* Some algorithms require the payload to have the size of
458 * the hash encoded in the algorithm. Use this input size
459 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200460 if( hash_alg != 0 )
461 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100462 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
463 payload, payload_length,
464 signature, sizeof( signature ),
465 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200466 }
467
468 if( usage & PSA_KEY_USAGE_VERIFY )
469 {
470 psa_status_t verify_status =
471 ( usage & PSA_KEY_USAGE_SIGN ?
472 PSA_SUCCESS :
473 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100474 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
475 payload, payload_length,
476 signature, signature_length ),
477 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200478 }
479
480 return( 1 );
481
482exit:
483 return( 0 );
484}
485
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100486static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200487 psa_key_usage_t usage,
488 psa_algorithm_t alg )
489{
490 unsigned char plaintext[256] = "Hello, world...";
491 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
492 size_t ciphertext_length = sizeof( ciphertext );
493 size_t plaintext_length = 16;
494
495 if( usage & PSA_KEY_USAGE_ENCRYPT )
496 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100497 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
498 plaintext, plaintext_length,
499 NULL, 0,
500 ciphertext, sizeof( ciphertext ),
501 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200502 }
503
504 if( usage & PSA_KEY_USAGE_DECRYPT )
505 {
506 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100507 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200508 ciphertext, ciphertext_length,
509 NULL, 0,
510 plaintext, sizeof( plaintext ),
511 &plaintext_length );
512 TEST_ASSERT( status == PSA_SUCCESS ||
513 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
514 ( status == PSA_ERROR_INVALID_ARGUMENT ||
515 status == PSA_ERROR_INVALID_PADDING ) ) );
516 }
517
518 return( 1 );
519
520exit:
521 return( 0 );
522}
Gilles Peskine02b75072018-07-01 22:31:34 +0200523
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100524static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200525 psa_key_usage_t usage,
526 psa_algorithm_t alg )
527{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200528 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +0200529 unsigned char label[16] = "This is a label.";
530 size_t label_length = sizeof( label );
531 unsigned char seed[16] = "abcdefghijklmnop";
532 size_t seed_length = sizeof( seed );
533 unsigned char output[1];
534
535 if( usage & PSA_KEY_USAGE_DERIVE )
536 {
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100537 if( PSA_ALG_IS_HKDF( alg ) )
538 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200539 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
540 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200541 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100542 label,
543 label_length ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200544 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200545 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100546 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200547 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +0200548 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100549 seed,
550 seed_length ) );
551 }
552 else
553 {
554 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200555 PSA_ASSERT( psa_key_derivation( &operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100556 handle, alg,
557 label, label_length,
558 seed, seed_length,
559 sizeof( output ) ) );
560 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200561 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +0100562 output,
563 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200564 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200565 }
566
567 return( 1 );
568
569exit:
570 return( 0 );
571}
572
Gilles Peskinec7998b72018-11-07 18:45:02 +0100573/* We need two keys to exercise key agreement. Exercise the
574 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200575static psa_status_t key_agreement_with_self( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +0100576 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100577{
578 psa_key_type_t private_key_type;
579 psa_key_type_t public_key_type;
580 size_t key_bits;
581 uint8_t *public_key = NULL;
582 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200583 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinea99d3fb2019-05-16 15:28:51 +0200584 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory, but it's
Gilles Peskinec7998b72018-11-07 18:45:02 +0100585 * good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200586 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200587 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100588
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200589 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
590 private_key_type = psa_get_key_type( &attributes );
591 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100592 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
593 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
594 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100595 PSA_ASSERT( psa_export_public_key( handle,
596 public_key, public_key_length,
597 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100598
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200599 status = psa_key_derivation_key_agreement( operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
Gilles Peskine969c5d62019-01-16 15:53:06 +0100600 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100601exit:
602 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200603 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100604 return( status );
605}
606
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200607/* We need two keys to exercise key agreement. Exercise the
608 * private key against its own public key. */
609static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
610 psa_key_handle_t handle )
611{
612 psa_key_type_t private_key_type;
613 psa_key_type_t public_key_type;
614 size_t key_bits;
615 uint8_t *public_key = NULL;
616 size_t public_key_length;
617 uint8_t output[1024];
618 size_t output_length;
619 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinea99d3fb2019-05-16 15:28:51 +0200620 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory, but it's
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200621 * good enough: callers will report it as a failed test anyway. */
622 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200623 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200624
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200625 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
626 private_key_type = psa_get_key_type( &attributes );
627 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200628 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
629 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
630 ASSERT_ALLOC( public_key, public_key_length );
631 PSA_ASSERT( psa_export_public_key( handle,
632 public_key, public_key_length,
633 &public_key_length ) );
634
635 status = psa_key_agreement_raw_shared_secret(
636 alg, handle,
637 public_key, public_key_length,
638 output, sizeof( output ), &output_length );
639exit:
640 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200641 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200642 return( status );
643}
644
645static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
646 psa_key_usage_t usage,
647 psa_algorithm_t alg )
648{
649 int ok = 0;
650
651 if( usage & PSA_KEY_USAGE_DERIVE )
652 {
653 /* We need two keys to exercise key agreement. Exercise the
654 * private key against its own public key. */
655 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
656 }
657 ok = 1;
658
659exit:
660 return( ok );
661}
662
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100663static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200664 psa_key_usage_t usage,
665 psa_algorithm_t alg )
666{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200667 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200668 unsigned char output[1];
669 int ok = 0;
670
671 if( usage & PSA_KEY_USAGE_DERIVE )
672 {
673 /* We need two keys to exercise key agreement. Exercise the
674 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200675 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
676 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
677 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +0100678 output,
679 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200680 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200681 }
682 ok = 1;
683
684exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200685 return( ok );
686}
687
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200688static int is_oid_of_key_type( psa_key_type_t type,
689 const uint8_t *oid, size_t oid_length )
690{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200691 const uint8_t *expected_oid = NULL;
692 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200693#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200694 if( PSA_KEY_TYPE_IS_RSA( type ) )
695 {
696 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
697 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
698 }
699 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200700#endif /* MBEDTLS_RSA_C */
701#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200702 if( PSA_KEY_TYPE_IS_ECC( type ) )
703 {
704 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
705 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
706 }
707 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200708#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200709 {
710 char message[40];
711 mbedtls_snprintf( message, sizeof( message ),
712 "OID not known for key type=0x%08lx",
713 (unsigned long) type );
714 test_fail( message, __LINE__, __FILE__ );
715 return( 0 );
716 }
717
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200718 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200719 return( 1 );
720
721exit:
722 return( 0 );
723}
724
725static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
726 size_t min_bits, size_t max_bits,
727 int must_be_odd )
728{
729 size_t len;
730 size_t actual_bits;
731 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100732 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100733 MBEDTLS_ASN1_INTEGER ),
734 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200735 /* Tolerate a slight departure from DER encoding:
736 * - 0 may be represented by an empty string or a 1-byte string.
737 * - The sign bit may be used as a value bit. */
738 if( ( len == 1 && ( *p )[0] == 0 ) ||
739 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
740 {
741 ++( *p );
742 --len;
743 }
744 if( min_bits == 0 && len == 0 )
745 return( 1 );
746 msb = ( *p )[0];
747 TEST_ASSERT( msb != 0 );
748 actual_bits = 8 * ( len - 1 );
749 while( msb != 0 )
750 {
751 msb >>= 1;
752 ++actual_bits;
753 }
754 TEST_ASSERT( actual_bits >= min_bits );
755 TEST_ASSERT( actual_bits <= max_bits );
756 if( must_be_odd )
757 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
758 *p += len;
759 return( 1 );
760exit:
761 return( 0 );
762}
763
764static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
765 size_t *len,
766 unsigned char n, unsigned char tag )
767{
768 int ret;
769 ret = mbedtls_asn1_get_tag( p, end, len,
770 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
771 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
772 if( ret != 0 )
773 return( ret );
774 end = *p + *len;
775 ret = mbedtls_asn1_get_tag( p, end, len, tag );
776 if( ret != 0 )
777 return( ret );
778 if( *p + *len != end )
779 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
780 return( 0 );
781}
782
783static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
784 uint8_t *exported, size_t exported_length )
785{
786 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100787 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200788 else
789 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200790
791#if defined(MBEDTLS_DES_C)
792 if( type == PSA_KEY_TYPE_DES )
793 {
794 /* Check the parity bits. */
795 unsigned i;
796 for( i = 0; i < bits / 8; i++ )
797 {
798 unsigned bit_count = 0;
799 unsigned m;
800 for( m = 1; m <= 0x100; m <<= 1 )
801 {
802 if( exported[i] & m )
803 ++bit_count;
804 }
805 TEST_ASSERT( bit_count % 2 != 0 );
806 }
807 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200808 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200809#endif
810
811#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
812 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
813 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200814 uint8_t *p = exported;
815 uint8_t *end = exported + exported_length;
816 size_t len;
817 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200818 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200819 * modulus INTEGER, -- n
820 * publicExponent INTEGER, -- e
821 * privateExponent INTEGER, -- d
822 * prime1 INTEGER, -- p
823 * prime2 INTEGER, -- q
824 * exponent1 INTEGER, -- d mod (p-1)
825 * exponent2 INTEGER, -- d mod (q-1)
826 * coefficient INTEGER, -- (inverse of q) mod p
827 * }
828 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100829 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
830 MBEDTLS_ASN1_SEQUENCE |
831 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
832 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200833 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
834 goto exit;
835 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
836 goto exit;
837 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
838 goto exit;
839 /* Require d to be at least half the size of n. */
840 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
841 goto exit;
842 /* Require p and q to be at most half the size of n, rounded up. */
843 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
844 goto exit;
845 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
846 goto exit;
847 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
848 goto exit;
849 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
850 goto exit;
851 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
852 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100853 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100854 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200855 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200856#endif /* MBEDTLS_RSA_C */
857
858#if defined(MBEDTLS_ECP_C)
859 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
860 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100861 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100862 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100863 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200864 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200865#endif /* MBEDTLS_ECP_C */
866
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200867 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
868 {
869 uint8_t *p = exported;
870 uint8_t *end = exported + exported_length;
871 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200872#if defined(MBEDTLS_RSA_C)
873 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
874 {
875 /* RSAPublicKey ::= SEQUENCE {
876 * modulus INTEGER, -- n
877 * publicExponent INTEGER } -- e
878 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100879 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
880 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100881 MBEDTLS_ASN1_CONSTRUCTED ),
882 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100883 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200884 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
885 goto exit;
886 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
887 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100888 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200889 }
890 else
891#endif /* MBEDTLS_RSA_C */
892#if defined(MBEDTLS_ECP_C)
893 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
894 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000895 /* The representation of an ECC public key is:
896 * - The byte 0x04;
897 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
898 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
899 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000900 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100901 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
902 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200903 }
904 else
905#endif /* MBEDTLS_ECP_C */
906 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100907 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200908 mbedtls_snprintf( message, sizeof( message ),
909 "No sanity check for public key type=0x%08lx",
910 (unsigned long) type );
911 test_fail( message, __LINE__, __FILE__ );
912 return( 0 );
913 }
914 }
915 else
916
917 {
918 /* No sanity checks for other types */
919 }
920
921 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200922
923exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200924 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200925}
926
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100927static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200928 psa_key_usage_t usage )
929{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200930 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200931 uint8_t *exported = NULL;
932 size_t exported_size = 0;
933 size_t exported_length = 0;
934 int ok = 0;
935
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200936 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200937
938 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200939 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200940 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100941 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
942 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200943 ok = 1;
944 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200945 }
946
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200947 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
948 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200949 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200950
Gilles Peskine8817f612018-12-18 00:18:46 +0100951 PSA_ASSERT( psa_export_key( handle,
952 exported, exported_size,
953 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200954 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
955 psa_get_key_bits( &attributes ),
956 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200957
958exit:
959 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200960 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200961 return( ok );
962}
963
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100964static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200965{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200966 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200967 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200968 uint8_t *exported = NULL;
969 size_t exported_size = 0;
970 size_t exported_length = 0;
971 int ok = 0;
972
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200973 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
974 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200975 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100976 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100977 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200978 return( 1 );
979 }
980
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200981 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
982 psa_get_key_type( &attributes ) );
983 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
984 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200985 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200986
Gilles Peskine8817f612018-12-18 00:18:46 +0100987 PSA_ASSERT( psa_export_public_key( handle,
988 exported, exported_size,
989 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200990 ok = exported_key_sanity_check( public_type,
991 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200992 exported, exported_length );
993
994exit:
995 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200996 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200997 return( ok );
998}
999
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001000/** Do smoke tests on a key.
1001 *
1002 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1003 * sign/verify, or derivation) that is permitted according to \p usage.
1004 * \p usage and \p alg should correspond to the expected policy on the
1005 * key.
1006 *
1007 * Export the key if permitted by \p usage, and check that the output
1008 * looks sensible. If \p usage forbids export, check that
1009 * \p psa_export_key correctly rejects the attempt. If the key is
1010 * asymmetric, also check \p psa_export_public_key.
1011 *
1012 * If the key fails the tests, this function calls the test framework's
1013 * `test_fail` function and returns false. Otherwise this function returns
1014 * true. Therefore it should be used as follows:
1015 * ```
1016 * if( ! exercise_key( ... ) ) goto exit;
1017 * ```
1018 *
1019 * \param handle The key to exercise. It should be capable of performing
1020 * \p alg.
1021 * \param usage The usage flags to assume.
1022 * \param alg The algorithm to exercise.
1023 *
1024 * \retval 0 The key failed the smoke tests.
1025 * \retval 1 The key passed the smoke tests.
1026 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001027static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001028 psa_key_usage_t usage,
1029 psa_algorithm_t alg )
1030{
1031 int ok;
1032 if( alg == 0 )
1033 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1034 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001035 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001036 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001037 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001038 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001039 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001040 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001041 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001042 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001043 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001044 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001045 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001046 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1047 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001048 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001049 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001050 else
1051 {
1052 char message[40];
1053 mbedtls_snprintf( message, sizeof( message ),
1054 "No code to exercise alg=0x%08lx",
1055 (unsigned long) alg );
1056 test_fail( message, __LINE__, __FILE__ );
1057 ok = 0;
1058 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001059
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001060 ok = ok && exercise_export_key( handle, usage );
1061 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001062
Gilles Peskine02b75072018-07-01 22:31:34 +02001063 return( ok );
1064}
1065
Gilles Peskine10df3412018-10-25 22:35:43 +02001066static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1067 psa_algorithm_t alg )
1068{
1069 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1070 {
1071 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1072 PSA_KEY_USAGE_VERIFY :
1073 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1074 }
1075 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1076 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1077 {
1078 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1079 PSA_KEY_USAGE_ENCRYPT :
1080 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1081 }
1082 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1083 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1084 {
1085 return( PSA_KEY_USAGE_DERIVE );
1086 }
1087 else
1088 {
1089 return( 0 );
1090 }
1091
1092}
Darryl Green0c6575a2018-11-07 16:05:30 +00001093
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001094static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1095{
1096 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1097 uint8_t buffer[1];
1098 size_t length;
1099 int ok = 0;
1100
Gilles Peskinec87af662019-05-15 16:12:22 +02001101 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001102 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1103 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1104 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1105 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1106 PSA_ERROR_INVALID_HANDLE );
1107 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001108 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001109 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1110 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1111 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1112 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1113
1114 TEST_EQUAL( psa_export_key( handle,
1115 buffer, sizeof( buffer ), &length ),
1116 PSA_ERROR_INVALID_HANDLE );
1117 TEST_EQUAL( psa_export_public_key( handle,
1118 buffer, sizeof( buffer ), &length ),
1119 PSA_ERROR_INVALID_HANDLE );
1120
1121 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1122 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1123
1124 ok = 1;
1125
1126exit:
1127 psa_reset_key_attributes( &attributes );
1128 return( ok );
1129}
1130
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001131/* An overapproximation of the amount of storage needed for a key of the
1132 * given type and with the given content. The API doesn't make it easy
1133 * to find a good value for the size. The current implementation doesn't
1134 * care about the value anyway. */
1135#define KEY_BITS_FROM_DATA( type, data ) \
1136 ( data )->len
1137
Darryl Green0c6575a2018-11-07 16:05:30 +00001138typedef enum {
1139 IMPORT_KEY = 0,
1140 GENERATE_KEY = 1,
1141 DERIVE_KEY = 2
1142} generate_method;
1143
Gilles Peskinee59236f2018-01-27 23:32:46 +01001144/* END_HEADER */
1145
1146/* BEGIN_DEPENDENCIES
1147 * depends_on:MBEDTLS_PSA_CRYPTO_C
1148 * END_DEPENDENCIES
1149 */
1150
1151/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001152void static_checks( )
1153{
1154 size_t max_truncated_mac_size =
1155 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1156
1157 /* Check that the length for a truncated MAC always fits in the algorithm
1158 * encoding. The shifted mask is the maximum truncated value. The
1159 * untruncated algorithm may be one byte larger. */
1160 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1161}
1162/* END_CASE */
1163
1164/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001165void attributes_set_get( int id_arg, int lifetime_arg,
1166 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001167 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001168{
Gilles Peskine4747d192019-04-17 15:05:45 +02001169 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001170 psa_key_id_t id = id_arg;
1171 psa_key_lifetime_t lifetime = lifetime_arg;
1172 psa_key_usage_t usage_flags = usage_flags_arg;
1173 psa_algorithm_t alg = alg_arg;
1174 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001175 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001176
1177 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1178 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1179 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001182 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001183
Gilles Peskinec87af662019-05-15 16:12:22 +02001184 psa_set_key_id( &attributes, id );
1185 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001186 psa_set_key_usage_flags( &attributes, usage_flags );
1187 psa_set_key_algorithm( &attributes, alg );
1188 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001189 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001190
1191 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1192 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1193 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1194 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1195 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001196 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001197
1198 psa_reset_key_attributes( &attributes );
1199
1200 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1201 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1202 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1203 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1204 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001205 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001206}
1207/* END_CASE */
1208
1209/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001210void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1211 int expected_id_arg, int expected_lifetime_arg )
1212{
1213 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1214 psa_key_id_t id1 = id1_arg;
1215 psa_key_lifetime_t lifetime = lifetime_arg;
1216 psa_key_id_t id2 = id2_arg;
1217 psa_key_id_t expected_id = expected_id_arg;
1218 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1219
1220 if( id1_arg != -1 )
1221 psa_set_key_id( &attributes, id1 );
1222 if( lifetime_arg != -1 )
1223 psa_set_key_lifetime( &attributes, lifetime );
1224 if( id2_arg != -1 )
1225 psa_set_key_id( &attributes, id2 );
1226
1227 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1228 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1229}
1230/* END_CASE */
1231
1232/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001233void import( data_t *data, int type_arg,
1234 int attr_bits_arg,
1235 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001236{
1237 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1238 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001239 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001240 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001241 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001242 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001243 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001244
Gilles Peskine8817f612018-12-18 00:18:46 +01001245 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001246
Gilles Peskine4747d192019-04-17 15:05:45 +02001247 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001248 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001249 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001250 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001251 if( status != PSA_SUCCESS )
1252 goto exit;
1253
1254 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1255 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001256 if( attr_bits != 0 )
1257 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001258
1259 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001260 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001261
1262exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001263 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001264 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001265 mbedtls_psa_crypto_free( );
1266}
1267/* END_CASE */
1268
1269/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001270void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1271{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001272 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001273 size_t bits = bits_arg;
1274 psa_status_t expected_status = expected_status_arg;
1275 psa_status_t status;
1276 psa_key_type_t type =
1277 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1278 size_t buffer_size = /* Slight overapproximations */
1279 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001280 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001281 unsigned char *p;
1282 int ret;
1283 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001284 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001285
Gilles Peskine8817f612018-12-18 00:18:46 +01001286 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001287 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001288
1289 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1290 bits, keypair ) ) >= 0 );
1291 length = ret;
1292
1293 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001294 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001295 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001296 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001297 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001298 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001299
1300exit:
1301 mbedtls_free( buffer );
1302 mbedtls_psa_crypto_free( );
1303}
1304/* END_CASE */
1305
1306/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001307void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001308 int type_arg,
1309 int alg_arg,
1310 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001311 int expected_bits,
1312 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001313 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001314 int canonical_input )
1315{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001316 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001318 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001319 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001320 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001321 unsigned char *exported = NULL;
1322 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001323 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001324 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001325 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001326 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001327 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001328
Moran Pekercb088e72018-07-17 17:36:59 +03001329 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001330 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001331 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001332 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001333 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001334
Gilles Peskine4747d192019-04-17 15:05:45 +02001335 psa_set_key_usage_flags( &attributes, usage_arg );
1336 psa_set_key_algorithm( &attributes, alg );
1337 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001338
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001339 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001340 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001341
1342 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001343 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1344 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1345 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001346
1347 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001348 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001349 exported, export_size,
1350 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001351 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001352
1353 /* The exported length must be set by psa_export_key() to a value between 0
1354 * and export_size. On errors, the exported length must be 0. */
1355 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1356 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1357 TEST_ASSERT( exported_length <= export_size );
1358
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001359 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001360 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001361 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001362 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001363 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001364 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001365 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001366
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001367 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001368 goto exit;
1369
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001370 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001371 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001372 else
1373 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001374 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001375 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1376 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001377 PSA_ASSERT( psa_export_key( handle2,
1378 reexported,
1379 export_size,
1380 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001381 ASSERT_COMPARE( exported, exported_length,
1382 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001383 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001384 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001385 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001386
1387destroy:
1388 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001389 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001390 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001391
1392exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001393 mbedtls_free( exported );
1394 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001395 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001396 mbedtls_psa_crypto_free( );
1397}
1398/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001399
Moran Pekerf709f4a2018-06-06 17:26:04 +03001400/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001401void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001402{
Gilles Peskine8817f612018-12-18 00:18:46 +01001403 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001404 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001405
1406exit:
1407 mbedtls_psa_crypto_free( );
1408}
1409/* END_CASE */
1410
1411/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001412void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001413 int type_arg,
1414 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001415 int export_size_delta,
1416 int expected_export_status_arg,
1417 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001418{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001419 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001420 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001421 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001422 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001423 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001424 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001425 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001426 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001427 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001428
Gilles Peskine8817f612018-12-18 00:18:46 +01001429 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001430
Gilles Peskine4747d192019-04-17 15:05:45 +02001431 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1432 psa_set_key_algorithm( &attributes, alg );
1433 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001434
1435 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001436 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001437
Gilles Peskine49c25912018-10-29 15:15:31 +01001438 /* Export the public key */
1439 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001440 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001441 exported, export_size,
1442 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001443 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001444 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001445 {
1446 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1447 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001448 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1449 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001450 TEST_ASSERT( expected_public_key->len <=
1451 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001452 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1453 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001454 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001455
1456exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001457 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001458 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001459 psa_reset_key_attributes( &attributes );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001460 mbedtls_psa_crypto_free( );
1461}
1462/* END_CASE */
1463
Gilles Peskine20035e32018-02-03 22:44:14 +01001464/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001465void import_and_exercise_key( data_t *data,
1466 int type_arg,
1467 int bits_arg,
1468 int alg_arg )
1469{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001470 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001471 psa_key_type_t type = type_arg;
1472 size_t bits = bits_arg;
1473 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001474 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001475 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001476 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001477
Gilles Peskine8817f612018-12-18 00:18:46 +01001478 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001479
Gilles Peskine4747d192019-04-17 15:05:45 +02001480 psa_set_key_usage_flags( &attributes, usage );
1481 psa_set_key_algorithm( &attributes, alg );
1482 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001483
1484 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001485 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001486
1487 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001488 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1489 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1490 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001491
1492 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001493 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001494 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001495
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001496 PSA_ASSERT( psa_destroy_key( handle ) );
1497 test_operations_on_invalid_handle( handle );
1498
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001499exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001500 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001501 psa_reset_key_attributes( &got_attributes );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001502 mbedtls_psa_crypto_free( );
1503}
1504/* END_CASE */
1505
1506/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001507void key_policy( int usage_arg, int alg_arg )
1508{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001509 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001510 psa_algorithm_t alg = alg_arg;
1511 psa_key_usage_t usage = usage_arg;
1512 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1513 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001514 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001515
1516 memset( key, 0x2a, sizeof( key ) );
1517
Gilles Peskine8817f612018-12-18 00:18:46 +01001518 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001519
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001520 psa_set_key_usage_flags( &attributes, usage );
1521 psa_set_key_algorithm( &attributes, alg );
1522 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001523
Gilles Peskine73676cb2019-05-15 20:15:10 +02001524 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001525
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001526 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1527 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1528 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1529 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001530
1531exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001532 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001533 psa_reset_key_attributes( &attributes );
Gilles Peskined5b33222018-06-18 22:20:03 +02001534 mbedtls_psa_crypto_free( );
1535}
1536/* END_CASE */
1537
1538/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001539void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001540{
1541 /* Test each valid way of initializing the object, except for `= {0}`, as
1542 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1543 * though it's OK by the C standard. We could test for this, but we'd need
1544 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001545 psa_key_attributes_t func = psa_key_attributes_init( );
1546 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1547 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001548
1549 memset( &zero, 0, sizeof( zero ) );
1550
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001551 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1552 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1553 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001554
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001555 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1556 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1557 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1558
1559 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1560 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1561 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1562
1563 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1564 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1565 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1566
1567 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1568 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1569 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001570}
1571/* END_CASE */
1572
1573/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001574void mac_key_policy( int policy_usage,
1575 int policy_alg,
1576 int key_type,
1577 data_t *key_data,
1578 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001579{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001580 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001581 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001582 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001583 psa_status_t status;
1584 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001585
Gilles Peskine8817f612018-12-18 00:18:46 +01001586 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001587
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001588 psa_set_key_usage_flags( &attributes, policy_usage );
1589 psa_set_key_algorithm( &attributes, policy_alg );
1590 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001591
Gilles Peskine049c7532019-05-15 20:22:09 +02001592 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1593 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001594
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001595 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001596 if( policy_alg == exercise_alg &&
1597 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001598 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001599 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001600 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001601 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001602
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001603 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001604 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001605 if( policy_alg == exercise_alg &&
1606 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001607 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001608 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001609 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001610
1611exit:
1612 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001613 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001614 mbedtls_psa_crypto_free( );
1615}
1616/* END_CASE */
1617
1618/* BEGIN_CASE */
1619void cipher_key_policy( int policy_usage,
1620 int policy_alg,
1621 int key_type,
1622 data_t *key_data,
1623 int exercise_alg )
1624{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001625 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001626 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001627 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001628 psa_status_t status;
1629
Gilles Peskine8817f612018-12-18 00:18:46 +01001630 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001631
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001632 psa_set_key_usage_flags( &attributes, policy_usage );
1633 psa_set_key_algorithm( &attributes, policy_alg );
1634 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001635
Gilles Peskine049c7532019-05-15 20:22:09 +02001636 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1637 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001638
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001639 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001640 if( policy_alg == exercise_alg &&
1641 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001642 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001643 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001644 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001645 psa_cipher_abort( &operation );
1646
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001647 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001648 if( policy_alg == exercise_alg &&
1649 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001650 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001651 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001652 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001653
1654exit:
1655 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001656 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001657 mbedtls_psa_crypto_free( );
1658}
1659/* END_CASE */
1660
1661/* BEGIN_CASE */
1662void aead_key_policy( int policy_usage,
1663 int policy_alg,
1664 int key_type,
1665 data_t *key_data,
1666 int nonce_length_arg,
1667 int tag_length_arg,
1668 int exercise_alg )
1669{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001670 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001671 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001672 psa_status_t status;
1673 unsigned char nonce[16] = {0};
1674 size_t nonce_length = nonce_length_arg;
1675 unsigned char tag[16];
1676 size_t tag_length = tag_length_arg;
1677 size_t output_length;
1678
1679 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1680 TEST_ASSERT( tag_length <= sizeof( tag ) );
1681
Gilles Peskine8817f612018-12-18 00:18:46 +01001682 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001683
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001684 psa_set_key_usage_flags( &attributes, policy_usage );
1685 psa_set_key_algorithm( &attributes, policy_alg );
1686 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001687
Gilles Peskine049c7532019-05-15 20:22:09 +02001688 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1689 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001690
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001691 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692 nonce, nonce_length,
1693 NULL, 0,
1694 NULL, 0,
1695 tag, tag_length,
1696 &output_length );
1697 if( policy_alg == exercise_alg &&
1698 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001699 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001700 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001701 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001702
1703 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001704 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705 nonce, nonce_length,
1706 NULL, 0,
1707 tag, tag_length,
1708 NULL, 0,
1709 &output_length );
1710 if( policy_alg == exercise_alg &&
1711 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001712 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
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
1716exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001717 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001718 mbedtls_psa_crypto_free( );
1719}
1720/* END_CASE */
1721
1722/* BEGIN_CASE */
1723void asymmetric_encryption_key_policy( int policy_usage,
1724 int policy_alg,
1725 int key_type,
1726 data_t *key_data,
1727 int exercise_alg )
1728{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001729 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001730 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001731 psa_status_t status;
1732 size_t key_bits;
1733 size_t buffer_length;
1734 unsigned char *buffer = NULL;
1735 size_t output_length;
1736
Gilles Peskine8817f612018-12-18 00:18:46 +01001737 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001738
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001739 psa_set_key_usage_flags( &attributes, policy_usage );
1740 psa_set_key_algorithm( &attributes, policy_alg );
1741 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001742
Gilles Peskine049c7532019-05-15 20:22:09 +02001743 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1744 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001745
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001746 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1747 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1749 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001750 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001752 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001753 NULL, 0,
1754 NULL, 0,
1755 buffer, buffer_length,
1756 &output_length );
1757 if( policy_alg == exercise_alg &&
1758 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001759 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001760 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001761 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001763 if( buffer_length != 0 )
1764 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001765 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001766 buffer, buffer_length,
1767 NULL, 0,
1768 buffer, buffer_length,
1769 &output_length );
1770 if( policy_alg == exercise_alg &&
1771 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001772 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001773 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001774 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001775
1776exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001777 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001778 psa_reset_key_attributes( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001779 mbedtls_psa_crypto_free( );
1780 mbedtls_free( buffer );
1781}
1782/* END_CASE */
1783
1784/* BEGIN_CASE */
1785void asymmetric_signature_key_policy( int policy_usage,
1786 int policy_alg,
1787 int key_type,
1788 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001789 int exercise_alg,
1790 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001791{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001792 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001793 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001794 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001795 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1796 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1797 * compatible with the policy and `payload_length_arg` is supposed to be
1798 * a valid input length to sign. If `payload_length_arg <= 0`,
1799 * `exercise_alg` is supposed to be forbidden by the policy. */
1800 int compatible_alg = payload_length_arg > 0;
1801 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001802 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1803 size_t signature_length;
1804
Gilles Peskine8817f612018-12-18 00:18:46 +01001805 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001806
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001807 psa_set_key_usage_flags( &attributes, policy_usage );
1808 psa_set_key_algorithm( &attributes, policy_alg );
1809 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001810
Gilles Peskine049c7532019-05-15 20:22:09 +02001811 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1812 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001813
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001814 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001815 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001816 signature, sizeof( signature ),
1817 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001818 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001819 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001820 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001821 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822
1823 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001824 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001825 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001826 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001827 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001828 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001829 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001830 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001831
1832exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001833 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001834 mbedtls_psa_crypto_free( );
1835}
1836/* END_CASE */
1837
1838/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001839void derive_key_policy( int policy_usage,
1840 int policy_alg,
1841 int key_type,
1842 data_t *key_data,
1843 int exercise_alg )
1844{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001845 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001846 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001847 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001848 psa_status_t status;
1849
Gilles Peskine8817f612018-12-18 00:18:46 +01001850 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001851
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001852 psa_set_key_usage_flags( &attributes, policy_usage );
1853 psa_set_key_algorithm( &attributes, policy_alg );
1854 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001855
Gilles Peskine049c7532019-05-15 20:22:09 +02001856 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1857 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001858
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001859 status = psa_key_derivation( &operation, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001860 exercise_alg,
1861 NULL, 0,
1862 NULL, 0,
1863 1 );
1864 if( policy_alg == exercise_alg &&
1865 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001866 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001867 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001868 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001869
1870exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001871 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001872 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001873 mbedtls_psa_crypto_free( );
1874}
1875/* END_CASE */
1876
1877/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001878void agreement_key_policy( int policy_usage,
1879 int policy_alg,
1880 int key_type_arg,
1881 data_t *key_data,
1882 int exercise_alg )
1883{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001884 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001885 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001886 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001887 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001888 psa_status_t status;
1889
Gilles Peskine8817f612018-12-18 00:18:46 +01001890 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001891
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001892 psa_set_key_usage_flags( &attributes, policy_usage );
1893 psa_set_key_algorithm( &attributes, policy_alg );
1894 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001895
Gilles Peskine049c7532019-05-15 20:22:09 +02001896 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1897 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001898
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001899 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1900 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001901
Gilles Peskine01d718c2018-09-18 12:01:02 +02001902 if( policy_alg == exercise_alg &&
1903 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001904 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001905 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001906 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001907
1908exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001909 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001910 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001911 mbedtls_psa_crypto_free( );
1912}
1913/* END_CASE */
1914
1915/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001916void raw_agreement_key_policy( int policy_usage,
1917 int policy_alg,
1918 int key_type_arg,
1919 data_t *key_data,
1920 int exercise_alg )
1921{
1922 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001923 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001924 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001925 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001926 psa_status_t status;
1927
1928 PSA_ASSERT( psa_crypto_init( ) );
1929
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001930 psa_set_key_usage_flags( &attributes, policy_usage );
1931 psa_set_key_algorithm( &attributes, policy_alg );
1932 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001933
Gilles Peskine049c7532019-05-15 20:22:09 +02001934 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1935 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001936
1937 status = raw_key_agreement_with_self( exercise_alg, handle );
1938
1939 if( policy_alg == exercise_alg &&
1940 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1941 PSA_ASSERT( status );
1942 else
1943 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1944
1945exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001946 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001947 psa_destroy_key( handle );
1948 mbedtls_psa_crypto_free( );
1949}
1950/* END_CASE */
1951
1952/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02001953void copy_success( int source_usage_arg, int source_alg_arg,
1954 int type_arg, data_t *material,
1955 int copy_attributes,
1956 int target_usage_arg, int target_alg_arg,
1957 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001958{
Gilles Peskineca25db92019-04-19 11:43:08 +02001959 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1960 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001961 psa_key_usage_t expected_usage = expected_usage_arg;
1962 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001963 psa_key_handle_t source_handle = 0;
1964 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001965 uint8_t *export_buffer = NULL;
1966
Gilles Peskine57ab7212019-01-28 13:03:09 +01001967 PSA_ASSERT( psa_crypto_init( ) );
1968
Gilles Peskineca25db92019-04-19 11:43:08 +02001969 /* Prepare the source key. */
1970 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1971 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1972 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02001973 PSA_ASSERT( psa_import_key( &source_attributes,
1974 material->x, material->len,
1975 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001976 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001977
Gilles Peskineca25db92019-04-19 11:43:08 +02001978 /* Prepare the target attributes. */
1979 if( copy_attributes )
1980 target_attributes = source_attributes;
1981 if( target_usage_arg != -1 )
1982 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1983 if( target_alg_arg != -1 )
1984 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001985
1986 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02001987 PSA_ASSERT( psa_copy_key( source_handle,
1988 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001989
1990 /* Destroy the source to ensure that this doesn't affect the target. */
1991 PSA_ASSERT( psa_destroy_key( source_handle ) );
1992
1993 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001994 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1995 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1996 psa_get_key_type( &target_attributes ) );
1997 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1998 psa_get_key_bits( &target_attributes ) );
1999 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2000 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002001 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2002 {
2003 size_t length;
2004 ASSERT_ALLOC( export_buffer, material->len );
2005 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2006 material->len, &length ) );
2007 ASSERT_COMPARE( material->x, material->len,
2008 export_buffer, length );
2009 }
2010 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2011 goto exit;
2012
2013 PSA_ASSERT( psa_close_key( target_handle ) );
2014
2015exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002016 psa_reset_key_attributes( &source_attributes );
2017 psa_reset_key_attributes( &target_attributes );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002018 mbedtls_psa_crypto_free( );
2019 mbedtls_free( export_buffer );
2020}
2021/* END_CASE */
2022
2023/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02002024void copy_fail( int source_usage_arg, int source_alg_arg,
2025 int type_arg, data_t *material,
2026 int target_type_arg, int target_bits_arg,
2027 int target_usage_arg, int target_alg_arg,
2028 int expected_status_arg )
2029{
2030 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2031 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2032 psa_key_handle_t source_handle = 0;
2033 psa_key_handle_t target_handle = 0;
2034
2035 PSA_ASSERT( psa_crypto_init( ) );
2036
2037 /* Prepare the source key. */
2038 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2039 psa_set_key_algorithm( &source_attributes, source_alg_arg );
2040 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002041 PSA_ASSERT( psa_import_key( &source_attributes,
2042 material->x, material->len,
2043 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002044
2045 /* Prepare the target attributes. */
2046 psa_set_key_type( &target_attributes, target_type_arg );
2047 psa_set_key_bits( &target_attributes, target_bits_arg );
2048 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2049 psa_set_key_algorithm( &target_attributes, target_alg_arg );
2050
2051 /* Try to copy the key. */
2052 TEST_EQUAL( psa_copy_key( source_handle,
2053 &target_attributes, &target_handle ),
2054 expected_status_arg );
2055exit:
2056 psa_reset_key_attributes( &source_attributes );
2057 psa_reset_key_attributes( &target_attributes );
2058 mbedtls_psa_crypto_free( );
2059}
2060/* END_CASE */
2061
2062/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002063void hash_operation_init( )
2064{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002065 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002066 /* Test each valid way of initializing the object, except for `= {0}`, as
2067 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2068 * though it's OK by the C standard. We could test for this, but we'd need
2069 * to supress the Clang warning for the test. */
2070 psa_hash_operation_t func = psa_hash_operation_init( );
2071 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2072 psa_hash_operation_t zero;
2073
2074 memset( &zero, 0, sizeof( zero ) );
2075
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002076 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002077 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2078 PSA_ERROR_BAD_STATE );
2079 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2080 PSA_ERROR_BAD_STATE );
2081 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2082 PSA_ERROR_BAD_STATE );
2083
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002084 /* A default hash operation should be abortable without error. */
2085 PSA_ASSERT( psa_hash_abort( &func ) );
2086 PSA_ASSERT( psa_hash_abort( &init ) );
2087 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002088}
2089/* END_CASE */
2090
2091/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002092void hash_setup( int alg_arg,
2093 int expected_status_arg )
2094{
2095 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002096 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002097 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002098 psa_status_t status;
2099
Gilles Peskine8817f612018-12-18 00:18:46 +01002100 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002101
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002102 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002103 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002104
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002105 /* Whether setup succeeded or failed, abort must succeed. */
2106 PSA_ASSERT( psa_hash_abort( &operation ) );
2107
2108 /* If setup failed, reproduce the failure, so as to
2109 * test the resulting state of the operation object. */
2110 if( status != PSA_SUCCESS )
2111 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2112
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002113 /* Now the operation object should be reusable. */
2114#if defined(KNOWN_SUPPORTED_HASH_ALG)
2115 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2116 PSA_ASSERT( psa_hash_abort( &operation ) );
2117#endif
2118
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002119exit:
2120 mbedtls_psa_crypto_free( );
2121}
2122/* END_CASE */
2123
2124/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002125void hash_bad_order( )
2126{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002127 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002128 unsigned char input[] = "";
2129 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002130 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002131 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2132 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2133 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002134 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002135 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002136 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002137
Gilles Peskine8817f612018-12-18 00:18:46 +01002138 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002139
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002140 /* Call setup twice in a row. */
2141 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2142 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2143 PSA_ERROR_BAD_STATE );
2144 PSA_ASSERT( psa_hash_abort( &operation ) );
2145
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002146 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002147 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002148 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002149 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002150
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002151 /* Call update after finish. */
2152 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2153 PSA_ASSERT( psa_hash_finish( &operation,
2154 hash, sizeof( hash ), &hash_len ) );
2155 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002156 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002157 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002158
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002159 /* Call verify without calling setup beforehand. */
2160 TEST_EQUAL( psa_hash_verify( &operation,
2161 valid_hash, sizeof( valid_hash ) ),
2162 PSA_ERROR_BAD_STATE );
2163 PSA_ASSERT( psa_hash_abort( &operation ) );
2164
2165 /* Call verify after finish. */
2166 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2167 PSA_ASSERT( psa_hash_finish( &operation,
2168 hash, sizeof( hash ), &hash_len ) );
2169 TEST_EQUAL( psa_hash_verify( &operation,
2170 valid_hash, sizeof( valid_hash ) ),
2171 PSA_ERROR_BAD_STATE );
2172 PSA_ASSERT( psa_hash_abort( &operation ) );
2173
2174 /* Call verify twice in a row. */
2175 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2176 PSA_ASSERT( psa_hash_verify( &operation,
2177 valid_hash, sizeof( valid_hash ) ) );
2178 TEST_EQUAL( psa_hash_verify( &operation,
2179 valid_hash, sizeof( valid_hash ) ),
2180 PSA_ERROR_BAD_STATE );
2181 PSA_ASSERT( psa_hash_abort( &operation ) );
2182
2183 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002184 TEST_EQUAL( psa_hash_finish( &operation,
2185 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002186 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002187 PSA_ASSERT( psa_hash_abort( &operation ) );
2188
2189 /* Call finish twice in a row. */
2190 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2191 PSA_ASSERT( psa_hash_finish( &operation,
2192 hash, sizeof( hash ), &hash_len ) );
2193 TEST_EQUAL( psa_hash_finish( &operation,
2194 hash, sizeof( hash ), &hash_len ),
2195 PSA_ERROR_BAD_STATE );
2196 PSA_ASSERT( psa_hash_abort( &operation ) );
2197
2198 /* Call finish after calling verify. */
2199 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2200 PSA_ASSERT( psa_hash_verify( &operation,
2201 valid_hash, sizeof( valid_hash ) ) );
2202 TEST_EQUAL( psa_hash_finish( &operation,
2203 hash, sizeof( hash ), &hash_len ),
2204 PSA_ERROR_BAD_STATE );
2205 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002206
2207exit:
2208 mbedtls_psa_crypto_free( );
2209}
2210/* END_CASE */
2211
itayzafrir27e69452018-11-01 14:26:34 +02002212/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2213void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002214{
2215 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002216 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2217 * appended to it */
2218 unsigned char hash[] = {
2219 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2220 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2221 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002222 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002223 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002224
Gilles Peskine8817f612018-12-18 00:18:46 +01002225 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002226
itayzafrir27e69452018-11-01 14:26:34 +02002227 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002228 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002229 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002230 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002231
itayzafrir27e69452018-11-01 14:26:34 +02002232 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002233 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002234 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002235 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002236
itayzafrir27e69452018-11-01 14:26:34 +02002237 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002238 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002239 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002240 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002241
itayzafrirec93d302018-10-18 18:01:10 +03002242exit:
2243 mbedtls_psa_crypto_free( );
2244}
2245/* END_CASE */
2246
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002247/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2248void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002249{
2250 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002251 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002252 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002253 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002254 size_t hash_len;
2255
Gilles Peskine8817f612018-12-18 00:18:46 +01002256 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002257
itayzafrir58028322018-10-25 10:22:01 +03002258 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002259 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002260 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002261 hash, expected_size - 1, &hash_len ),
2262 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002263
2264exit:
2265 mbedtls_psa_crypto_free( );
2266}
2267/* END_CASE */
2268
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002269/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2270void hash_clone_source_state( )
2271{
2272 psa_algorithm_t alg = PSA_ALG_SHA_256;
2273 unsigned char hash[PSA_HASH_MAX_SIZE];
2274 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2275 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2276 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2277 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2278 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2279 size_t hash_len;
2280
2281 PSA_ASSERT( psa_crypto_init( ) );
2282 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2283
2284 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2285 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2286 PSA_ASSERT( psa_hash_finish( &op_finished,
2287 hash, sizeof( hash ), &hash_len ) );
2288 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2289 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2290
2291 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2292 PSA_ERROR_BAD_STATE );
2293
2294 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2295 PSA_ASSERT( psa_hash_finish( &op_init,
2296 hash, sizeof( hash ), &hash_len ) );
2297 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2298 PSA_ASSERT( psa_hash_finish( &op_finished,
2299 hash, sizeof( hash ), &hash_len ) );
2300 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2301 PSA_ASSERT( psa_hash_finish( &op_aborted,
2302 hash, sizeof( hash ), &hash_len ) );
2303
2304exit:
2305 psa_hash_abort( &op_source );
2306 psa_hash_abort( &op_init );
2307 psa_hash_abort( &op_setup );
2308 psa_hash_abort( &op_finished );
2309 psa_hash_abort( &op_aborted );
2310 mbedtls_psa_crypto_free( );
2311}
2312/* END_CASE */
2313
2314/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2315void hash_clone_target_state( )
2316{
2317 psa_algorithm_t alg = PSA_ALG_SHA_256;
2318 unsigned char hash[PSA_HASH_MAX_SIZE];
2319 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2320 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2321 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2322 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2323 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2324 size_t hash_len;
2325
2326 PSA_ASSERT( psa_crypto_init( ) );
2327
2328 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2329 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2330 PSA_ASSERT( psa_hash_finish( &op_finished,
2331 hash, sizeof( hash ), &hash_len ) );
2332 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2333 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2334
2335 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2336 PSA_ASSERT( psa_hash_finish( &op_target,
2337 hash, sizeof( hash ), &hash_len ) );
2338
2339 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2340 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2341 PSA_ERROR_BAD_STATE );
2342 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2343 PSA_ERROR_BAD_STATE );
2344
2345exit:
2346 psa_hash_abort( &op_target );
2347 psa_hash_abort( &op_init );
2348 psa_hash_abort( &op_setup );
2349 psa_hash_abort( &op_finished );
2350 psa_hash_abort( &op_aborted );
2351 mbedtls_psa_crypto_free( );
2352}
2353/* END_CASE */
2354
itayzafrir58028322018-10-25 10:22:01 +03002355/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002356void mac_operation_init( )
2357{
Jaeden Amero252ef282019-02-15 14:05:35 +00002358 const uint8_t input[1] = { 0 };
2359
Jaeden Amero769ce272019-01-04 11:48:03 +00002360 /* Test each valid way of initializing the object, except for `= {0}`, as
2361 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2362 * though it's OK by the C standard. We could test for this, but we'd need
2363 * to supress the Clang warning for the test. */
2364 psa_mac_operation_t func = psa_mac_operation_init( );
2365 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2366 psa_mac_operation_t zero;
2367
2368 memset( &zero, 0, sizeof( zero ) );
2369
Jaeden Amero252ef282019-02-15 14:05:35 +00002370 /* A freshly-initialized MAC operation should not be usable. */
2371 TEST_EQUAL( psa_mac_update( &func,
2372 input, sizeof( input ) ),
2373 PSA_ERROR_BAD_STATE );
2374 TEST_EQUAL( psa_mac_update( &init,
2375 input, sizeof( input ) ),
2376 PSA_ERROR_BAD_STATE );
2377 TEST_EQUAL( psa_mac_update( &zero,
2378 input, sizeof( input ) ),
2379 PSA_ERROR_BAD_STATE );
2380
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002381 /* A default MAC operation should be abortable without error. */
2382 PSA_ASSERT( psa_mac_abort( &func ) );
2383 PSA_ASSERT( psa_mac_abort( &init ) );
2384 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002385}
2386/* END_CASE */
2387
2388/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002389void mac_setup( int key_type_arg,
2390 data_t *key,
2391 int alg_arg,
2392 int expected_status_arg )
2393{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002394 psa_key_type_t key_type = key_type_arg;
2395 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002396 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002397 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002398 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2399#if defined(KNOWN_SUPPORTED_MAC_ALG)
2400 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2401#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002402
Gilles Peskine8817f612018-12-18 00:18:46 +01002403 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002404
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002405 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2406 &operation, &status ) )
2407 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002408 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002409
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002410 /* The operation object should be reusable. */
2411#if defined(KNOWN_SUPPORTED_MAC_ALG)
2412 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2413 smoke_test_key_data,
2414 sizeof( smoke_test_key_data ),
2415 KNOWN_SUPPORTED_MAC_ALG,
2416 &operation, &status ) )
2417 goto exit;
2418 TEST_EQUAL( status, PSA_SUCCESS );
2419#endif
2420
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002421exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002422 mbedtls_psa_crypto_free( );
2423}
2424/* END_CASE */
2425
2426/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002427void mac_bad_order( )
2428{
2429 psa_key_handle_t handle = 0;
2430 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2431 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2432 const uint8_t key[] = {
2433 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2434 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2435 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002436 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002437 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2438 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2439 size_t sign_mac_length = 0;
2440 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2441 const uint8_t verify_mac[] = {
2442 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2443 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2444 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2445
2446 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002447 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2448 psa_set_key_algorithm( &attributes, alg );
2449 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002450
Gilles Peskine73676cb2019-05-15 20:15:10 +02002451 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002452
Jaeden Amero252ef282019-02-15 14:05:35 +00002453 /* Call update without calling setup beforehand. */
2454 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2455 PSA_ERROR_BAD_STATE );
2456 PSA_ASSERT( psa_mac_abort( &operation ) );
2457
2458 /* Call sign finish without calling setup beforehand. */
2459 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2460 &sign_mac_length),
2461 PSA_ERROR_BAD_STATE );
2462 PSA_ASSERT( psa_mac_abort( &operation ) );
2463
2464 /* Call verify finish without calling setup beforehand. */
2465 TEST_EQUAL( psa_mac_verify_finish( &operation,
2466 verify_mac, sizeof( verify_mac ) ),
2467 PSA_ERROR_BAD_STATE );
2468 PSA_ASSERT( psa_mac_abort( &operation ) );
2469
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002470 /* Call setup twice in a row. */
2471 PSA_ASSERT( psa_mac_sign_setup( &operation,
2472 handle, alg ) );
2473 TEST_EQUAL( psa_mac_sign_setup( &operation,
2474 handle, alg ),
2475 PSA_ERROR_BAD_STATE );
2476 PSA_ASSERT( psa_mac_abort( &operation ) );
2477
Jaeden Amero252ef282019-02-15 14:05:35 +00002478 /* Call update after sign finish. */
2479 PSA_ASSERT( psa_mac_sign_setup( &operation,
2480 handle, alg ) );
2481 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2482 PSA_ASSERT( psa_mac_sign_finish( &operation,
2483 sign_mac, sizeof( sign_mac ),
2484 &sign_mac_length ) );
2485 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2486 PSA_ERROR_BAD_STATE );
2487 PSA_ASSERT( psa_mac_abort( &operation ) );
2488
2489 /* Call update after verify finish. */
2490 PSA_ASSERT( psa_mac_verify_setup( &operation,
2491 handle, alg ) );
2492 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2493 PSA_ASSERT( psa_mac_verify_finish( &operation,
2494 verify_mac, sizeof( verify_mac ) ) );
2495 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2496 PSA_ERROR_BAD_STATE );
2497 PSA_ASSERT( psa_mac_abort( &operation ) );
2498
2499 /* Call sign finish twice in a row. */
2500 PSA_ASSERT( psa_mac_sign_setup( &operation,
2501 handle, alg ) );
2502 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2503 PSA_ASSERT( psa_mac_sign_finish( &operation,
2504 sign_mac, sizeof( sign_mac ),
2505 &sign_mac_length ) );
2506 TEST_EQUAL( psa_mac_sign_finish( &operation,
2507 sign_mac, sizeof( sign_mac ),
2508 &sign_mac_length ),
2509 PSA_ERROR_BAD_STATE );
2510 PSA_ASSERT( psa_mac_abort( &operation ) );
2511
2512 /* Call verify finish twice in a row. */
2513 PSA_ASSERT( psa_mac_verify_setup( &operation,
2514 handle, alg ) );
2515 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2516 PSA_ASSERT( psa_mac_verify_finish( &operation,
2517 verify_mac, sizeof( verify_mac ) ) );
2518 TEST_EQUAL( psa_mac_verify_finish( &operation,
2519 verify_mac, sizeof( verify_mac ) ),
2520 PSA_ERROR_BAD_STATE );
2521 PSA_ASSERT( psa_mac_abort( &operation ) );
2522
2523 /* Setup sign but try verify. */
2524 PSA_ASSERT( psa_mac_sign_setup( &operation,
2525 handle, alg ) );
2526 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2527 TEST_EQUAL( psa_mac_verify_finish( &operation,
2528 verify_mac, sizeof( verify_mac ) ),
2529 PSA_ERROR_BAD_STATE );
2530 PSA_ASSERT( psa_mac_abort( &operation ) );
2531
2532 /* Setup verify but try sign. */
2533 PSA_ASSERT( psa_mac_verify_setup( &operation,
2534 handle, alg ) );
2535 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2536 TEST_EQUAL( psa_mac_sign_finish( &operation,
2537 sign_mac, sizeof( sign_mac ),
2538 &sign_mac_length ),
2539 PSA_ERROR_BAD_STATE );
2540 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002541
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002542exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002543 mbedtls_psa_crypto_free( );
2544}
2545/* END_CASE */
2546
2547/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002548void mac_sign( int key_type_arg,
2549 data_t *key,
2550 int alg_arg,
2551 data_t *input,
2552 data_t *expected_mac )
2553{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002554 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002555 psa_key_type_t key_type = key_type_arg;
2556 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002557 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002558 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002559 /* Leave a little extra room in the output buffer. At the end of the
2560 * test, we'll check that the implementation didn't overwrite onto
2561 * this extra room. */
2562 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2563 size_t mac_buffer_size =
2564 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2565 size_t mac_length = 0;
2566
2567 memset( actual_mac, '+', sizeof( actual_mac ) );
2568 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2569 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2570
Gilles Peskine8817f612018-12-18 00:18:46 +01002571 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002572
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002573 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2574 psa_set_key_algorithm( &attributes, alg );
2575 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002576
Gilles Peskine73676cb2019-05-15 20:15:10 +02002577 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002578
2579 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002580 PSA_ASSERT( psa_mac_sign_setup( &operation,
2581 handle, alg ) );
2582 PSA_ASSERT( psa_mac_update( &operation,
2583 input->x, input->len ) );
2584 PSA_ASSERT( psa_mac_sign_finish( &operation,
2585 actual_mac, mac_buffer_size,
2586 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002587
2588 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002589 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2590 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002591
2592 /* Verify that the end of the buffer is untouched. */
2593 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2594 sizeof( actual_mac ) - mac_length ) );
2595
2596exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002597 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002598 mbedtls_psa_crypto_free( );
2599}
2600/* END_CASE */
2601
2602/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002603void mac_verify( int key_type_arg,
2604 data_t *key,
2605 int alg_arg,
2606 data_t *input,
2607 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002608{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002609 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002610 psa_key_type_t key_type = key_type_arg;
2611 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002612 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002613 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002614
Gilles Peskine69c12672018-06-28 00:07:19 +02002615 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2616
Gilles Peskine8817f612018-12-18 00:18:46 +01002617 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002618
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002619 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2620 psa_set_key_algorithm( &attributes, alg );
2621 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002622
Gilles Peskine73676cb2019-05-15 20:15:10 +02002623 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002624
Gilles Peskine8817f612018-12-18 00:18:46 +01002625 PSA_ASSERT( psa_mac_verify_setup( &operation,
2626 handle, alg ) );
2627 PSA_ASSERT( psa_destroy_key( handle ) );
2628 PSA_ASSERT( psa_mac_update( &operation,
2629 input->x, input->len ) );
2630 PSA_ASSERT( psa_mac_verify_finish( &operation,
2631 expected_mac->x,
2632 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002633
2634exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002635 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002636 mbedtls_psa_crypto_free( );
2637}
2638/* END_CASE */
2639
2640/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002641void cipher_operation_init( )
2642{
Jaeden Ameroab439972019-02-15 14:12:05 +00002643 const uint8_t input[1] = { 0 };
2644 unsigned char output[1] = { 0 };
2645 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002646 /* Test each valid way of initializing the object, except for `= {0}`, as
2647 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2648 * though it's OK by the C standard. We could test for this, but we'd need
2649 * to supress the Clang warning for the test. */
2650 psa_cipher_operation_t func = psa_cipher_operation_init( );
2651 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2652 psa_cipher_operation_t zero;
2653
2654 memset( &zero, 0, sizeof( zero ) );
2655
Jaeden Ameroab439972019-02-15 14:12:05 +00002656 /* A freshly-initialized cipher operation should not be usable. */
2657 TEST_EQUAL( psa_cipher_update( &func,
2658 input, sizeof( input ),
2659 output, sizeof( output ),
2660 &output_length ),
2661 PSA_ERROR_BAD_STATE );
2662 TEST_EQUAL( psa_cipher_update( &init,
2663 input, sizeof( input ),
2664 output, sizeof( output ),
2665 &output_length ),
2666 PSA_ERROR_BAD_STATE );
2667 TEST_EQUAL( psa_cipher_update( &zero,
2668 input, sizeof( input ),
2669 output, sizeof( output ),
2670 &output_length ),
2671 PSA_ERROR_BAD_STATE );
2672
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002673 /* A default cipher operation should be abortable without error. */
2674 PSA_ASSERT( psa_cipher_abort( &func ) );
2675 PSA_ASSERT( psa_cipher_abort( &init ) );
2676 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002677}
2678/* END_CASE */
2679
2680/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002681void cipher_setup( int key_type_arg,
2682 data_t *key,
2683 int alg_arg,
2684 int expected_status_arg )
2685{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002686 psa_key_type_t key_type = key_type_arg;
2687 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002688 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002689 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002690 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002691#if defined(KNOWN_SUPPORTED_MAC_ALG)
2692 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2693#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002694
Gilles Peskine8817f612018-12-18 00:18:46 +01002695 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002696
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002697 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2698 &operation, &status ) )
2699 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002700 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002701
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002702 /* The operation object should be reusable. */
2703#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2704 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2705 smoke_test_key_data,
2706 sizeof( smoke_test_key_data ),
2707 KNOWN_SUPPORTED_CIPHER_ALG,
2708 &operation, &status ) )
2709 goto exit;
2710 TEST_EQUAL( status, PSA_SUCCESS );
2711#endif
2712
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002713exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002714 mbedtls_psa_crypto_free( );
2715}
2716/* END_CASE */
2717
2718/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002719void cipher_bad_order( )
2720{
2721 psa_key_handle_t handle = 0;
2722 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2723 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002724 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002725 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2726 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2727 const uint8_t key[] = {
2728 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2729 0xaa, 0xaa, 0xaa, 0xaa };
2730 const uint8_t text[] = {
2731 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2732 0xbb, 0xbb, 0xbb, 0xbb };
2733 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2734 size_t length = 0;
2735
2736 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002737 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2738 psa_set_key_algorithm( &attributes, alg );
2739 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002740 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002741
2742
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002743 /* Call encrypt setup twice in a row. */
2744 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2745 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2746 PSA_ERROR_BAD_STATE );
2747 PSA_ASSERT( psa_cipher_abort( &operation ) );
2748
2749 /* Call decrypt setup twice in a row. */
2750 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2751 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2752 PSA_ERROR_BAD_STATE );
2753 PSA_ASSERT( psa_cipher_abort( &operation ) );
2754
Jaeden Ameroab439972019-02-15 14:12:05 +00002755 /* Generate an IV without calling setup beforehand. */
2756 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2757 buffer, sizeof( buffer ),
2758 &length ),
2759 PSA_ERROR_BAD_STATE );
2760 PSA_ASSERT( psa_cipher_abort( &operation ) );
2761
2762 /* Generate an IV twice in a row. */
2763 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2764 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2765 buffer, sizeof( buffer ),
2766 &length ) );
2767 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2768 buffer, sizeof( buffer ),
2769 &length ),
2770 PSA_ERROR_BAD_STATE );
2771 PSA_ASSERT( psa_cipher_abort( &operation ) );
2772
2773 /* Generate an IV after it's already set. */
2774 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2775 PSA_ASSERT( psa_cipher_set_iv( &operation,
2776 iv, sizeof( iv ) ) );
2777 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2778 buffer, sizeof( buffer ),
2779 &length ),
2780 PSA_ERROR_BAD_STATE );
2781 PSA_ASSERT( psa_cipher_abort( &operation ) );
2782
2783 /* Set an IV without calling setup beforehand. */
2784 TEST_EQUAL( psa_cipher_set_iv( &operation,
2785 iv, sizeof( iv ) ),
2786 PSA_ERROR_BAD_STATE );
2787 PSA_ASSERT( psa_cipher_abort( &operation ) );
2788
2789 /* Set an IV after it's already set. */
2790 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2791 PSA_ASSERT( psa_cipher_set_iv( &operation,
2792 iv, sizeof( iv ) ) );
2793 TEST_EQUAL( psa_cipher_set_iv( &operation,
2794 iv, sizeof( iv ) ),
2795 PSA_ERROR_BAD_STATE );
2796 PSA_ASSERT( psa_cipher_abort( &operation ) );
2797
2798 /* Set an IV after it's already generated. */
2799 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2800 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2801 buffer, sizeof( buffer ),
2802 &length ) );
2803 TEST_EQUAL( psa_cipher_set_iv( &operation,
2804 iv, sizeof( iv ) ),
2805 PSA_ERROR_BAD_STATE );
2806 PSA_ASSERT( psa_cipher_abort( &operation ) );
2807
2808 /* Call update without calling setup beforehand. */
2809 TEST_EQUAL( psa_cipher_update( &operation,
2810 text, sizeof( text ),
2811 buffer, sizeof( buffer ),
2812 &length ),
2813 PSA_ERROR_BAD_STATE );
2814 PSA_ASSERT( psa_cipher_abort( &operation ) );
2815
2816 /* Call update without an IV where an IV is required. */
2817 TEST_EQUAL( psa_cipher_update( &operation,
2818 text, sizeof( text ),
2819 buffer, sizeof( buffer ),
2820 &length ),
2821 PSA_ERROR_BAD_STATE );
2822 PSA_ASSERT( psa_cipher_abort( &operation ) );
2823
2824 /* Call update after finish. */
2825 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2826 PSA_ASSERT( psa_cipher_set_iv( &operation,
2827 iv, sizeof( iv ) ) );
2828 PSA_ASSERT( psa_cipher_finish( &operation,
2829 buffer, sizeof( buffer ), &length ) );
2830 TEST_EQUAL( psa_cipher_update( &operation,
2831 text, sizeof( text ),
2832 buffer, sizeof( buffer ),
2833 &length ),
2834 PSA_ERROR_BAD_STATE );
2835 PSA_ASSERT( psa_cipher_abort( &operation ) );
2836
2837 /* Call finish without calling setup beforehand. */
2838 TEST_EQUAL( psa_cipher_finish( &operation,
2839 buffer, sizeof( buffer ), &length ),
2840 PSA_ERROR_BAD_STATE );
2841 PSA_ASSERT( psa_cipher_abort( &operation ) );
2842
2843 /* Call finish without an IV where an IV is required. */
2844 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2845 /* Not calling update means we are encrypting an empty buffer, which is OK
2846 * for cipher modes with padding. */
2847 TEST_EQUAL( psa_cipher_finish( &operation,
2848 buffer, sizeof( buffer ), &length ),
2849 PSA_ERROR_BAD_STATE );
2850 PSA_ASSERT( psa_cipher_abort( &operation ) );
2851
2852 /* Call finish twice in a row. */
2853 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2854 PSA_ASSERT( psa_cipher_set_iv( &operation,
2855 iv, sizeof( iv ) ) );
2856 PSA_ASSERT( psa_cipher_finish( &operation,
2857 buffer, sizeof( buffer ), &length ) );
2858 TEST_EQUAL( psa_cipher_finish( &operation,
2859 buffer, sizeof( buffer ), &length ),
2860 PSA_ERROR_BAD_STATE );
2861 PSA_ASSERT( psa_cipher_abort( &operation ) );
2862
2863exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002864 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002865}
2866/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002867
Gilles Peskine50e586b2018-06-08 14:28:46 +02002868/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002869void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002870 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002871 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002872 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002873{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002874 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002875 psa_status_t status;
2876 psa_key_type_t key_type = key_type_arg;
2877 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002878 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002879 unsigned char *output = NULL;
2880 size_t output_buffer_size = 0;
2881 size_t function_output_length = 0;
2882 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002883 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002884 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002885
Gilles Peskine8817f612018-12-18 00:18:46 +01002886 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002887
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002888 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2889 psa_set_key_algorithm( &attributes, alg );
2890 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002891
Gilles Peskine73676cb2019-05-15 20:15:10 +02002892 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002893
Gilles Peskine8817f612018-12-18 00:18:46 +01002894 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2895 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002896
Gilles Peskine423005e2019-05-06 15:22:57 +02002897 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002898 output_buffer_size = ( (size_t) input->len +
2899 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002900 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002901
Gilles Peskine8817f612018-12-18 00:18:46 +01002902 PSA_ASSERT( psa_cipher_update( &operation,
2903 input->x, input->len,
2904 output, output_buffer_size,
2905 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002906 total_output_length += function_output_length;
2907 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002908 output + total_output_length,
2909 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002910 &function_output_length );
2911 total_output_length += function_output_length;
2912
Gilles Peskinefe11b722018-12-18 00:24:04 +01002913 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002914 if( expected_status == PSA_SUCCESS )
2915 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002916 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002917 ASSERT_COMPARE( expected_output->x, expected_output->len,
2918 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002919 }
2920
2921exit:
2922 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002923 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924 mbedtls_psa_crypto_free( );
2925}
2926/* END_CASE */
2927
2928/* BEGIN_CASE */
2929void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002930 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002931 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002932 int first_part_size_arg,
2933 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002934 data_t *expected_output )
2935{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002936 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002937 psa_key_type_t key_type = key_type_arg;
2938 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002939 size_t first_part_size = first_part_size_arg;
2940 size_t output1_length = output1_length_arg;
2941 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002942 unsigned char *output = NULL;
2943 size_t output_buffer_size = 0;
2944 size_t function_output_length = 0;
2945 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002946 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002947 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002948
Gilles Peskine8817f612018-12-18 00:18:46 +01002949 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002950
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002951 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2952 psa_set_key_algorithm( &attributes, alg );
2953 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002954
Gilles Peskine73676cb2019-05-15 20:15:10 +02002955 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002956
Gilles Peskine8817f612018-12-18 00:18:46 +01002957 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2958 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002959
Gilles Peskine423005e2019-05-06 15:22:57 +02002960 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002961 output_buffer_size = ( (size_t) input->len +
2962 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002963 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002964
Gilles Peskinee0866522019-02-19 19:44:00 +01002965 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002966 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2967 output, output_buffer_size,
2968 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002969 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002970 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002971 PSA_ASSERT( psa_cipher_update( &operation,
2972 input->x + first_part_size,
2973 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002974 output + total_output_length,
2975 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002976 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002977 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002978 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002979 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002980 output + total_output_length,
2981 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002982 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002983 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002984 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002985
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002986 ASSERT_COMPARE( expected_output->x, expected_output->len,
2987 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002988
2989exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002990 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002991 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002992 mbedtls_psa_crypto_free( );
2993}
2994/* END_CASE */
2995
2996/* BEGIN_CASE */
2997void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002998 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002999 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003000 int first_part_size_arg,
3001 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003002 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003003{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003004 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003005
3006 psa_key_type_t key_type = key_type_arg;
3007 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003008 size_t first_part_size = first_part_size_arg;
3009 size_t output1_length = output1_length_arg;
3010 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003011 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012 size_t output_buffer_size = 0;
3013 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003014 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003015 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003016 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003017
Gilles Peskine8817f612018-12-18 00:18:46 +01003018 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003019
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003020 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3021 psa_set_key_algorithm( &attributes, alg );
3022 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003023
Gilles Peskine73676cb2019-05-15 20:15:10 +02003024 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003025
Gilles Peskine8817f612018-12-18 00:18:46 +01003026 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3027 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003028
Gilles Peskine423005e2019-05-06 15:22:57 +02003029 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003030
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003031 output_buffer_size = ( (size_t) input->len +
3032 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003033 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003034
Gilles Peskinee0866522019-02-19 19:44:00 +01003035 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003036 PSA_ASSERT( psa_cipher_update( &operation,
3037 input->x, first_part_size,
3038 output, output_buffer_size,
3039 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003040 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003041 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003042 PSA_ASSERT( psa_cipher_update( &operation,
3043 input->x + first_part_size,
3044 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003045 output + total_output_length,
3046 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003047 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003048 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003049 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003050 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003051 output + total_output_length,
3052 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003053 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003054 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003055 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003056
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003057 ASSERT_COMPARE( expected_output->x, expected_output->len,
3058 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003059
3060exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003061 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003062 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003063 mbedtls_psa_crypto_free( );
3064}
3065/* END_CASE */
3066
Gilles Peskine50e586b2018-06-08 14:28:46 +02003067/* BEGIN_CASE */
3068void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003069 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003070 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003071 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003072{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003073 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074 psa_status_t status;
3075 psa_key_type_t key_type = key_type_arg;
3076 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003077 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003078 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003079 size_t output_buffer_size = 0;
3080 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003081 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003082 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003083 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003084
Gilles Peskine8817f612018-12-18 00:18:46 +01003085 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003087 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3088 psa_set_key_algorithm( &attributes, alg );
3089 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003090
Gilles Peskine73676cb2019-05-15 20:15:10 +02003091 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003092
Gilles Peskine8817f612018-12-18 00:18:46 +01003093 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3094 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003095
Gilles Peskine423005e2019-05-06 15:22:57 +02003096 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003097
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003098 output_buffer_size = ( (size_t) input->len +
3099 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003100 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003101
Gilles Peskine8817f612018-12-18 00:18:46 +01003102 PSA_ASSERT( psa_cipher_update( &operation,
3103 input->x, input->len,
3104 output, output_buffer_size,
3105 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003106 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003107 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003108 output + total_output_length,
3109 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003110 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003111 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003112 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003113
3114 if( expected_status == PSA_SUCCESS )
3115 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003116 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003117 ASSERT_COMPARE( expected_output->x, expected_output->len,
3118 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003119 }
3120
Gilles Peskine50e586b2018-06-08 14:28:46 +02003121exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003122 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003123 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003124 mbedtls_psa_crypto_free( );
3125}
3126/* END_CASE */
3127
Gilles Peskine50e586b2018-06-08 14:28:46 +02003128/* BEGIN_CASE */
3129void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003130 data_t *key,
3131 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003132{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003133 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003134 psa_key_type_t key_type = key_type_arg;
3135 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003136 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003137 size_t iv_size = 16;
3138 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003139 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003140 size_t output1_size = 0;
3141 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003142 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003143 size_t output2_size = 0;
3144 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003145 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003146 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3147 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003148 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003149
Gilles Peskine8817f612018-12-18 00:18:46 +01003150 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003151
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003152 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3153 psa_set_key_algorithm( &attributes, alg );
3154 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003155
Gilles Peskine73676cb2019-05-15 20:15:10 +02003156 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003157
Gilles Peskine8817f612018-12-18 00:18:46 +01003158 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3159 handle, alg ) );
3160 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3161 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003162
Gilles Peskine8817f612018-12-18 00:18:46 +01003163 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3164 iv, iv_size,
3165 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003166 output1_size = ( (size_t) input->len +
3167 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003168 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003169
Gilles Peskine8817f612018-12-18 00:18:46 +01003170 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3171 output1, output1_size,
3172 &output1_length ) );
3173 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003174 output1 + output1_length,
3175 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003176 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003177
Gilles Peskine048b7f02018-06-08 14:20:49 +02003178 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003179
Gilles Peskine8817f612018-12-18 00:18:46 +01003180 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003181
3182 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003183 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003184
Gilles Peskine8817f612018-12-18 00:18:46 +01003185 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3186 iv, iv_length ) );
3187 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3188 output2, output2_size,
3189 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003190 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003191 PSA_ASSERT( psa_cipher_finish( &operation2,
3192 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003193 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003194 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003195
Gilles Peskine048b7f02018-06-08 14:20:49 +02003196 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003197
Gilles Peskine8817f612018-12-18 00:18:46 +01003198 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003199
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003200 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003201
3202exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003203 mbedtls_free( output1 );
3204 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003205 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003206 mbedtls_psa_crypto_free( );
3207}
3208/* END_CASE */
3209
3210/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003211void cipher_verify_output_multipart( int alg_arg,
3212 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003213 data_t *key,
3214 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003215 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003216{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003217 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003218 psa_key_type_t key_type = key_type_arg;
3219 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003220 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003221 unsigned char iv[16] = {0};
3222 size_t iv_size = 16;
3223 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003224 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003225 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003226 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003227 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003228 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003229 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003230 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003231 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3232 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003233 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003234
Gilles Peskine8817f612018-12-18 00:18:46 +01003235 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003236
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003237 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3238 psa_set_key_algorithm( &attributes, alg );
3239 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003240
Gilles Peskine73676cb2019-05-15 20:15:10 +02003241 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003242
Gilles Peskine8817f612018-12-18 00:18:46 +01003243 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3244 handle, alg ) );
3245 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3246 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003247
Gilles Peskine8817f612018-12-18 00:18:46 +01003248 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3249 iv, iv_size,
3250 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003251 output1_buffer_size = ( (size_t) input->len +
3252 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003253 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003254
Gilles Peskinee0866522019-02-19 19:44:00 +01003255 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003256
Gilles Peskine8817f612018-12-18 00:18:46 +01003257 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3258 output1, output1_buffer_size,
3259 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003260 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003261
Gilles Peskine8817f612018-12-18 00:18:46 +01003262 PSA_ASSERT( psa_cipher_update( &operation1,
3263 input->x + first_part_size,
3264 input->len - first_part_size,
3265 output1, output1_buffer_size,
3266 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003267 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003268
Gilles Peskine8817f612018-12-18 00:18:46 +01003269 PSA_ASSERT( psa_cipher_finish( &operation1,
3270 output1 + output1_length,
3271 output1_buffer_size - output1_length,
3272 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003273 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003274
Gilles Peskine8817f612018-12-18 00:18:46 +01003275 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003276
Gilles Peskine048b7f02018-06-08 14:20:49 +02003277 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003278 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003279
Gilles Peskine8817f612018-12-18 00:18:46 +01003280 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3281 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003282
Gilles Peskine8817f612018-12-18 00:18:46 +01003283 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3284 output2, output2_buffer_size,
3285 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003286 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003287
Gilles Peskine8817f612018-12-18 00:18:46 +01003288 PSA_ASSERT( psa_cipher_update( &operation2,
3289 output1 + first_part_size,
3290 output1_length - first_part_size,
3291 output2, output2_buffer_size,
3292 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003293 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003294
Gilles Peskine8817f612018-12-18 00:18:46 +01003295 PSA_ASSERT( psa_cipher_finish( &operation2,
3296 output2 + output2_length,
3297 output2_buffer_size - output2_length,
3298 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003299 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003300
Gilles Peskine8817f612018-12-18 00:18:46 +01003301 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003302
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003303 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003304
3305exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003306 mbedtls_free( output1 );
3307 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003308 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003309 mbedtls_psa_crypto_free( );
3310}
3311/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003312
Gilles Peskine20035e32018-02-03 22:44:14 +01003313/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003314void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003315 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003316 data_t *nonce,
3317 data_t *additional_data,
3318 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003319 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003320{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003321 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003322 psa_key_type_t key_type = key_type_arg;
3323 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003324 unsigned char *output_data = NULL;
3325 size_t output_size = 0;
3326 size_t output_length = 0;
3327 unsigned char *output_data2 = NULL;
3328 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003329 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003330 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003331 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003332
Gilles Peskine4abf7412018-06-18 16:35:34 +02003333 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003334 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3335 * should be exact. */
3336 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3337 TEST_EQUAL( output_size,
3338 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003339 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003340
Gilles Peskine8817f612018-12-18 00:18:46 +01003341 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003342
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003343 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3344 psa_set_key_algorithm( &attributes, alg );
3345 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003346
Gilles Peskine049c7532019-05-15 20:22:09 +02003347 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3348 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003349
Gilles Peskinefe11b722018-12-18 00:24:04 +01003350 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3351 nonce->x, nonce->len,
3352 additional_data->x,
3353 additional_data->len,
3354 input_data->x, input_data->len,
3355 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003356 &output_length ),
3357 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003358
3359 if( PSA_SUCCESS == expected_result )
3360 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003361 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003362
Gilles Peskine003a4a92019-05-14 16:09:40 +02003363 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3364 * should be exact. */
3365 TEST_EQUAL( input_data->len,
3366 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3367
Gilles Peskinefe11b722018-12-18 00:24:04 +01003368 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3369 nonce->x, nonce->len,
3370 additional_data->x,
3371 additional_data->len,
3372 output_data, output_length,
3373 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003374 &output_length2 ),
3375 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003376
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003377 ASSERT_COMPARE( input_data->x, input_data->len,
3378 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003379 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003380
Gilles Peskinea1cac842018-06-11 19:33:02 +02003381exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003382 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003383 mbedtls_free( output_data );
3384 mbedtls_free( output_data2 );
3385 mbedtls_psa_crypto_free( );
3386}
3387/* END_CASE */
3388
3389/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003390void aead_encrypt( int key_type_arg, data_t *key_data,
3391 int alg_arg,
3392 data_t *nonce,
3393 data_t *additional_data,
3394 data_t *input_data,
3395 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003396{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003397 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398 psa_key_type_t key_type = key_type_arg;
3399 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400 unsigned char *output_data = NULL;
3401 size_t output_size = 0;
3402 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003403 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003404 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003405
Gilles Peskine4abf7412018-06-18 16:35:34 +02003406 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003407 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3408 * should be exact. */
3409 TEST_EQUAL( output_size,
3410 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003411 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003412
Gilles Peskine8817f612018-12-18 00:18:46 +01003413 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003414
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003415 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3416 psa_set_key_algorithm( &attributes, alg );
3417 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418
Gilles Peskine049c7532019-05-15 20:22:09 +02003419 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3420 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421
Gilles Peskine8817f612018-12-18 00:18:46 +01003422 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3423 nonce->x, nonce->len,
3424 additional_data->x, additional_data->len,
3425 input_data->x, input_data->len,
3426 output_data, output_size,
3427 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003428
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003429 ASSERT_COMPARE( expected_result->x, expected_result->len,
3430 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003431
Gilles Peskinea1cac842018-06-11 19:33:02 +02003432exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003433 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003434 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435 mbedtls_psa_crypto_free( );
3436}
3437/* END_CASE */
3438
3439/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003440void aead_decrypt( int key_type_arg, data_t *key_data,
3441 int alg_arg,
3442 data_t *nonce,
3443 data_t *additional_data,
3444 data_t *input_data,
3445 data_t *expected_data,
3446 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003447{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003448 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003449 psa_key_type_t key_type = key_type_arg;
3450 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003451 unsigned char *output_data = NULL;
3452 size_t output_size = 0;
3453 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003454 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003455 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003456 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003457
Gilles Peskine003a4a92019-05-14 16:09:40 +02003458 output_size = input_data->len - tag_length;
3459 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3460 * should be exact. */
3461 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3462 TEST_EQUAL( output_size,
3463 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003464 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003465
Gilles Peskine8817f612018-12-18 00:18:46 +01003466 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003467
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003468 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3469 psa_set_key_algorithm( &attributes, alg );
3470 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003471
Gilles Peskine049c7532019-05-15 20:22:09 +02003472 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3473 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003474
Gilles Peskinefe11b722018-12-18 00:24:04 +01003475 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3476 nonce->x, nonce->len,
3477 additional_data->x,
3478 additional_data->len,
3479 input_data->x, input_data->len,
3480 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003481 &output_length ),
3482 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003483
Gilles Peskine2d277862018-06-18 15:41:12 +02003484 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003485 ASSERT_COMPARE( expected_data->x, expected_data->len,
3486 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003487
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003489 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003490 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003491 mbedtls_psa_crypto_free( );
3492}
3493/* END_CASE */
3494
3495/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003496void signature_size( int type_arg,
3497 int bits,
3498 int alg_arg,
3499 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003500{
3501 psa_key_type_t type = type_arg;
3502 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003503 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003504 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003505exit:
3506 ;
3507}
3508/* END_CASE */
3509
3510/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003511void sign_deterministic( int key_type_arg, data_t *key_data,
3512 int alg_arg, data_t *input_data,
3513 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003514{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003515 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003516 psa_key_type_t key_type = key_type_arg;
3517 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003518 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003519 unsigned char *signature = NULL;
3520 size_t signature_size;
3521 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003522 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003523
Gilles Peskine8817f612018-12-18 00:18:46 +01003524 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003525
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003526 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3527 psa_set_key_algorithm( &attributes, alg );
3528 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003529
Gilles Peskine049c7532019-05-15 20:22:09 +02003530 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3531 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003532 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3533 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003534
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003535 /* Allocate a buffer which has the size advertized by the
3536 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003537 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3538 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003539 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003540 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003541 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003542
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003543 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003544 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3545 input_data->x, input_data->len,
3546 signature, signature_size,
3547 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003548 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003549 ASSERT_COMPARE( output_data->x, output_data->len,
3550 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003551
3552exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003553 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003554 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003555 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003556 mbedtls_psa_crypto_free( );
3557}
3558/* END_CASE */
3559
3560/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003561void sign_fail( int key_type_arg, data_t *key_data,
3562 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003563 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003564{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003565 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003566 psa_key_type_t key_type = key_type_arg;
3567 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003568 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003569 psa_status_t actual_status;
3570 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003571 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003572 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003573 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003574
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003575 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003576
Gilles Peskine8817f612018-12-18 00:18:46 +01003577 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003578
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003579 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3580 psa_set_key_algorithm( &attributes, alg );
3581 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003582
Gilles Peskine049c7532019-05-15 20:22:09 +02003583 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3584 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003585
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003586 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003587 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003588 signature, signature_size,
3589 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003590 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003591 /* The value of *signature_length is unspecified on error, but
3592 * whatever it is, it should be less than signature_size, so that
3593 * if the caller tries to read *signature_length bytes without
3594 * checking the error code then they don't overflow a buffer. */
3595 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003596
3597exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003598 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003599 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003600 mbedtls_free( signature );
3601 mbedtls_psa_crypto_free( );
3602}
3603/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003604
3605/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003606void sign_verify( int key_type_arg, data_t *key_data,
3607 int alg_arg, data_t *input_data )
3608{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003609 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003610 psa_key_type_t key_type = key_type_arg;
3611 psa_algorithm_t alg = alg_arg;
3612 size_t key_bits;
3613 unsigned char *signature = NULL;
3614 size_t signature_size;
3615 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003616 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003617
Gilles Peskine8817f612018-12-18 00:18:46 +01003618 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003619
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003620 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3621 psa_set_key_algorithm( &attributes, alg );
3622 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003623
Gilles Peskine049c7532019-05-15 20:22:09 +02003624 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3625 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003626 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3627 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003628
3629 /* Allocate a buffer which has the size advertized by the
3630 * library. */
3631 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3632 key_bits, alg );
3633 TEST_ASSERT( signature_size != 0 );
3634 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003635 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003636
3637 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003638 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3639 input_data->x, input_data->len,
3640 signature, signature_size,
3641 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003642 /* Check that the signature length looks sensible. */
3643 TEST_ASSERT( signature_length <= signature_size );
3644 TEST_ASSERT( signature_length > 0 );
3645
3646 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003647 PSA_ASSERT( psa_asymmetric_verify(
3648 handle, alg,
3649 input_data->x, input_data->len,
3650 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003651
3652 if( input_data->len != 0 )
3653 {
3654 /* Flip a bit in the input and verify that the signature is now
3655 * detected as invalid. Flip a bit at the beginning, not at the end,
3656 * because ECDSA may ignore the last few bits of the input. */
3657 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003658 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3659 input_data->x, input_data->len,
3660 signature, signature_length ),
3661 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003662 }
3663
3664exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003665 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003666 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003667 mbedtls_free( signature );
3668 mbedtls_psa_crypto_free( );
3669}
3670/* END_CASE */
3671
3672/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003673void asymmetric_verify( int key_type_arg, data_t *key_data,
3674 int alg_arg, data_t *hash_data,
3675 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003676{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003677 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003678 psa_key_type_t key_type = key_type_arg;
3679 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003680 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003681
Gilles Peskine69c12672018-06-28 00:07:19 +02003682 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3683
Gilles Peskine8817f612018-12-18 00:18:46 +01003684 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003685
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003686 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3687 psa_set_key_algorithm( &attributes, alg );
3688 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003689
Gilles Peskine049c7532019-05-15 20:22:09 +02003690 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3691 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003692
Gilles Peskine8817f612018-12-18 00:18:46 +01003693 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3694 hash_data->x, hash_data->len,
3695 signature_data->x,
3696 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003697exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003698 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003699 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003700 mbedtls_psa_crypto_free( );
3701}
3702/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003703
3704/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003705void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3706 int alg_arg, data_t *hash_data,
3707 data_t *signature_data,
3708 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003709{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003710 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003711 psa_key_type_t key_type = key_type_arg;
3712 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003713 psa_status_t actual_status;
3714 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003715 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003716
Gilles Peskine8817f612018-12-18 00:18:46 +01003717 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003718
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003719 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3720 psa_set_key_algorithm( &attributes, alg );
3721 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003722
Gilles Peskine049c7532019-05-15 20:22:09 +02003723 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3724 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003725
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003726 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003727 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003728 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003729 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003730
Gilles Peskinefe11b722018-12-18 00:24:04 +01003731 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003732
3733exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003734 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003735 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003736 mbedtls_psa_crypto_free( );
3737}
3738/* END_CASE */
3739
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003740/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003741void asymmetric_encrypt( int key_type_arg,
3742 data_t *key_data,
3743 int alg_arg,
3744 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003745 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003746 int expected_output_length_arg,
3747 int expected_status_arg )
3748{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003749 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003750 psa_key_type_t key_type = key_type_arg;
3751 psa_algorithm_t alg = alg_arg;
3752 size_t expected_output_length = expected_output_length_arg;
3753 size_t key_bits;
3754 unsigned char *output = NULL;
3755 size_t output_size;
3756 size_t output_length = ~0;
3757 psa_status_t actual_status;
3758 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003759 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003760
Gilles Peskine8817f612018-12-18 00:18:46 +01003761 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003762
Gilles Peskine656896e2018-06-29 19:12:28 +02003763 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003764 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3765 psa_set_key_algorithm( &attributes, alg );
3766 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003767 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3768 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003769
3770 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003771 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3772 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003773 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003774 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003775
3776 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003777 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003778 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003779 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003780 output, output_size,
3781 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003782 TEST_EQUAL( actual_status, expected_status );
3783 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003784
Gilles Peskine68428122018-06-30 18:42:41 +02003785 /* If the label is empty, the test framework puts a non-null pointer
3786 * in label->x. Test that a null pointer works as well. */
3787 if( label->len == 0 )
3788 {
3789 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003790 if( output_size != 0 )
3791 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003792 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003793 input_data->x, input_data->len,
3794 NULL, label->len,
3795 output, output_size,
3796 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003797 TEST_EQUAL( actual_status, expected_status );
3798 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003799 }
3800
Gilles Peskine656896e2018-06-29 19:12:28 +02003801exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003802 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003803 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003804 mbedtls_free( output );
3805 mbedtls_psa_crypto_free( );
3806}
3807/* END_CASE */
3808
3809/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003810void asymmetric_encrypt_decrypt( int key_type_arg,
3811 data_t *key_data,
3812 int alg_arg,
3813 data_t *input_data,
3814 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003815{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003816 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003817 psa_key_type_t key_type = key_type_arg;
3818 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003819 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003820 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003821 size_t output_size;
3822 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003823 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003824 size_t output2_size;
3825 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003826 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003827
Gilles Peskine8817f612018-12-18 00:18:46 +01003828 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003829
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003830 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3831 psa_set_key_algorithm( &attributes, alg );
3832 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003833
Gilles Peskine049c7532019-05-15 20:22:09 +02003834 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3835 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003836
3837 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003838 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3839 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003840 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003841 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003842 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003843 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003844
Gilles Peskineeebd7382018-06-08 18:11:54 +02003845 /* We test encryption by checking that encrypt-then-decrypt gives back
3846 * the original plaintext because of the non-optional random
3847 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003848 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3849 input_data->x, input_data->len,
3850 label->x, label->len,
3851 output, output_size,
3852 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003853 /* We don't know what ciphertext length to expect, but check that
3854 * it looks sensible. */
3855 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003856
Gilles Peskine8817f612018-12-18 00:18:46 +01003857 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3858 output, output_length,
3859 label->x, label->len,
3860 output2, output2_size,
3861 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003862 ASSERT_COMPARE( input_data->x, input_data->len,
3863 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003864
3865exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003866 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003867 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003868 mbedtls_free( output );
3869 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003870 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871}
3872/* END_CASE */
3873
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003874/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003875void asymmetric_decrypt( int key_type_arg,
3876 data_t *key_data,
3877 int alg_arg,
3878 data_t *input_data,
3879 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003880 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003882 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883 psa_key_type_t key_type = key_type_arg;
3884 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003885 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003886 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003887 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003888 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003889
Jaeden Amero412654a2019-02-06 12:57:46 +00003890 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003891 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003892
Gilles Peskine8817f612018-12-18 00:18:46 +01003893 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003894
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003895 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3896 psa_set_key_algorithm( &attributes, alg );
3897 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003898
Gilles Peskine049c7532019-05-15 20:22:09 +02003899 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3900 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003901
Gilles Peskine8817f612018-12-18 00:18:46 +01003902 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3903 input_data->x, input_data->len,
3904 label->x, label->len,
3905 output,
3906 output_size,
3907 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003908 ASSERT_COMPARE( expected_data->x, expected_data->len,
3909 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003910
Gilles Peskine68428122018-06-30 18:42:41 +02003911 /* If the label is empty, the test framework puts a non-null pointer
3912 * in label->x. Test that a null pointer works as well. */
3913 if( label->len == 0 )
3914 {
3915 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003916 if( output_size != 0 )
3917 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003918 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3919 input_data->x, input_data->len,
3920 NULL, label->len,
3921 output,
3922 output_size,
3923 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003924 ASSERT_COMPARE( expected_data->x, expected_data->len,
3925 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003926 }
3927
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003928exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003929 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003930 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003931 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003932 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003933}
3934/* END_CASE */
3935
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003936/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003937void asymmetric_decrypt_fail( int key_type_arg,
3938 data_t *key_data,
3939 int alg_arg,
3940 data_t *input_data,
3941 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003942 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003943 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003944{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003945 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003946 psa_key_type_t key_type = key_type_arg;
3947 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003948 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003949 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003950 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003951 psa_status_t actual_status;
3952 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003953 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003954
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003955 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003956
Gilles Peskine8817f612018-12-18 00:18:46 +01003957 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003958
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003959 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3960 psa_set_key_algorithm( &attributes, alg );
3961 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003962
Gilles Peskine049c7532019-05-15 20:22:09 +02003963 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3964 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003965
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003966 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003967 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003968 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003969 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003970 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003971 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003972 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003973
Gilles Peskine68428122018-06-30 18:42:41 +02003974 /* If the label is empty, the test framework puts a non-null pointer
3975 * in label->x. Test that a null pointer works as well. */
3976 if( label->len == 0 )
3977 {
3978 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003979 if( output_size != 0 )
3980 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003981 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003982 input_data->x, input_data->len,
3983 NULL, label->len,
3984 output, output_size,
3985 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003986 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003987 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003988 }
3989
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003990exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003991 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003992 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003993 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003994 mbedtls_psa_crypto_free( );
3995}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003996/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003997
3998/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02003999void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004000{
4001 /* Test each valid way of initializing the object, except for `= {0}`, as
4002 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4003 * though it's OK by the C standard. We could test for this, but we'd need
4004 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004005 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004006 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4007 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4008 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004009
4010 memset( &zero, 0, sizeof( zero ) );
4011
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004012 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004013 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004014 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004015 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004016 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004017 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004018 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004019
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004020 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004021 PSA_ASSERT( psa_key_derivation_abort(&func) );
4022 PSA_ASSERT( psa_key_derivation_abort(&init) );
4023 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004024}
4025/* END_CASE */
4026
4027/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004028void derive_setup( int key_type_arg,
4029 data_t *key_data,
4030 int alg_arg,
4031 data_t *salt,
4032 data_t *label,
4033 int requested_capacity_arg,
4034 int expected_status_arg )
4035{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004036 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004037 size_t key_type = key_type_arg;
4038 psa_algorithm_t alg = alg_arg;
4039 size_t requested_capacity = requested_capacity_arg;
4040 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004041 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004042 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004043
Gilles Peskine8817f612018-12-18 00:18:46 +01004044 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004045
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004046 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4047 psa_set_key_algorithm( &attributes, alg );
4048 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004049
Gilles Peskine049c7532019-05-15 20:22:09 +02004050 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4051 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004052
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004053 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004054 salt->x, salt->len,
4055 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004056 requested_capacity ),
4057 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004058
4059exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004060 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004061 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004062 mbedtls_psa_crypto_free( );
4063}
4064/* END_CASE */
4065
4066/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004067void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004068{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004069 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004070 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004071 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004072 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004073 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004074 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004075 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4076 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4077 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004078 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004079
Gilles Peskine8817f612018-12-18 00:18:46 +01004080 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004081
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004082 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4083 psa_set_key_algorithm( &attributes, alg );
4084 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004085
Gilles Peskine73676cb2019-05-15 20:15:10 +02004086 PSA_ASSERT( psa_import_key( &attributes,
4087 key_data, sizeof( key_data ),
4088 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004089
4090 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004091 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004092 NULL, 0,
4093 NULL, 0,
4094 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004095
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004096 /* state of operation shouldn't allow additional generation */
4097 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004098 NULL, 0,
4099 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004100 capacity ),
4101 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004102
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004103 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004104
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004105 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004106 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004107
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004108exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004109 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004110 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004111 mbedtls_psa_crypto_free( );
4112}
4113/* END_CASE */
4114
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004115/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004116void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004117{
4118 uint8_t output_buffer[16];
4119 size_t buffer_size = 16;
4120 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004121 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004122
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004123 TEST_ASSERT( psa_key_derivation_output_bytes( &operation, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004124 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004125
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004126 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004127 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004128
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004129 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004130
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004131 TEST_ASSERT( psa_key_derivation_output_bytes( &operation, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004132 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004133
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004134 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004135 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004136
4137exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004138 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004139}
4140/* END_CASE */
4141
4142/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004143void derive_output( int alg_arg,
4144 data_t *key_data,
4145 data_t *salt,
4146 data_t *label,
4147 int requested_capacity_arg,
4148 data_t *expected_output1,
4149 data_t *expected_output2 )
4150{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004151 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004152 psa_algorithm_t alg = alg_arg;
4153 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004154 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004155 uint8_t *expected_outputs[2] =
4156 {expected_output1->x, expected_output2->x};
4157 size_t output_sizes[2] =
4158 {expected_output1->len, expected_output2->len};
4159 size_t output_buffer_size = 0;
4160 uint8_t *output_buffer = NULL;
4161 size_t expected_capacity;
4162 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004163 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004164 psa_status_t status;
4165 unsigned i;
4166
4167 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4168 {
4169 if( output_sizes[i] > output_buffer_size )
4170 output_buffer_size = output_sizes[i];
4171 if( output_sizes[i] == 0 )
4172 expected_outputs[i] = NULL;
4173 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004174 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004175 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004176
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004177 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4178 psa_set_key_algorithm( &attributes, alg );
4179 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004180
Gilles Peskine049c7532019-05-15 20:22:09 +02004181 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4182 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004183
4184 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004185 if( PSA_ALG_IS_HKDF( alg ) )
4186 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004187 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4188 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004189 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004190 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004191 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004192 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004193 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004194 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004195 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004196 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004197 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004198 label->x, label->len ) );
4199 }
4200 else
4201 {
4202 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004203 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004204 salt->x, salt->len,
4205 label->x, label->len,
4206 requested_capacity ) );
4207 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004208 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004209 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004210 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004211 expected_capacity = requested_capacity;
4212
4213 /* Expansion phase. */
4214 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4215 {
4216 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004217 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004218 output_buffer, output_sizes[i] );
4219 if( expected_capacity == 0 && output_sizes[i] == 0 )
4220 {
4221 /* Reading 0 bytes when 0 bytes are available can go either way. */
4222 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004223 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004224 continue;
4225 }
4226 else if( expected_capacity == 0 ||
4227 output_sizes[i] > expected_capacity )
4228 {
4229 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004230 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004231 expected_capacity = 0;
4232 continue;
4233 }
4234 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004235 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004236 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004237 ASSERT_COMPARE( output_buffer, output_sizes[i],
4238 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004239 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004240 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004241 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004242 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004243 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004244 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004245 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004246
4247exit:
4248 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004249 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004250 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004251 mbedtls_psa_crypto_free( );
4252}
4253/* END_CASE */
4254
4255/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004256void derive_full( int alg_arg,
4257 data_t *key_data,
4258 data_t *salt,
4259 data_t *label,
4260 int requested_capacity_arg )
4261{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004262 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004263 psa_algorithm_t alg = alg_arg;
4264 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004265 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004266 unsigned char output_buffer[16];
4267 size_t expected_capacity = requested_capacity;
4268 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004269 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004270
Gilles Peskine8817f612018-12-18 00:18:46 +01004271 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004272
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004273 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4274 psa_set_key_algorithm( &attributes, alg );
4275 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004276
Gilles Peskine049c7532019-05-15 20:22:09 +02004277 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4278 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004279
4280 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004281 if( PSA_ALG_IS_HKDF( alg ) )
4282 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004283 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4284 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004285 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004286 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004287 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004288 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004289 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004290 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004291 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004292 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004293 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004294 label->x, label->len ) );
4295 }
4296 else
4297 {
4298 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004299 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004300 salt->x, salt->len,
4301 label->x, label->len,
4302 requested_capacity ) );
4303 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004304 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004305 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004306 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004307
4308 /* Expansion phase. */
4309 while( current_capacity > 0 )
4310 {
4311 size_t read_size = sizeof( output_buffer );
4312 if( read_size > current_capacity )
4313 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004314 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004315 output_buffer,
4316 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004317 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004318 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004319 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004320 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004321 }
4322
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004323 /* Check that the operation refuses to go over capacity. */
4324 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004325 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004326
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004327 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004328
4329exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004330 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004331 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004332 mbedtls_psa_crypto_free( );
4333}
4334/* END_CASE */
4335
4336/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004337void derive_key_exercise( int alg_arg,
4338 data_t *key_data,
4339 data_t *salt,
4340 data_t *label,
4341 int derived_type_arg,
4342 int derived_bits_arg,
4343 int derived_usage_arg,
4344 int derived_alg_arg )
4345{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004346 psa_key_handle_t base_handle = 0;
4347 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004348 psa_algorithm_t alg = alg_arg;
4349 psa_key_type_t derived_type = derived_type_arg;
4350 size_t derived_bits = derived_bits_arg;
4351 psa_key_usage_t derived_usage = derived_usage_arg;
4352 psa_algorithm_t derived_alg = derived_alg_arg;
4353 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004354 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004355 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004356 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004357
Gilles Peskine8817f612018-12-18 00:18:46 +01004358 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004359
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004360 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4361 psa_set_key_algorithm( &attributes, alg );
4362 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004363 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4364 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004365
4366 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004367 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004368 salt->x, salt->len,
4369 label->x, label->len,
4370 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004371 psa_set_key_usage_flags( &attributes, derived_usage );
4372 psa_set_key_algorithm( &attributes, derived_alg );
4373 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004374 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004375 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskine98dd7792019-05-15 19:43:49 +02004376 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004377
4378 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004379 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4380 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4381 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004382
4383 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004384 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004385 goto exit;
4386
4387exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004388 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004389 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004390 psa_destroy_key( base_handle );
4391 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004392 mbedtls_psa_crypto_free( );
4393}
4394/* END_CASE */
4395
4396/* BEGIN_CASE */
4397void derive_key_export( int alg_arg,
4398 data_t *key_data,
4399 data_t *salt,
4400 data_t *label,
4401 int bytes1_arg,
4402 int bytes2_arg )
4403{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004404 psa_key_handle_t base_handle = 0;
4405 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004406 psa_algorithm_t alg = alg_arg;
4407 size_t bytes1 = bytes1_arg;
4408 size_t bytes2 = bytes2_arg;
4409 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004410 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004411 uint8_t *output_buffer = NULL;
4412 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004413 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4414 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004415 size_t length;
4416
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004417 ASSERT_ALLOC( output_buffer, capacity );
4418 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004419 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004420
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004421 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4422 psa_set_key_algorithm( &base_attributes, alg );
4423 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004424 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4425 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004426
4427 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004428 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004429 salt->x, salt->len,
4430 label->x, label->len,
4431 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004432 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004433 output_buffer,
4434 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004435 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004436
4437 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004438 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004439 salt->x, salt->len,
4440 label->x, label->len,
4441 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004442 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4443 psa_set_key_algorithm( &derived_attributes, 0 );
4444 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004445 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004446 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskine98dd7792019-05-15 19:43:49 +02004447 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004448 PSA_ASSERT( psa_export_key( derived_handle,
4449 export_buffer, bytes1,
4450 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004451 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004452 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004453 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004454 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskine98dd7792019-05-15 19:43:49 +02004455 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004456 PSA_ASSERT( psa_export_key( derived_handle,
4457 export_buffer + bytes1, bytes2,
4458 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004459 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004460
4461 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004462 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4463 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004464
4465exit:
4466 mbedtls_free( output_buffer );
4467 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004468 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004469 psa_destroy_key( base_handle );
4470 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004471 mbedtls_psa_crypto_free( );
4472}
4473/* END_CASE */
4474
4475/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004476void key_agreement_setup( int alg_arg,
4477 int our_key_type_arg, data_t *our_key_data,
4478 data_t *peer_key_data,
4479 int expected_status_arg )
4480{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004481 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004482 psa_algorithm_t alg = alg_arg;
4483 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004484 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004485 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004486 psa_status_t expected_status = expected_status_arg;
4487 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004488
Gilles Peskine8817f612018-12-18 00:18:46 +01004489 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004490
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004491 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4492 psa_set_key_algorithm( &attributes, alg );
4493 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004494 PSA_ASSERT( psa_import_key( &attributes,
4495 our_key_data->x, our_key_data->len,
4496 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004497
Gilles Peskine77f40d82019-04-11 21:27:06 +02004498 /* The tests currently include inputs that should fail at either step.
4499 * Test cases that fail at the setup step should be changed to call
4500 * key_derivation_setup instead, and this function should be renamed
4501 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004502 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004503 if( status == PSA_SUCCESS )
4504 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004505 TEST_EQUAL( psa_key_derivation_key_agreement( &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskine77f40d82019-04-11 21:27:06 +02004506 our_key,
4507 peer_key_data->x, peer_key_data->len ),
4508 expected_status );
4509 }
4510 else
4511 {
4512 TEST_ASSERT( status == expected_status );
4513 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004514
4515exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004516 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004517 psa_destroy_key( our_key );
4518 mbedtls_psa_crypto_free( );
4519}
4520/* END_CASE */
4521
4522/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004523void raw_key_agreement( int alg_arg,
4524 int our_key_type_arg, data_t *our_key_data,
4525 data_t *peer_key_data,
4526 data_t *expected_output )
4527{
4528 psa_key_handle_t our_key = 0;
4529 psa_algorithm_t alg = alg_arg;
4530 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004531 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004532 unsigned char *output = NULL;
4533 size_t output_length = ~0;
4534
4535 ASSERT_ALLOC( output, expected_output->len );
4536 PSA_ASSERT( psa_crypto_init( ) );
4537
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004538 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4539 psa_set_key_algorithm( &attributes, alg );
4540 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004541 PSA_ASSERT( psa_import_key( &attributes,
4542 our_key_data->x, our_key_data->len,
4543 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004544
4545 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4546 alg, our_key,
4547 peer_key_data->x, peer_key_data->len,
4548 output, expected_output->len, &output_length ) );
4549 ASSERT_COMPARE( output, output_length,
4550 expected_output->x, expected_output->len );
4551
4552exit:
4553 mbedtls_free( output );
4554 psa_destroy_key( our_key );
4555 mbedtls_psa_crypto_free( );
4556}
4557/* END_CASE */
4558
4559/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004560void key_agreement_capacity( int alg_arg,
4561 int our_key_type_arg, data_t *our_key_data,
4562 data_t *peer_key_data,
4563 int expected_capacity_arg )
4564{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004565 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004566 psa_algorithm_t alg = alg_arg;
4567 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004568 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004569 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004570 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004571 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004572
Gilles Peskine8817f612018-12-18 00:18:46 +01004573 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004574
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004575 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4576 psa_set_key_algorithm( &attributes, alg );
4577 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004578 PSA_ASSERT( psa_import_key( &attributes,
4579 our_key_data->x, our_key_data->len,
4580 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004581
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004582 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4583 PSA_ASSERT( psa_key_derivation_key_agreement( &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004584 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004585 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004586 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4587 {
4588 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004589 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004590 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004591 NULL, 0 ) );
4592 }
Gilles Peskine59685592018-09-18 12:11:34 +02004593
Gilles Peskinebf491972018-10-25 22:36:12 +02004594 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004595 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004596 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004597 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004598
Gilles Peskinebf491972018-10-25 22:36:12 +02004599 /* Test the actual capacity by reading the output. */
4600 while( actual_capacity > sizeof( output ) )
4601 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004602 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004603 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004604 actual_capacity -= sizeof( output );
4605 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004606 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskine8817f612018-12-18 00:18:46 +01004607 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004608 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004609 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004610
Gilles Peskine59685592018-09-18 12:11:34 +02004611exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004612 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004613 psa_destroy_key( our_key );
4614 mbedtls_psa_crypto_free( );
4615}
4616/* END_CASE */
4617
4618/* BEGIN_CASE */
4619void key_agreement_output( int alg_arg,
4620 int our_key_type_arg, data_t *our_key_data,
4621 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004622 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004623{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004624 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004625 psa_algorithm_t alg = alg_arg;
4626 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004627 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004628 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004629 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004630
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004631 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4632 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004633
Gilles Peskine8817f612018-12-18 00:18:46 +01004634 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004635
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004636 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4637 psa_set_key_algorithm( &attributes, alg );
4638 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004639 PSA_ASSERT( psa_import_key( &attributes,
4640 our_key_data->x, our_key_data->len,
4641 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004642
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004643 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4644 PSA_ASSERT( psa_key_derivation_key_agreement( &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004645 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004646 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004647 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4648 {
4649 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004650 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004651 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004652 NULL, 0 ) );
4653 }
Gilles Peskine59685592018-09-18 12:11:34 +02004654
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004655 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004656 actual_output,
4657 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004658 ASSERT_COMPARE( actual_output, expected_output1->len,
4659 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004660 if( expected_output2->len != 0 )
4661 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004662 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004663 actual_output,
4664 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004665 ASSERT_COMPARE( actual_output, expected_output2->len,
4666 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004667 }
Gilles Peskine59685592018-09-18 12:11:34 +02004668
4669exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004670 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004671 psa_destroy_key( our_key );
4672 mbedtls_psa_crypto_free( );
4673 mbedtls_free( actual_output );
4674}
4675/* END_CASE */
4676
4677/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004678void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004679{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004680 size_t bytes = bytes_arg;
4681 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004682 unsigned char *output = NULL;
4683 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004684 size_t i;
4685 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004686
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004687 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4688 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004689 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004690
Gilles Peskine8817f612018-12-18 00:18:46 +01004691 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004692
Gilles Peskinea50d7392018-06-21 10:22:13 +02004693 /* Run several times, to ensure that every output byte will be
4694 * nonzero at least once with overwhelming probability
4695 * (2^(-8*number_of_runs)). */
4696 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004697 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004698 if( bytes != 0 )
4699 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004700 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004701
4702 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004703 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4704 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004705
4706 for( i = 0; i < bytes; i++ )
4707 {
4708 if( output[i] != 0 )
4709 ++changed[i];
4710 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004711 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004712
4713 /* Check that every byte was changed to nonzero at least once. This
4714 * validates that psa_generate_random is overwriting every byte of
4715 * the output buffer. */
4716 for( i = 0; i < bytes; i++ )
4717 {
4718 TEST_ASSERT( changed[i] != 0 );
4719 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004720
4721exit:
4722 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004723 mbedtls_free( output );
4724 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004725}
4726/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004727
4728/* BEGIN_CASE */
4729void generate_key( int type_arg,
4730 int bits_arg,
4731 int usage_arg,
4732 int alg_arg,
4733 int expected_status_arg )
4734{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004735 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004736 psa_key_type_t type = type_arg;
4737 psa_key_usage_t usage = usage_arg;
4738 size_t bits = bits_arg;
4739 psa_algorithm_t alg = alg_arg;
4740 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004741 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004742 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004743
Gilles Peskine8817f612018-12-18 00:18:46 +01004744 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004745
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004746 psa_set_key_usage_flags( &attributes, usage );
4747 psa_set_key_algorithm( &attributes, alg );
4748 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004749 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004750
4751 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004752 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004753 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004754 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004755
4756 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004757 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4758 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4759 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004760
Gilles Peskine818ca122018-06-20 18:16:48 +02004761 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004762 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004763 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004764
4765exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004766 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004767 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004768 mbedtls_psa_crypto_free( );
4769}
4770/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004771
Gilles Peskinee56e8782019-04-26 17:34:02 +02004772/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4773void generate_key_rsa( int bits_arg,
4774 data_t *e_arg,
4775 int expected_status_arg )
4776{
4777 psa_key_handle_t handle = 0;
4778 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEYPAIR;
4779 size_t bits = bits_arg;
4780 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4781 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4782 psa_status_t expected_status = expected_status_arg;
4783 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4784 uint8_t *exported = NULL;
4785 size_t exported_size =
4786 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4787 size_t exported_length = SIZE_MAX;
4788 uint8_t *e_read_buffer = NULL;
4789 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004790 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004791 size_t e_read_length = SIZE_MAX;
4792
4793 if( e_arg->len == 0 ||
4794 ( e_arg->len == 3 &&
4795 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4796 {
4797 is_default_public_exponent = 1;
4798 e_read_size = 0;
4799 }
4800 ASSERT_ALLOC( e_read_buffer, e_read_size );
4801 ASSERT_ALLOC( exported, exported_size );
4802
4803 PSA_ASSERT( psa_crypto_init( ) );
4804
4805 psa_set_key_usage_flags( &attributes, usage );
4806 psa_set_key_algorithm( &attributes, alg );
4807 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4808 e_arg->x, e_arg->len ) );
4809 psa_set_key_bits( &attributes, bits );
4810
4811 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004812 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004813 if( expected_status != PSA_SUCCESS )
4814 goto exit;
4815
4816 /* Test the key information */
4817 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4818 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4819 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4820 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4821 e_read_buffer, e_read_size,
4822 &e_read_length ) );
4823 if( is_default_public_exponent )
4824 TEST_EQUAL( e_read_length, 0 );
4825 else
4826 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4827
4828 /* Do something with the key according to its type and permitted usage. */
4829 if( ! exercise_key( handle, usage, alg ) )
4830 goto exit;
4831
4832 /* Export the key and check the public exponent. */
4833 PSA_ASSERT( psa_export_public_key( handle,
4834 exported, exported_size,
4835 &exported_length ) );
4836 {
4837 uint8_t *p = exported;
4838 uint8_t *end = exported + exported_length;
4839 size_t len;
4840 /* RSAPublicKey ::= SEQUENCE {
4841 * modulus INTEGER, -- n
4842 * publicExponent INTEGER } -- e
4843 */
4844 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4845 MBEDTLS_ASN1_SEQUENCE |
4846 MBEDTLS_ASN1_CONSTRUCTED ) );
4847 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4848 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4849 MBEDTLS_ASN1_INTEGER ) );
4850 if( len >= 1 && p[0] == 0 )
4851 {
4852 ++p;
4853 --len;
4854 }
4855 if( e_arg->len == 0 )
4856 {
4857 TEST_EQUAL( len, 3 );
4858 TEST_EQUAL( p[0], 1 );
4859 TEST_EQUAL( p[1], 0 );
4860 TEST_EQUAL( p[2], 1 );
4861 }
4862 else
4863 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4864 }
4865
4866exit:
4867 psa_reset_key_attributes( &attributes );
4868 psa_destroy_key( handle );
4869 mbedtls_psa_crypto_free( );
4870 mbedtls_free( e_read_buffer );
4871 mbedtls_free( exported );
4872}
4873/* END_CASE */
4874
Darryl Greend49a4992018-06-18 17:27:26 +01004875/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004876void persistent_key_load_key_from_storage( data_t *data,
4877 int type_arg, int bits_arg,
4878 int usage_flags_arg, int alg_arg,
4879 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004880{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004881 psa_key_id_t key_id = 1;
4882 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004883 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004884 psa_key_handle_t base_key = 0;
4885 psa_key_type_t type = type_arg;
4886 size_t bits = bits_arg;
4887 psa_key_usage_t usage_flags = usage_flags_arg;
4888 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004889 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004890 unsigned char *first_export = NULL;
4891 unsigned char *second_export = NULL;
4892 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4893 size_t first_exported_length;
4894 size_t second_exported_length;
4895
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004896 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4897 {
4898 ASSERT_ALLOC( first_export, export_size );
4899 ASSERT_ALLOC( second_export, export_size );
4900 }
Darryl Greend49a4992018-06-18 17:27:26 +01004901
Gilles Peskine8817f612018-12-18 00:18:46 +01004902 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004903
Gilles Peskinec87af662019-05-15 16:12:22 +02004904 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004905 psa_set_key_usage_flags( &attributes, usage_flags );
4906 psa_set_key_algorithm( &attributes, alg );
4907 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004908 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004909
Darryl Green0c6575a2018-11-07 16:05:30 +00004910 switch( generation_method )
4911 {
4912 case IMPORT_KEY:
4913 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004914 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4915 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004916 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004917
Darryl Green0c6575a2018-11-07 16:05:30 +00004918 case GENERATE_KEY:
4919 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004920 PSA_ASSERT( psa_generate_random_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004921 break;
4922
4923 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004924 {
4925 /* Create base key */
4926 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4927 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4928 psa_set_key_usage_flags( &base_attributes,
4929 PSA_KEY_USAGE_DERIVE );
4930 psa_set_key_algorithm( &base_attributes, derive_alg );
4931 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004932 PSA_ASSERT( psa_import_key( &base_attributes,
4933 data->x, data->len,
4934 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004935 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004936 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
4937 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004938 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004939 base_key ) );
4940 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004941 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004942 NULL, 0 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004943 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskine98dd7792019-05-15 19:43:49 +02004944 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004945 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004946 PSA_ASSERT( psa_destroy_key( base_key ) );
4947 base_key = 0;
4948 }
Darryl Green0c6575a2018-11-07 16:05:30 +00004949 break;
4950 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004951 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004952
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004953 /* Export the key if permitted by the key policy. */
4954 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4955 {
4956 PSA_ASSERT( psa_export_key( handle,
4957 first_export, export_size,
4958 &first_exported_length ) );
4959 if( generation_method == IMPORT_KEY )
4960 ASSERT_COMPARE( data->x, data->len,
4961 first_export, first_exported_length );
4962 }
Darryl Greend49a4992018-06-18 17:27:26 +01004963
4964 /* Shutdown and restart */
4965 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004966 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004967
Darryl Greend49a4992018-06-18 17:27:26 +01004968 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02004969 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004970 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4971 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4972 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4973 PSA_KEY_LIFETIME_PERSISTENT );
4974 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4975 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4976 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4977 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004978
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004979 /* Export the key again if permitted by the key policy. */
4980 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004981 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004982 PSA_ASSERT( psa_export_key( handle,
4983 second_export, export_size,
4984 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004985 ASSERT_COMPARE( first_export, first_exported_length,
4986 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004987 }
4988
4989 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004990 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004991 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004992
4993exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004994 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004995 mbedtls_free( first_export );
4996 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004997 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004998 psa_destroy_key( base_key );
4999 if( handle == 0 )
5000 {
5001 /* In case there was a test failure after creating the persistent key
5002 * but while it was not open, try to re-open the persistent key
5003 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005004 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005005 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005006 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01005007 mbedtls_psa_crypto_free();
5008}
5009/* END_CASE */