blob: aaa3189a826bd77719642cc38becb6b10f211c2e [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 Peskinecf7292e2019-05-16 17:53:40 +0200562 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 Peskinecf7292e2019-05-16 17:53:40 +0200575static psa_status_t key_agreement_with_self(
576 psa_key_derivation_operation_t *operation,
577 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100578{
579 psa_key_type_t private_key_type;
580 psa_key_type_t public_key_type;
581 size_t key_bits;
582 uint8_t *public_key = NULL;
583 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200584 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200585 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
586 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200587 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200588 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100589
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200590 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
591 private_key_type = psa_get_key_type( &attributes );
592 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200593 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100594 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
595 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100596 PSA_ASSERT( psa_export_public_key( handle,
597 public_key, public_key_length,
598 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100599
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200600 status = psa_key_derivation_key_agreement(
601 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
602 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100603exit:
604 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200605 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100606 return( status );
607}
608
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200609/* We need two keys to exercise key agreement. Exercise the
610 * private key against its own public key. */
611static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
612 psa_key_handle_t handle )
613{
614 psa_key_type_t private_key_type;
615 psa_key_type_t public_key_type;
616 size_t key_bits;
617 uint8_t *public_key = NULL;
618 size_t public_key_length;
619 uint8_t output[1024];
620 size_t output_length;
621 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200622 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
623 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200624 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200625 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200626
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200627 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
628 private_key_type = psa_get_key_type( &attributes );
629 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200630 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200631 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
632 ASSERT_ALLOC( public_key, public_key_length );
633 PSA_ASSERT( psa_export_public_key( handle,
634 public_key, public_key_length,
635 &public_key_length ) );
636
Gilles Peskinebe697d82019-05-16 18:00:41 +0200637 status = psa_raw_key_agreement( alg, handle,
638 public_key, public_key_length,
639 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200640exit:
641 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200642 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200643 return( status );
644}
645
646static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
647 psa_key_usage_t usage,
648 psa_algorithm_t alg )
649{
650 int ok = 0;
651
652 if( usage & PSA_KEY_USAGE_DERIVE )
653 {
654 /* We need two keys to exercise key agreement. Exercise the
655 * private key against its own public key. */
656 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
657 }
658 ok = 1;
659
660exit:
661 return( ok );
662}
663
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100664static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200665 psa_key_usage_t usage,
666 psa_algorithm_t alg )
667{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200668 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200669 unsigned char output[1];
670 int ok = 0;
671
672 if( usage & PSA_KEY_USAGE_DERIVE )
673 {
674 /* We need two keys to exercise key agreement. Exercise the
675 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200676 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
677 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
678 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200679 output,
680 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200681 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200682 }
683 ok = 1;
684
685exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200686 return( ok );
687}
688
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200689static int is_oid_of_key_type( psa_key_type_t type,
690 const uint8_t *oid, size_t oid_length )
691{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200692 const uint8_t *expected_oid = NULL;
693 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200694#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200695 if( PSA_KEY_TYPE_IS_RSA( type ) )
696 {
697 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
698 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
699 }
700 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200701#endif /* MBEDTLS_RSA_C */
702#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200703 if( PSA_KEY_TYPE_IS_ECC( type ) )
704 {
705 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
706 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
707 }
708 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200709#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200710 {
711 char message[40];
712 mbedtls_snprintf( message, sizeof( message ),
713 "OID not known for key type=0x%08lx",
714 (unsigned long) type );
715 test_fail( message, __LINE__, __FILE__ );
716 return( 0 );
717 }
718
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200719 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200720 return( 1 );
721
722exit:
723 return( 0 );
724}
725
726static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
727 size_t min_bits, size_t max_bits,
728 int must_be_odd )
729{
730 size_t len;
731 size_t actual_bits;
732 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100733 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100734 MBEDTLS_ASN1_INTEGER ),
735 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200736 /* Tolerate a slight departure from DER encoding:
737 * - 0 may be represented by an empty string or a 1-byte string.
738 * - The sign bit may be used as a value bit. */
739 if( ( len == 1 && ( *p )[0] == 0 ) ||
740 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
741 {
742 ++( *p );
743 --len;
744 }
745 if( min_bits == 0 && len == 0 )
746 return( 1 );
747 msb = ( *p )[0];
748 TEST_ASSERT( msb != 0 );
749 actual_bits = 8 * ( len - 1 );
750 while( msb != 0 )
751 {
752 msb >>= 1;
753 ++actual_bits;
754 }
755 TEST_ASSERT( actual_bits >= min_bits );
756 TEST_ASSERT( actual_bits <= max_bits );
757 if( must_be_odd )
758 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
759 *p += len;
760 return( 1 );
761exit:
762 return( 0 );
763}
764
765static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
766 size_t *len,
767 unsigned char n, unsigned char tag )
768{
769 int ret;
770 ret = mbedtls_asn1_get_tag( p, end, len,
771 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
772 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
773 if( ret != 0 )
774 return( ret );
775 end = *p + *len;
776 ret = mbedtls_asn1_get_tag( p, end, len, tag );
777 if( ret != 0 )
778 return( ret );
779 if( *p + *len != end )
780 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
781 return( 0 );
782}
783
784static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
785 uint8_t *exported, size_t exported_length )
786{
787 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100788 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200789 else
790 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200791
792#if defined(MBEDTLS_DES_C)
793 if( type == PSA_KEY_TYPE_DES )
794 {
795 /* Check the parity bits. */
796 unsigned i;
797 for( i = 0; i < bits / 8; i++ )
798 {
799 unsigned bit_count = 0;
800 unsigned m;
801 for( m = 1; m <= 0x100; m <<= 1 )
802 {
803 if( exported[i] & m )
804 ++bit_count;
805 }
806 TEST_ASSERT( bit_count % 2 != 0 );
807 }
808 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200809 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200810#endif
811
812#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200813 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200814 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200815 uint8_t *p = exported;
816 uint8_t *end = exported + exported_length;
817 size_t len;
818 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200819 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200820 * modulus INTEGER, -- n
821 * publicExponent INTEGER, -- e
822 * privateExponent INTEGER, -- d
823 * prime1 INTEGER, -- p
824 * prime2 INTEGER, -- q
825 * exponent1 INTEGER, -- d mod (p-1)
826 * exponent2 INTEGER, -- d mod (q-1)
827 * coefficient INTEGER, -- (inverse of q) mod p
828 * }
829 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100830 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
831 MBEDTLS_ASN1_SEQUENCE |
832 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
833 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200834 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
835 goto exit;
836 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
837 goto exit;
838 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
839 goto exit;
840 /* Require d to be at least half the size of n. */
841 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
842 goto exit;
843 /* Require p and q to be at most half the size of n, rounded up. */
844 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
845 goto exit;
846 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
847 goto exit;
848 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
849 goto exit;
850 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
851 goto exit;
852 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
853 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100854 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100855 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200856 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200857#endif /* MBEDTLS_RSA_C */
858
859#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200860 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200861 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100862 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100863 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100864 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200865 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200866#endif /* MBEDTLS_ECP_C */
867
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200868 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
869 {
870 uint8_t *p = exported;
871 uint8_t *end = exported + exported_length;
872 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200873#if defined(MBEDTLS_RSA_C)
874 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
875 {
876 /* RSAPublicKey ::= SEQUENCE {
877 * modulus INTEGER, -- n
878 * publicExponent INTEGER } -- e
879 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100880 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
881 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100882 MBEDTLS_ASN1_CONSTRUCTED ),
883 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100884 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200885 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
886 goto exit;
887 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
888 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100889 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200890 }
891 else
892#endif /* MBEDTLS_RSA_C */
893#if defined(MBEDTLS_ECP_C)
894 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
895 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000896 /* The representation of an ECC public key is:
897 * - The byte 0x04;
898 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
899 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
900 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000901 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100902 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
903 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200904 }
905 else
906#endif /* MBEDTLS_ECP_C */
907 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100908 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200909 mbedtls_snprintf( message, sizeof( message ),
910 "No sanity check for public key type=0x%08lx",
911 (unsigned long) type );
912 test_fail( message, __LINE__, __FILE__ );
913 return( 0 );
914 }
915 }
916 else
917
918 {
919 /* No sanity checks for other types */
920 }
921
922 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200923
924exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200925 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200926}
927
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100928static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200929 psa_key_usage_t usage )
930{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200931 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200932 uint8_t *exported = NULL;
933 size_t exported_size = 0;
934 size_t exported_length = 0;
935 int ok = 0;
936
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200937 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200938
939 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200940 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200941 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100942 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
943 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200944 ok = 1;
945 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200946 }
947
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200948 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
949 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200950 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200951
Gilles Peskine8817f612018-12-18 00:18:46 +0100952 PSA_ASSERT( psa_export_key( handle,
953 exported, exported_size,
954 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200955 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
956 psa_get_key_bits( &attributes ),
957 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200958
959exit:
960 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200961 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200962 return( ok );
963}
964
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100965static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200966{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200968 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200969 uint8_t *exported = NULL;
970 size_t exported_size = 0;
971 size_t exported_length = 0;
972 int ok = 0;
973
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200974 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
975 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200976 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100977 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100978 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200979 return( 1 );
980 }
981
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200982 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200983 psa_get_key_type( &attributes ) );
984 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
985 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200986 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200987
Gilles Peskine8817f612018-12-18 00:18:46 +0100988 PSA_ASSERT( psa_export_public_key( handle,
989 exported, exported_size,
990 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200991 ok = exported_key_sanity_check( public_type,
992 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200993 exported, exported_length );
994
995exit:
996 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200997 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200998 return( ok );
999}
1000
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001001/** Do smoke tests on a key.
1002 *
1003 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1004 * sign/verify, or derivation) that is permitted according to \p usage.
1005 * \p usage and \p alg should correspond to the expected policy on the
1006 * key.
1007 *
1008 * Export the key if permitted by \p usage, and check that the output
1009 * looks sensible. If \p usage forbids export, check that
1010 * \p psa_export_key correctly rejects the attempt. If the key is
1011 * asymmetric, also check \p psa_export_public_key.
1012 *
1013 * If the key fails the tests, this function calls the test framework's
1014 * `test_fail` function and returns false. Otherwise this function returns
1015 * true. Therefore it should be used as follows:
1016 * ```
1017 * if( ! exercise_key( ... ) ) goto exit;
1018 * ```
1019 *
1020 * \param handle The key to exercise. It should be capable of performing
1021 * \p alg.
1022 * \param usage The usage flags to assume.
1023 * \param alg The algorithm to exercise.
1024 *
1025 * \retval 0 The key failed the smoke tests.
1026 * \retval 1 The key passed the smoke tests.
1027 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001029 psa_key_usage_t usage,
1030 psa_algorithm_t alg )
1031{
1032 int ok;
1033 if( alg == 0 )
1034 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1035 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001036 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001037 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001038 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001039 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001040 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001041 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001042 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001043 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001044 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001045 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001046 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001047 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1048 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001049 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001050 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001051 else
1052 {
1053 char message[40];
1054 mbedtls_snprintf( message, sizeof( message ),
1055 "No code to exercise alg=0x%08lx",
1056 (unsigned long) alg );
1057 test_fail( message, __LINE__, __FILE__ );
1058 ok = 0;
1059 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001060
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001061 ok = ok && exercise_export_key( handle, usage );
1062 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001063
Gilles Peskine02b75072018-07-01 22:31:34 +02001064 return( ok );
1065}
1066
Gilles Peskine10df3412018-10-25 22:35:43 +02001067static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1068 psa_algorithm_t alg )
1069{
1070 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1071 {
1072 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1073 PSA_KEY_USAGE_VERIFY :
1074 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1075 }
1076 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1077 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1078 {
1079 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1080 PSA_KEY_USAGE_ENCRYPT :
1081 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1082 }
1083 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1084 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1085 {
1086 return( PSA_KEY_USAGE_DERIVE );
1087 }
1088 else
1089 {
1090 return( 0 );
1091 }
1092
1093}
Darryl Green0c6575a2018-11-07 16:05:30 +00001094
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001095static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1096{
1097 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1098 uint8_t buffer[1];
1099 size_t length;
1100 int ok = 0;
1101
Gilles Peskinec87af662019-05-15 16:12:22 +02001102 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001103 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1104 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1105 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1106 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1107 PSA_ERROR_INVALID_HANDLE );
1108 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001109 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001110 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1111 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1112 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1113 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1114
1115 TEST_EQUAL( psa_export_key( handle,
1116 buffer, sizeof( buffer ), &length ),
1117 PSA_ERROR_INVALID_HANDLE );
1118 TEST_EQUAL( psa_export_public_key( handle,
1119 buffer, sizeof( buffer ), &length ),
1120 PSA_ERROR_INVALID_HANDLE );
1121
1122 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1123 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1124
1125 ok = 1;
1126
1127exit:
1128 psa_reset_key_attributes( &attributes );
1129 return( ok );
1130}
1131
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001132/* An overapproximation of the amount of storage needed for a key of the
1133 * given type and with the given content. The API doesn't make it easy
1134 * to find a good value for the size. The current implementation doesn't
1135 * care about the value anyway. */
1136#define KEY_BITS_FROM_DATA( type, data ) \
1137 ( data )->len
1138
Darryl Green0c6575a2018-11-07 16:05:30 +00001139typedef enum {
1140 IMPORT_KEY = 0,
1141 GENERATE_KEY = 1,
1142 DERIVE_KEY = 2
1143} generate_method;
1144
Gilles Peskinee59236f2018-01-27 23:32:46 +01001145/* END_HEADER */
1146
1147/* BEGIN_DEPENDENCIES
1148 * depends_on:MBEDTLS_PSA_CRYPTO_C
1149 * END_DEPENDENCIES
1150 */
1151
1152/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001153void static_checks( )
1154{
1155 size_t max_truncated_mac_size =
1156 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1157
1158 /* Check that the length for a truncated MAC always fits in the algorithm
1159 * encoding. The shifted mask is the maximum truncated value. The
1160 * untruncated algorithm may be one byte larger. */
1161 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1162}
1163/* END_CASE */
1164
1165/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001166void attributes_set_get( int id_arg, int lifetime_arg,
1167 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001168 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001169{
Gilles Peskine4747d192019-04-17 15:05:45 +02001170 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001171 psa_key_id_t id = id_arg;
1172 psa_key_lifetime_t lifetime = lifetime_arg;
1173 psa_key_usage_t usage_flags = usage_flags_arg;
1174 psa_algorithm_t alg = alg_arg;
1175 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001176 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001177
1178 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1179 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1182 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001183 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001184
Gilles Peskinec87af662019-05-15 16:12:22 +02001185 psa_set_key_id( &attributes, id );
1186 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001187 psa_set_key_usage_flags( &attributes, usage_flags );
1188 psa_set_key_algorithm( &attributes, alg );
1189 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001190 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001191
1192 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1193 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1194 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1195 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1196 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001197 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001198
1199 psa_reset_key_attributes( &attributes );
1200
1201 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1202 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1203 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1204 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1205 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001206 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001207}
1208/* END_CASE */
1209
1210/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001211void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1212 int expected_id_arg, int expected_lifetime_arg )
1213{
1214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1215 psa_key_id_t id1 = id1_arg;
1216 psa_key_lifetime_t lifetime = lifetime_arg;
1217 psa_key_id_t id2 = id2_arg;
1218 psa_key_id_t expected_id = expected_id_arg;
1219 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1220
1221 if( id1_arg != -1 )
1222 psa_set_key_id( &attributes, id1 );
1223 if( lifetime_arg != -1 )
1224 psa_set_key_lifetime( &attributes, lifetime );
1225 if( id2_arg != -1 )
1226 psa_set_key_id( &attributes, id2 );
1227
1228 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1229 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1230}
1231/* END_CASE */
1232
1233/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001234void import( data_t *data, int type_arg,
1235 int attr_bits_arg,
1236 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001237{
1238 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1239 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001240 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001241 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001242 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001243 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001244 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001245
Gilles Peskine8817f612018-12-18 00:18:46 +01001246 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001247
Gilles Peskine4747d192019-04-17 15:05:45 +02001248 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001249 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001250 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001251 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001252 if( status != PSA_SUCCESS )
1253 goto exit;
1254
1255 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1256 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001257 if( attr_bits != 0 )
1258 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001259
1260 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001261 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001262
1263exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001264 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001265 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001266 mbedtls_psa_crypto_free( );
1267}
1268/* END_CASE */
1269
1270/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001271void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1272{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001273 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001274 size_t bits = bits_arg;
1275 psa_status_t expected_status = expected_status_arg;
1276 psa_status_t status;
1277 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001278 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001279 size_t buffer_size = /* Slight overapproximations */
1280 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001281 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001282 unsigned char *p;
1283 int ret;
1284 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001285 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001286
Gilles Peskine8817f612018-12-18 00:18:46 +01001287 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001288 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001289
1290 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1291 bits, keypair ) ) >= 0 );
1292 length = ret;
1293
1294 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001295 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001296 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001297 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001298 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001299 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001300
1301exit:
1302 mbedtls_free( buffer );
1303 mbedtls_psa_crypto_free( );
1304}
1305/* END_CASE */
1306
1307/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001308void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001309 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001310 int usage_arg, int alg_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 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001446 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001447 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 Peskine96f0b3b2019-05-10 19:33:38 +02001916void key_policy_alg2( int key_type_arg, data_t *key_data,
1917 int usage_arg, int alg_arg, int alg2_arg )
1918{
1919 psa_key_handle_t handle = 0;
1920 psa_key_type_t key_type = key_type_arg;
1921 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1922 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1923 psa_key_usage_t usage = usage_arg;
1924 psa_algorithm_t alg = alg_arg;
1925 psa_algorithm_t alg2 = alg2_arg;
1926
1927 PSA_ASSERT( psa_crypto_init( ) );
1928
1929 psa_set_key_usage_flags( &attributes, usage );
1930 psa_set_key_algorithm( &attributes, alg );
1931 psa_set_key_enrollment_algorithm( &attributes, alg2 );
1932 psa_set_key_type( &attributes, key_type );
1933 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1934 &handle ) );
1935
1936 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1937 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1938 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
1939 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
1940
1941 if( ! exercise_key( handle, usage, alg ) )
1942 goto exit;
1943 if( ! exercise_key( handle, usage, alg2 ) )
1944 goto exit;
1945
1946exit:
1947 psa_destroy_key( handle );
1948 mbedtls_psa_crypto_free( );
1949}
1950/* END_CASE */
1951
1952/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001953void raw_agreement_key_policy( int policy_usage,
1954 int policy_alg,
1955 int key_type_arg,
1956 data_t *key_data,
1957 int exercise_alg )
1958{
1959 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001960 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001961 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001962 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001963 psa_status_t status;
1964
1965 PSA_ASSERT( psa_crypto_init( ) );
1966
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001967 psa_set_key_usage_flags( &attributes, policy_usage );
1968 psa_set_key_algorithm( &attributes, policy_alg );
1969 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001970
Gilles Peskine049c7532019-05-15 20:22:09 +02001971 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1972 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001973
1974 status = raw_key_agreement_with_self( exercise_alg, handle );
1975
1976 if( policy_alg == exercise_alg &&
1977 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1978 PSA_ASSERT( status );
1979 else
1980 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1981
1982exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001983 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001984 psa_destroy_key( handle );
1985 mbedtls_psa_crypto_free( );
1986}
1987/* END_CASE */
1988
1989/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001990void copy_success( int source_usage_arg,
1991 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02001992 int type_arg, data_t *material,
1993 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02001994 int target_usage_arg,
1995 int target_alg_arg, int target_alg2_arg,
1996 int expected_usage_arg,
1997 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001998{
Gilles Peskineca25db92019-04-19 11:43:08 +02001999 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2000 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002001 psa_key_usage_t expected_usage = expected_usage_arg;
2002 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002003 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002004 psa_key_handle_t source_handle = 0;
2005 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002006 uint8_t *export_buffer = NULL;
2007
Gilles Peskine57ab7212019-01-28 13:03:09 +01002008 PSA_ASSERT( psa_crypto_init( ) );
2009
Gilles Peskineca25db92019-04-19 11:43:08 +02002010 /* Prepare the source key. */
2011 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2012 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002013 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002014 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002015 PSA_ASSERT( psa_import_key( &source_attributes,
2016 material->x, material->len,
2017 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002018 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002019
Gilles Peskineca25db92019-04-19 11:43:08 +02002020 /* Prepare the target attributes. */
2021 if( copy_attributes )
2022 target_attributes = source_attributes;
2023 if( target_usage_arg != -1 )
2024 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2025 if( target_alg_arg != -1 )
2026 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002027 if( target_alg2_arg != -1 )
2028 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002029
2030 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002031 PSA_ASSERT( psa_copy_key( source_handle,
2032 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002033
2034 /* Destroy the source to ensure that this doesn't affect the target. */
2035 PSA_ASSERT( psa_destroy_key( source_handle ) );
2036
2037 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002038 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2039 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2040 psa_get_key_type( &target_attributes ) );
2041 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2042 psa_get_key_bits( &target_attributes ) );
2043 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2044 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002045 TEST_EQUAL( expected_alg2,
2046 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002047 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2048 {
2049 size_t length;
2050 ASSERT_ALLOC( export_buffer, material->len );
2051 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2052 material->len, &length ) );
2053 ASSERT_COMPARE( material->x, material->len,
2054 export_buffer, length );
2055 }
2056 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2057 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002058 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2059 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002060
2061 PSA_ASSERT( psa_close_key( target_handle ) );
2062
2063exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002064 psa_reset_key_attributes( &source_attributes );
2065 psa_reset_key_attributes( &target_attributes );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002066 mbedtls_psa_crypto_free( );
2067 mbedtls_free( export_buffer );
2068}
2069/* END_CASE */
2070
2071/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002072void copy_fail( int source_usage_arg,
2073 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002074 int type_arg, data_t *material,
2075 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002076 int target_usage_arg,
2077 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002078 int expected_status_arg )
2079{
2080 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2081 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2082 psa_key_handle_t source_handle = 0;
2083 psa_key_handle_t target_handle = 0;
2084
2085 PSA_ASSERT( psa_crypto_init( ) );
2086
2087 /* Prepare the source key. */
2088 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2089 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002090 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002091 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002092 PSA_ASSERT( psa_import_key( &source_attributes,
2093 material->x, material->len,
2094 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002095
2096 /* Prepare the target attributes. */
2097 psa_set_key_type( &target_attributes, target_type_arg );
2098 psa_set_key_bits( &target_attributes, target_bits_arg );
2099 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2100 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002101 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002102
2103 /* Try to copy the key. */
2104 TEST_EQUAL( psa_copy_key( source_handle,
2105 &target_attributes, &target_handle ),
2106 expected_status_arg );
2107exit:
2108 psa_reset_key_attributes( &source_attributes );
2109 psa_reset_key_attributes( &target_attributes );
2110 mbedtls_psa_crypto_free( );
2111}
2112/* END_CASE */
2113
2114/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002115void hash_operation_init( )
2116{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002117 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002118 /* Test each valid way of initializing the object, except for `= {0}`, as
2119 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2120 * though it's OK by the C standard. We could test for this, but we'd need
2121 * to supress the Clang warning for the test. */
2122 psa_hash_operation_t func = psa_hash_operation_init( );
2123 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2124 psa_hash_operation_t zero;
2125
2126 memset( &zero, 0, sizeof( zero ) );
2127
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002128 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002129 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2130 PSA_ERROR_BAD_STATE );
2131 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2132 PSA_ERROR_BAD_STATE );
2133 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2134 PSA_ERROR_BAD_STATE );
2135
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002136 /* A default hash operation should be abortable without error. */
2137 PSA_ASSERT( psa_hash_abort( &func ) );
2138 PSA_ASSERT( psa_hash_abort( &init ) );
2139 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002140}
2141/* END_CASE */
2142
2143/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002144void hash_setup( int alg_arg,
2145 int expected_status_arg )
2146{
2147 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002148 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002149 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002150 psa_status_t status;
2151
Gilles Peskine8817f612018-12-18 00:18:46 +01002152 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002153
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002154 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002155 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002156
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002157 /* Whether setup succeeded or failed, abort must succeed. */
2158 PSA_ASSERT( psa_hash_abort( &operation ) );
2159
2160 /* If setup failed, reproduce the failure, so as to
2161 * test the resulting state of the operation object. */
2162 if( status != PSA_SUCCESS )
2163 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2164
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002165 /* Now the operation object should be reusable. */
2166#if defined(KNOWN_SUPPORTED_HASH_ALG)
2167 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2168 PSA_ASSERT( psa_hash_abort( &operation ) );
2169#endif
2170
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002171exit:
2172 mbedtls_psa_crypto_free( );
2173}
2174/* END_CASE */
2175
2176/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002177void hash_bad_order( )
2178{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002179 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002180 unsigned char input[] = "";
2181 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002182 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002183 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2184 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2185 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002186 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002187 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002188 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002189
Gilles Peskine8817f612018-12-18 00:18:46 +01002190 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002191
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002192 /* Call setup twice in a row. */
2193 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2194 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2195 PSA_ERROR_BAD_STATE );
2196 PSA_ASSERT( psa_hash_abort( &operation ) );
2197
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002198 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002199 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002200 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002201 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002202
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002203 /* Call update after finish. */
2204 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2205 PSA_ASSERT( psa_hash_finish( &operation,
2206 hash, sizeof( hash ), &hash_len ) );
2207 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002208 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002209 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002210
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002211 /* Call verify without calling setup beforehand. */
2212 TEST_EQUAL( psa_hash_verify( &operation,
2213 valid_hash, sizeof( valid_hash ) ),
2214 PSA_ERROR_BAD_STATE );
2215 PSA_ASSERT( psa_hash_abort( &operation ) );
2216
2217 /* Call verify after finish. */
2218 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2219 PSA_ASSERT( psa_hash_finish( &operation,
2220 hash, sizeof( hash ), &hash_len ) );
2221 TEST_EQUAL( psa_hash_verify( &operation,
2222 valid_hash, sizeof( valid_hash ) ),
2223 PSA_ERROR_BAD_STATE );
2224 PSA_ASSERT( psa_hash_abort( &operation ) );
2225
2226 /* Call verify twice in a row. */
2227 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2228 PSA_ASSERT( psa_hash_verify( &operation,
2229 valid_hash, sizeof( valid_hash ) ) );
2230 TEST_EQUAL( psa_hash_verify( &operation,
2231 valid_hash, sizeof( valid_hash ) ),
2232 PSA_ERROR_BAD_STATE );
2233 PSA_ASSERT( psa_hash_abort( &operation ) );
2234
2235 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002236 TEST_EQUAL( psa_hash_finish( &operation,
2237 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002238 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002239 PSA_ASSERT( psa_hash_abort( &operation ) );
2240
2241 /* Call finish twice in a row. */
2242 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2243 PSA_ASSERT( psa_hash_finish( &operation,
2244 hash, sizeof( hash ), &hash_len ) );
2245 TEST_EQUAL( psa_hash_finish( &operation,
2246 hash, sizeof( hash ), &hash_len ),
2247 PSA_ERROR_BAD_STATE );
2248 PSA_ASSERT( psa_hash_abort( &operation ) );
2249
2250 /* Call finish after calling verify. */
2251 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2252 PSA_ASSERT( psa_hash_verify( &operation,
2253 valid_hash, sizeof( valid_hash ) ) );
2254 TEST_EQUAL( psa_hash_finish( &operation,
2255 hash, sizeof( hash ), &hash_len ),
2256 PSA_ERROR_BAD_STATE );
2257 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002258
2259exit:
2260 mbedtls_psa_crypto_free( );
2261}
2262/* END_CASE */
2263
itayzafrir27e69452018-11-01 14:26:34 +02002264/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2265void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002266{
2267 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002268 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2269 * appended to it */
2270 unsigned char hash[] = {
2271 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2272 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2273 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002274 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002275 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002276
Gilles Peskine8817f612018-12-18 00:18:46 +01002277 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002278
itayzafrir27e69452018-11-01 14:26:34 +02002279 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002280 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002281 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002282 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002283
itayzafrir27e69452018-11-01 14:26:34 +02002284 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002285 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002286 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002287 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002288
itayzafrir27e69452018-11-01 14:26:34 +02002289 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002290 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002291 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002292 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002293
itayzafrirec93d302018-10-18 18:01:10 +03002294exit:
2295 mbedtls_psa_crypto_free( );
2296}
2297/* END_CASE */
2298
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002299/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2300void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002301{
2302 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002303 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002304 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002305 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002306 size_t hash_len;
2307
Gilles Peskine8817f612018-12-18 00:18:46 +01002308 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002309
itayzafrir58028322018-10-25 10:22:01 +03002310 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002311 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002312 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002313 hash, expected_size - 1, &hash_len ),
2314 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002315
2316exit:
2317 mbedtls_psa_crypto_free( );
2318}
2319/* END_CASE */
2320
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002321/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2322void hash_clone_source_state( )
2323{
2324 psa_algorithm_t alg = PSA_ALG_SHA_256;
2325 unsigned char hash[PSA_HASH_MAX_SIZE];
2326 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2327 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2328 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2329 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2330 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2331 size_t hash_len;
2332
2333 PSA_ASSERT( psa_crypto_init( ) );
2334 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2335
2336 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2337 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2338 PSA_ASSERT( psa_hash_finish( &op_finished,
2339 hash, sizeof( hash ), &hash_len ) );
2340 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2341 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2342
2343 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2344 PSA_ERROR_BAD_STATE );
2345
2346 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2347 PSA_ASSERT( psa_hash_finish( &op_init,
2348 hash, sizeof( hash ), &hash_len ) );
2349 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2350 PSA_ASSERT( psa_hash_finish( &op_finished,
2351 hash, sizeof( hash ), &hash_len ) );
2352 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2353 PSA_ASSERT( psa_hash_finish( &op_aborted,
2354 hash, sizeof( hash ), &hash_len ) );
2355
2356exit:
2357 psa_hash_abort( &op_source );
2358 psa_hash_abort( &op_init );
2359 psa_hash_abort( &op_setup );
2360 psa_hash_abort( &op_finished );
2361 psa_hash_abort( &op_aborted );
2362 mbedtls_psa_crypto_free( );
2363}
2364/* END_CASE */
2365
2366/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2367void hash_clone_target_state( )
2368{
2369 psa_algorithm_t alg = PSA_ALG_SHA_256;
2370 unsigned char hash[PSA_HASH_MAX_SIZE];
2371 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2372 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2373 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2374 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2375 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2376 size_t hash_len;
2377
2378 PSA_ASSERT( psa_crypto_init( ) );
2379
2380 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2381 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2382 PSA_ASSERT( psa_hash_finish( &op_finished,
2383 hash, sizeof( hash ), &hash_len ) );
2384 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2385 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2386
2387 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2388 PSA_ASSERT( psa_hash_finish( &op_target,
2389 hash, sizeof( hash ), &hash_len ) );
2390
2391 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2392 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2393 PSA_ERROR_BAD_STATE );
2394 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2395 PSA_ERROR_BAD_STATE );
2396
2397exit:
2398 psa_hash_abort( &op_target );
2399 psa_hash_abort( &op_init );
2400 psa_hash_abort( &op_setup );
2401 psa_hash_abort( &op_finished );
2402 psa_hash_abort( &op_aborted );
2403 mbedtls_psa_crypto_free( );
2404}
2405/* END_CASE */
2406
itayzafrir58028322018-10-25 10:22:01 +03002407/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002408void mac_operation_init( )
2409{
Jaeden Amero252ef282019-02-15 14:05:35 +00002410 const uint8_t input[1] = { 0 };
2411
Jaeden Amero769ce272019-01-04 11:48:03 +00002412 /* Test each valid way of initializing the object, except for `= {0}`, as
2413 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2414 * though it's OK by the C standard. We could test for this, but we'd need
2415 * to supress the Clang warning for the test. */
2416 psa_mac_operation_t func = psa_mac_operation_init( );
2417 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2418 psa_mac_operation_t zero;
2419
2420 memset( &zero, 0, sizeof( zero ) );
2421
Jaeden Amero252ef282019-02-15 14:05:35 +00002422 /* A freshly-initialized MAC operation should not be usable. */
2423 TEST_EQUAL( psa_mac_update( &func,
2424 input, sizeof( input ) ),
2425 PSA_ERROR_BAD_STATE );
2426 TEST_EQUAL( psa_mac_update( &init,
2427 input, sizeof( input ) ),
2428 PSA_ERROR_BAD_STATE );
2429 TEST_EQUAL( psa_mac_update( &zero,
2430 input, sizeof( input ) ),
2431 PSA_ERROR_BAD_STATE );
2432
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002433 /* A default MAC operation should be abortable without error. */
2434 PSA_ASSERT( psa_mac_abort( &func ) );
2435 PSA_ASSERT( psa_mac_abort( &init ) );
2436 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002437}
2438/* END_CASE */
2439
2440/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002441void mac_setup( int key_type_arg,
2442 data_t *key,
2443 int alg_arg,
2444 int expected_status_arg )
2445{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002446 psa_key_type_t key_type = key_type_arg;
2447 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002448 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002449 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002450 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2451#if defined(KNOWN_SUPPORTED_MAC_ALG)
2452 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2453#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002454
Gilles Peskine8817f612018-12-18 00:18:46 +01002455 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002456
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002457 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2458 &operation, &status ) )
2459 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002460 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002461
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002462 /* The operation object should be reusable. */
2463#if defined(KNOWN_SUPPORTED_MAC_ALG)
2464 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2465 smoke_test_key_data,
2466 sizeof( smoke_test_key_data ),
2467 KNOWN_SUPPORTED_MAC_ALG,
2468 &operation, &status ) )
2469 goto exit;
2470 TEST_EQUAL( status, PSA_SUCCESS );
2471#endif
2472
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002473exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002474 mbedtls_psa_crypto_free( );
2475}
2476/* END_CASE */
2477
2478/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002479void mac_bad_order( )
2480{
2481 psa_key_handle_t handle = 0;
2482 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2483 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2484 const uint8_t key[] = {
2485 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2486 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2487 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002488 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002489 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2490 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2491 size_t sign_mac_length = 0;
2492 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2493 const uint8_t verify_mac[] = {
2494 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2495 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2496 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2497
2498 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002499 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2500 psa_set_key_algorithm( &attributes, alg );
2501 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002502
Gilles Peskine73676cb2019-05-15 20:15:10 +02002503 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002504
Jaeden Amero252ef282019-02-15 14:05:35 +00002505 /* Call update without calling setup beforehand. */
2506 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2507 PSA_ERROR_BAD_STATE );
2508 PSA_ASSERT( psa_mac_abort( &operation ) );
2509
2510 /* Call sign finish without calling setup beforehand. */
2511 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2512 &sign_mac_length),
2513 PSA_ERROR_BAD_STATE );
2514 PSA_ASSERT( psa_mac_abort( &operation ) );
2515
2516 /* Call verify finish without calling setup beforehand. */
2517 TEST_EQUAL( psa_mac_verify_finish( &operation,
2518 verify_mac, sizeof( verify_mac ) ),
2519 PSA_ERROR_BAD_STATE );
2520 PSA_ASSERT( psa_mac_abort( &operation ) );
2521
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002522 /* Call setup twice in a row. */
2523 PSA_ASSERT( psa_mac_sign_setup( &operation,
2524 handle, alg ) );
2525 TEST_EQUAL( psa_mac_sign_setup( &operation,
2526 handle, alg ),
2527 PSA_ERROR_BAD_STATE );
2528 PSA_ASSERT( psa_mac_abort( &operation ) );
2529
Jaeden Amero252ef282019-02-15 14:05:35 +00002530 /* Call update after sign finish. */
2531 PSA_ASSERT( psa_mac_sign_setup( &operation,
2532 handle, alg ) );
2533 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2534 PSA_ASSERT( psa_mac_sign_finish( &operation,
2535 sign_mac, sizeof( sign_mac ),
2536 &sign_mac_length ) );
2537 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2538 PSA_ERROR_BAD_STATE );
2539 PSA_ASSERT( psa_mac_abort( &operation ) );
2540
2541 /* Call update after verify finish. */
2542 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002543 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002544 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2545 PSA_ASSERT( psa_mac_verify_finish( &operation,
2546 verify_mac, sizeof( verify_mac ) ) );
2547 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2548 PSA_ERROR_BAD_STATE );
2549 PSA_ASSERT( psa_mac_abort( &operation ) );
2550
2551 /* Call sign finish twice in a row. */
2552 PSA_ASSERT( psa_mac_sign_setup( &operation,
2553 handle, alg ) );
2554 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2555 PSA_ASSERT( psa_mac_sign_finish( &operation,
2556 sign_mac, sizeof( sign_mac ),
2557 &sign_mac_length ) );
2558 TEST_EQUAL( psa_mac_sign_finish( &operation,
2559 sign_mac, sizeof( sign_mac ),
2560 &sign_mac_length ),
2561 PSA_ERROR_BAD_STATE );
2562 PSA_ASSERT( psa_mac_abort( &operation ) );
2563
2564 /* Call verify finish twice in a row. */
2565 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002566 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002567 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2568 PSA_ASSERT( psa_mac_verify_finish( &operation,
2569 verify_mac, sizeof( verify_mac ) ) );
2570 TEST_EQUAL( psa_mac_verify_finish( &operation,
2571 verify_mac, sizeof( verify_mac ) ),
2572 PSA_ERROR_BAD_STATE );
2573 PSA_ASSERT( psa_mac_abort( &operation ) );
2574
2575 /* Setup sign but try verify. */
2576 PSA_ASSERT( psa_mac_sign_setup( &operation,
2577 handle, alg ) );
2578 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2579 TEST_EQUAL( psa_mac_verify_finish( &operation,
2580 verify_mac, sizeof( verify_mac ) ),
2581 PSA_ERROR_BAD_STATE );
2582 PSA_ASSERT( psa_mac_abort( &operation ) );
2583
2584 /* Setup verify but try sign. */
2585 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002586 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002587 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2588 TEST_EQUAL( psa_mac_sign_finish( &operation,
2589 sign_mac, sizeof( sign_mac ),
2590 &sign_mac_length ),
2591 PSA_ERROR_BAD_STATE );
2592 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002593
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002594exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002595 mbedtls_psa_crypto_free( );
2596}
2597/* END_CASE */
2598
2599/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002600void mac_sign( int key_type_arg,
2601 data_t *key,
2602 int alg_arg,
2603 data_t *input,
2604 data_t *expected_mac )
2605{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002606 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002607 psa_key_type_t key_type = key_type_arg;
2608 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002609 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002610 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002611 /* Leave a little extra room in the output buffer. At the end of the
2612 * test, we'll check that the implementation didn't overwrite onto
2613 * this extra room. */
2614 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2615 size_t mac_buffer_size =
2616 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2617 size_t mac_length = 0;
2618
2619 memset( actual_mac, '+', sizeof( actual_mac ) );
2620 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2621 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2622
Gilles Peskine8817f612018-12-18 00:18:46 +01002623 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002624
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002625 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2626 psa_set_key_algorithm( &attributes, alg );
2627 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002628
Gilles Peskine73676cb2019-05-15 20:15:10 +02002629 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002630
2631 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002632 PSA_ASSERT( psa_mac_sign_setup( &operation,
2633 handle, alg ) );
2634 PSA_ASSERT( psa_mac_update( &operation,
2635 input->x, input->len ) );
2636 PSA_ASSERT( psa_mac_sign_finish( &operation,
2637 actual_mac, mac_buffer_size,
2638 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002639
2640 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002641 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2642 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002643
2644 /* Verify that the end of the buffer is untouched. */
2645 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2646 sizeof( actual_mac ) - mac_length ) );
2647
2648exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002649 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002650 mbedtls_psa_crypto_free( );
2651}
2652/* END_CASE */
2653
2654/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002655void mac_verify( int key_type_arg,
2656 data_t *key,
2657 int alg_arg,
2658 data_t *input,
2659 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002660{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002661 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002662 psa_key_type_t key_type = key_type_arg;
2663 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002664 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002665 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002666
Gilles Peskine69c12672018-06-28 00:07:19 +02002667 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2668
Gilles Peskine8817f612018-12-18 00:18:46 +01002669 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002670
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002671 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2672 psa_set_key_algorithm( &attributes, alg );
2673 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002674
Gilles Peskine73676cb2019-05-15 20:15:10 +02002675 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002676
Gilles Peskine8817f612018-12-18 00:18:46 +01002677 PSA_ASSERT( psa_mac_verify_setup( &operation,
2678 handle, alg ) );
2679 PSA_ASSERT( psa_destroy_key( handle ) );
2680 PSA_ASSERT( psa_mac_update( &operation,
2681 input->x, input->len ) );
2682 PSA_ASSERT( psa_mac_verify_finish( &operation,
2683 expected_mac->x,
2684 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002685
2686exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002687 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002688 mbedtls_psa_crypto_free( );
2689}
2690/* END_CASE */
2691
2692/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002693void cipher_operation_init( )
2694{
Jaeden Ameroab439972019-02-15 14:12:05 +00002695 const uint8_t input[1] = { 0 };
2696 unsigned char output[1] = { 0 };
2697 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002698 /* Test each valid way of initializing the object, except for `= {0}`, as
2699 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2700 * though it's OK by the C standard. We could test for this, but we'd need
2701 * to supress the Clang warning for the test. */
2702 psa_cipher_operation_t func = psa_cipher_operation_init( );
2703 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2704 psa_cipher_operation_t zero;
2705
2706 memset( &zero, 0, sizeof( zero ) );
2707
Jaeden Ameroab439972019-02-15 14:12:05 +00002708 /* A freshly-initialized cipher operation should not be usable. */
2709 TEST_EQUAL( psa_cipher_update( &func,
2710 input, sizeof( input ),
2711 output, sizeof( output ),
2712 &output_length ),
2713 PSA_ERROR_BAD_STATE );
2714 TEST_EQUAL( psa_cipher_update( &init,
2715 input, sizeof( input ),
2716 output, sizeof( output ),
2717 &output_length ),
2718 PSA_ERROR_BAD_STATE );
2719 TEST_EQUAL( psa_cipher_update( &zero,
2720 input, sizeof( input ),
2721 output, sizeof( output ),
2722 &output_length ),
2723 PSA_ERROR_BAD_STATE );
2724
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002725 /* A default cipher operation should be abortable without error. */
2726 PSA_ASSERT( psa_cipher_abort( &func ) );
2727 PSA_ASSERT( psa_cipher_abort( &init ) );
2728 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002729}
2730/* END_CASE */
2731
2732/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002733void cipher_setup( int key_type_arg,
2734 data_t *key,
2735 int alg_arg,
2736 int expected_status_arg )
2737{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002738 psa_key_type_t key_type = key_type_arg;
2739 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002740 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002741 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002742 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002743#if defined(KNOWN_SUPPORTED_MAC_ALG)
2744 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2745#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002746
Gilles Peskine8817f612018-12-18 00:18:46 +01002747 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002748
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002749 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2750 &operation, &status ) )
2751 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002752 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002753
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002754 /* The operation object should be reusable. */
2755#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2756 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2757 smoke_test_key_data,
2758 sizeof( smoke_test_key_data ),
2759 KNOWN_SUPPORTED_CIPHER_ALG,
2760 &operation, &status ) )
2761 goto exit;
2762 TEST_EQUAL( status, PSA_SUCCESS );
2763#endif
2764
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002765exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002766 mbedtls_psa_crypto_free( );
2767}
2768/* END_CASE */
2769
2770/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002771void cipher_bad_order( )
2772{
2773 psa_key_handle_t handle = 0;
2774 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2775 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002776 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002777 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2778 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2779 const uint8_t key[] = {
2780 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2781 0xaa, 0xaa, 0xaa, 0xaa };
2782 const uint8_t text[] = {
2783 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2784 0xbb, 0xbb, 0xbb, 0xbb };
2785 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2786 size_t length = 0;
2787
2788 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002789 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2790 psa_set_key_algorithm( &attributes, alg );
2791 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002792 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002793
2794
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002795 /* Call encrypt setup twice in a row. */
2796 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2797 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2798 PSA_ERROR_BAD_STATE );
2799 PSA_ASSERT( psa_cipher_abort( &operation ) );
2800
2801 /* Call decrypt setup twice in a row. */
2802 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2803 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2804 PSA_ERROR_BAD_STATE );
2805 PSA_ASSERT( psa_cipher_abort( &operation ) );
2806
Jaeden Ameroab439972019-02-15 14:12:05 +00002807 /* Generate an IV without calling setup beforehand. */
2808 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2809 buffer, sizeof( buffer ),
2810 &length ),
2811 PSA_ERROR_BAD_STATE );
2812 PSA_ASSERT( psa_cipher_abort( &operation ) );
2813
2814 /* Generate an IV twice in a row. */
2815 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2816 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2817 buffer, sizeof( buffer ),
2818 &length ) );
2819 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2820 buffer, sizeof( buffer ),
2821 &length ),
2822 PSA_ERROR_BAD_STATE );
2823 PSA_ASSERT( psa_cipher_abort( &operation ) );
2824
2825 /* Generate an IV after it's already set. */
2826 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2827 PSA_ASSERT( psa_cipher_set_iv( &operation,
2828 iv, sizeof( iv ) ) );
2829 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2830 buffer, sizeof( buffer ),
2831 &length ),
2832 PSA_ERROR_BAD_STATE );
2833 PSA_ASSERT( psa_cipher_abort( &operation ) );
2834
2835 /* Set an IV without calling setup beforehand. */
2836 TEST_EQUAL( psa_cipher_set_iv( &operation,
2837 iv, sizeof( iv ) ),
2838 PSA_ERROR_BAD_STATE );
2839 PSA_ASSERT( psa_cipher_abort( &operation ) );
2840
2841 /* Set an IV after it's already set. */
2842 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2843 PSA_ASSERT( psa_cipher_set_iv( &operation,
2844 iv, sizeof( iv ) ) );
2845 TEST_EQUAL( psa_cipher_set_iv( &operation,
2846 iv, sizeof( iv ) ),
2847 PSA_ERROR_BAD_STATE );
2848 PSA_ASSERT( psa_cipher_abort( &operation ) );
2849
2850 /* Set an IV after it's already generated. */
2851 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2852 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2853 buffer, sizeof( buffer ),
2854 &length ) );
2855 TEST_EQUAL( psa_cipher_set_iv( &operation,
2856 iv, sizeof( iv ) ),
2857 PSA_ERROR_BAD_STATE );
2858 PSA_ASSERT( psa_cipher_abort( &operation ) );
2859
2860 /* Call update without calling setup beforehand. */
2861 TEST_EQUAL( psa_cipher_update( &operation,
2862 text, sizeof( text ),
2863 buffer, sizeof( buffer ),
2864 &length ),
2865 PSA_ERROR_BAD_STATE );
2866 PSA_ASSERT( psa_cipher_abort( &operation ) );
2867
2868 /* Call update without an IV where an IV is required. */
2869 TEST_EQUAL( psa_cipher_update( &operation,
2870 text, sizeof( text ),
2871 buffer, sizeof( buffer ),
2872 &length ),
2873 PSA_ERROR_BAD_STATE );
2874 PSA_ASSERT( psa_cipher_abort( &operation ) );
2875
2876 /* Call update after finish. */
2877 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2878 PSA_ASSERT( psa_cipher_set_iv( &operation,
2879 iv, sizeof( iv ) ) );
2880 PSA_ASSERT( psa_cipher_finish( &operation,
2881 buffer, sizeof( buffer ), &length ) );
2882 TEST_EQUAL( psa_cipher_update( &operation,
2883 text, sizeof( text ),
2884 buffer, sizeof( buffer ),
2885 &length ),
2886 PSA_ERROR_BAD_STATE );
2887 PSA_ASSERT( psa_cipher_abort( &operation ) );
2888
2889 /* Call finish without calling setup beforehand. */
2890 TEST_EQUAL( psa_cipher_finish( &operation,
2891 buffer, sizeof( buffer ), &length ),
2892 PSA_ERROR_BAD_STATE );
2893 PSA_ASSERT( psa_cipher_abort( &operation ) );
2894
2895 /* Call finish without an IV where an IV is required. */
2896 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2897 /* Not calling update means we are encrypting an empty buffer, which is OK
2898 * for cipher modes with padding. */
2899 TEST_EQUAL( psa_cipher_finish( &operation,
2900 buffer, sizeof( buffer ), &length ),
2901 PSA_ERROR_BAD_STATE );
2902 PSA_ASSERT( psa_cipher_abort( &operation ) );
2903
2904 /* Call finish twice in a row. */
2905 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2906 PSA_ASSERT( psa_cipher_set_iv( &operation,
2907 iv, sizeof( iv ) ) );
2908 PSA_ASSERT( psa_cipher_finish( &operation,
2909 buffer, sizeof( buffer ), &length ) );
2910 TEST_EQUAL( psa_cipher_finish( &operation,
2911 buffer, sizeof( buffer ), &length ),
2912 PSA_ERROR_BAD_STATE );
2913 PSA_ASSERT( psa_cipher_abort( &operation ) );
2914
2915exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002916 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002917}
2918/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002919
Gilles Peskine50e586b2018-06-08 14:28:46 +02002920/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002921void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002922 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002923 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002924 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002925{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002926 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002927 psa_status_t status;
2928 psa_key_type_t key_type = key_type_arg;
2929 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002930 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002931 unsigned char *output = NULL;
2932 size_t output_buffer_size = 0;
2933 size_t function_output_length = 0;
2934 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002935 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002936 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002937
Gilles Peskine8817f612018-12-18 00:18:46 +01002938 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002939
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002940 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2941 psa_set_key_algorithm( &attributes, alg );
2942 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002943
Gilles Peskine73676cb2019-05-15 20:15:10 +02002944 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002945
Gilles Peskine8817f612018-12-18 00:18:46 +01002946 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2947 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002948
Gilles Peskine423005e2019-05-06 15:22:57 +02002949 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002950 output_buffer_size = ( (size_t) input->len +
2951 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002952 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002953
Gilles Peskine8817f612018-12-18 00:18:46 +01002954 PSA_ASSERT( psa_cipher_update( &operation,
2955 input->x, input->len,
2956 output, output_buffer_size,
2957 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002958 total_output_length += function_output_length;
2959 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002960 output + total_output_length,
2961 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002962 &function_output_length );
2963 total_output_length += function_output_length;
2964
Gilles Peskinefe11b722018-12-18 00:24:04 +01002965 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002966 if( expected_status == PSA_SUCCESS )
2967 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002968 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002969 ASSERT_COMPARE( expected_output->x, expected_output->len,
2970 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002971 }
2972
2973exit:
2974 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002975 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002976 mbedtls_psa_crypto_free( );
2977}
2978/* END_CASE */
2979
2980/* BEGIN_CASE */
2981void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002982 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002983 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002984 int first_part_size_arg,
2985 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002986 data_t *expected_output )
2987{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002988 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002989 psa_key_type_t key_type = key_type_arg;
2990 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002991 size_t first_part_size = first_part_size_arg;
2992 size_t output1_length = output1_length_arg;
2993 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002994 unsigned char *output = NULL;
2995 size_t output_buffer_size = 0;
2996 size_t function_output_length = 0;
2997 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002998 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002999 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003000
Gilles Peskine8817f612018-12-18 00:18:46 +01003001 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003002
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003003 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3004 psa_set_key_algorithm( &attributes, alg );
3005 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003006
Gilles Peskine73676cb2019-05-15 20:15:10 +02003007 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003008
Gilles Peskine8817f612018-12-18 00:18:46 +01003009 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3010 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003011
Gilles Peskine423005e2019-05-06 15:22:57 +02003012 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003013 output_buffer_size = ( (size_t) input->len +
3014 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003015 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003016
Gilles Peskinee0866522019-02-19 19:44:00 +01003017 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003018 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3019 output, output_buffer_size,
3020 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003021 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003022 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003023 PSA_ASSERT( psa_cipher_update( &operation,
3024 input->x + first_part_size,
3025 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003026 output + total_output_length,
3027 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003028 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003029 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003030 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003031 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003032 output + total_output_length,
3033 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003034 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003035 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003036 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003037
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003038 ASSERT_COMPARE( expected_output->x, expected_output->len,
3039 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003040
3041exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003042 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003043 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003044 mbedtls_psa_crypto_free( );
3045}
3046/* END_CASE */
3047
3048/* BEGIN_CASE */
3049void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003050 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003051 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003052 int first_part_size_arg,
3053 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003054 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003055{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003056 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003057
3058 psa_key_type_t key_type = key_type_arg;
3059 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003060 size_t first_part_size = first_part_size_arg;
3061 size_t output1_length = output1_length_arg;
3062 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003063 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003064 size_t output_buffer_size = 0;
3065 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003066 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003067 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003068 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003069
Gilles Peskine8817f612018-12-18 00:18:46 +01003070 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003071
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003072 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3073 psa_set_key_algorithm( &attributes, alg );
3074 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003075
Gilles Peskine73676cb2019-05-15 20:15:10 +02003076 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003077
Gilles Peskine8817f612018-12-18 00:18:46 +01003078 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3079 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003080
Gilles Peskine423005e2019-05-06 15:22:57 +02003081 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003082
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003083 output_buffer_size = ( (size_t) input->len +
3084 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003085 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086
Gilles Peskinee0866522019-02-19 19:44:00 +01003087 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003088 PSA_ASSERT( psa_cipher_update( &operation,
3089 input->x, first_part_size,
3090 output, output_buffer_size,
3091 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003092 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003093 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003094 PSA_ASSERT( psa_cipher_update( &operation,
3095 input->x + first_part_size,
3096 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003097 output + total_output_length,
3098 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003099 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003100 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003101 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003102 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003103 output + total_output_length,
3104 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003105 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003106 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003107 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003108
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003109 ASSERT_COMPARE( expected_output->x, expected_output->len,
3110 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003111
3112exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003113 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003114 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003115 mbedtls_psa_crypto_free( );
3116}
3117/* END_CASE */
3118
Gilles Peskine50e586b2018-06-08 14:28:46 +02003119/* BEGIN_CASE */
3120void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003121 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003122 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003123 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003124{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003125 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003126 psa_status_t status;
3127 psa_key_type_t key_type = key_type_arg;
3128 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003129 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003130 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003131 size_t output_buffer_size = 0;
3132 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003133 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003134 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003135 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003136
Gilles Peskine8817f612018-12-18 00:18:46 +01003137 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003138
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003139 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3140 psa_set_key_algorithm( &attributes, alg );
3141 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003142
Gilles Peskine73676cb2019-05-15 20:15:10 +02003143 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003144
Gilles Peskine8817f612018-12-18 00:18:46 +01003145 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3146 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003147
Gilles Peskine423005e2019-05-06 15:22:57 +02003148 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003149
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003150 output_buffer_size = ( (size_t) input->len +
3151 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003152 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003153
Gilles Peskine8817f612018-12-18 00:18:46 +01003154 PSA_ASSERT( psa_cipher_update( &operation,
3155 input->x, input->len,
3156 output, output_buffer_size,
3157 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003158 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003159 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003160 output + total_output_length,
3161 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003162 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003163 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003164 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003165
3166 if( expected_status == PSA_SUCCESS )
3167 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003168 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003169 ASSERT_COMPARE( expected_output->x, expected_output->len,
3170 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003171 }
3172
Gilles Peskine50e586b2018-06-08 14:28:46 +02003173exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003174 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003175 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003176 mbedtls_psa_crypto_free( );
3177}
3178/* END_CASE */
3179
Gilles Peskine50e586b2018-06-08 14:28:46 +02003180/* BEGIN_CASE */
3181void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003182 data_t *key,
3183 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003184{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003185 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003186 psa_key_type_t key_type = key_type_arg;
3187 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003188 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003189 size_t iv_size = 16;
3190 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003191 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003192 size_t output1_size = 0;
3193 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003194 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003195 size_t output2_size = 0;
3196 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003197 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003198 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3199 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003200 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003201
Gilles Peskine8817f612018-12-18 00:18:46 +01003202 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003203
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003204 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3205 psa_set_key_algorithm( &attributes, alg );
3206 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003207
Gilles Peskine73676cb2019-05-15 20:15:10 +02003208 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003209
Gilles Peskine8817f612018-12-18 00:18:46 +01003210 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3211 handle, alg ) );
3212 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3213 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003214
Gilles Peskine8817f612018-12-18 00:18:46 +01003215 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3216 iv, iv_size,
3217 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003218 output1_size = ( (size_t) input->len +
3219 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003220 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003221
Gilles Peskine8817f612018-12-18 00:18:46 +01003222 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3223 output1, output1_size,
3224 &output1_length ) );
3225 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003226 output1 + output1_length,
3227 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003228 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003229
Gilles Peskine048b7f02018-06-08 14:20:49 +02003230 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003231
Gilles Peskine8817f612018-12-18 00:18:46 +01003232 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003233
3234 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003235 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003236
Gilles Peskine8817f612018-12-18 00:18:46 +01003237 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3238 iv, iv_length ) );
3239 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3240 output2, output2_size,
3241 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003242 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003243 PSA_ASSERT( psa_cipher_finish( &operation2,
3244 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003245 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003246 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003247
Gilles Peskine048b7f02018-06-08 14:20:49 +02003248 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003249
Gilles Peskine8817f612018-12-18 00:18:46 +01003250 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003251
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003252 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003253
3254exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003255 mbedtls_free( output1 );
3256 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003257 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003258 mbedtls_psa_crypto_free( );
3259}
3260/* END_CASE */
3261
3262/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003263void cipher_verify_output_multipart( int alg_arg,
3264 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003265 data_t *key,
3266 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003267 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003268{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003269 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003270 psa_key_type_t key_type = key_type_arg;
3271 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003272 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003273 unsigned char iv[16] = {0};
3274 size_t iv_size = 16;
3275 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003276 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003277 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003278 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003279 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003280 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003281 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003282 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003283 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3284 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003285 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003286
Gilles Peskine8817f612018-12-18 00:18:46 +01003287 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003288
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003289 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3290 psa_set_key_algorithm( &attributes, alg );
3291 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003292
Gilles Peskine73676cb2019-05-15 20:15:10 +02003293 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003294
Gilles Peskine8817f612018-12-18 00:18:46 +01003295 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3296 handle, alg ) );
3297 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3298 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003299
Gilles Peskine8817f612018-12-18 00:18:46 +01003300 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3301 iv, iv_size,
3302 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003303 output1_buffer_size = ( (size_t) input->len +
3304 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003305 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003306
Gilles Peskinee0866522019-02-19 19:44:00 +01003307 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003308
Gilles Peskine8817f612018-12-18 00:18:46 +01003309 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3310 output1, output1_buffer_size,
3311 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003312 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003313
Gilles Peskine8817f612018-12-18 00:18:46 +01003314 PSA_ASSERT( psa_cipher_update( &operation1,
3315 input->x + first_part_size,
3316 input->len - first_part_size,
3317 output1, output1_buffer_size,
3318 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003319 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003320
Gilles Peskine8817f612018-12-18 00:18:46 +01003321 PSA_ASSERT( psa_cipher_finish( &operation1,
3322 output1 + output1_length,
3323 output1_buffer_size - output1_length,
3324 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003325 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003326
Gilles Peskine8817f612018-12-18 00:18:46 +01003327 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003328
Gilles Peskine048b7f02018-06-08 14:20:49 +02003329 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003330 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003331
Gilles Peskine8817f612018-12-18 00:18:46 +01003332 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3333 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003334
Gilles Peskine8817f612018-12-18 00:18:46 +01003335 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3336 output2, output2_buffer_size,
3337 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003338 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003339
Gilles Peskine8817f612018-12-18 00:18:46 +01003340 PSA_ASSERT( psa_cipher_update( &operation2,
3341 output1 + first_part_size,
3342 output1_length - first_part_size,
3343 output2, output2_buffer_size,
3344 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003345 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003346
Gilles Peskine8817f612018-12-18 00:18:46 +01003347 PSA_ASSERT( psa_cipher_finish( &operation2,
3348 output2 + output2_length,
3349 output2_buffer_size - output2_length,
3350 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003351 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003352
Gilles Peskine8817f612018-12-18 00:18:46 +01003353 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003354
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003355 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003356
3357exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003358 mbedtls_free( output1 );
3359 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003360 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003361 mbedtls_psa_crypto_free( );
3362}
3363/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003364
Gilles Peskine20035e32018-02-03 22:44:14 +01003365/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003366void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003367 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003368 data_t *nonce,
3369 data_t *additional_data,
3370 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003371 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003372{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003373 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003374 psa_key_type_t key_type = key_type_arg;
3375 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003376 unsigned char *output_data = NULL;
3377 size_t output_size = 0;
3378 size_t output_length = 0;
3379 unsigned char *output_data2 = NULL;
3380 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003381 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003382 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003383 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003384
Gilles Peskine4abf7412018-06-18 16:35:34 +02003385 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003386 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3387 * should be exact. */
3388 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3389 TEST_EQUAL( output_size,
3390 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003391 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003392
Gilles Peskine8817f612018-12-18 00:18:46 +01003393 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003394
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003395 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3396 psa_set_key_algorithm( &attributes, alg );
3397 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398
Gilles Peskine049c7532019-05-15 20:22:09 +02003399 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3400 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003401
Gilles Peskinefe11b722018-12-18 00:24:04 +01003402 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3403 nonce->x, nonce->len,
3404 additional_data->x,
3405 additional_data->len,
3406 input_data->x, input_data->len,
3407 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003408 &output_length ),
3409 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003410
3411 if( PSA_SUCCESS == expected_result )
3412 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003413 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003414
Gilles Peskine003a4a92019-05-14 16:09:40 +02003415 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3416 * should be exact. */
3417 TEST_EQUAL( input_data->len,
3418 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3419
Gilles Peskinefe11b722018-12-18 00:24:04 +01003420 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3421 nonce->x, nonce->len,
3422 additional_data->x,
3423 additional_data->len,
3424 output_data, output_length,
3425 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003426 &output_length2 ),
3427 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003428
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003429 ASSERT_COMPARE( input_data->x, input_data->len,
3430 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003431 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003432
Gilles Peskinea1cac842018-06-11 19:33:02 +02003433exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003434 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435 mbedtls_free( output_data );
3436 mbedtls_free( output_data2 );
3437 mbedtls_psa_crypto_free( );
3438}
3439/* END_CASE */
3440
3441/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003442void aead_encrypt( int key_type_arg, data_t *key_data,
3443 int alg_arg,
3444 data_t *nonce,
3445 data_t *additional_data,
3446 data_t *input_data,
3447 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003448{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003449 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003450 psa_key_type_t key_type = key_type_arg;
3451 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003452 unsigned char *output_data = NULL;
3453 size_t output_size = 0;
3454 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003455 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003456 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003457
Gilles Peskine4abf7412018-06-18 16:35:34 +02003458 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003459 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3460 * should be exact. */
3461 TEST_EQUAL( output_size,
3462 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003463 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003464
Gilles Peskine8817f612018-12-18 00:18:46 +01003465 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003466
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003467 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3468 psa_set_key_algorithm( &attributes, alg );
3469 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003470
Gilles Peskine049c7532019-05-15 20:22:09 +02003471 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3472 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003473
Gilles Peskine8817f612018-12-18 00:18:46 +01003474 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3475 nonce->x, nonce->len,
3476 additional_data->x, additional_data->len,
3477 input_data->x, input_data->len,
3478 output_data, output_size,
3479 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003480
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003481 ASSERT_COMPARE( expected_result->x, expected_result->len,
3482 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003483
Gilles Peskinea1cac842018-06-11 19:33:02 +02003484exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003485 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003486 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003487 mbedtls_psa_crypto_free( );
3488}
3489/* END_CASE */
3490
3491/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003492void aead_decrypt( int key_type_arg, data_t *key_data,
3493 int alg_arg,
3494 data_t *nonce,
3495 data_t *additional_data,
3496 data_t *input_data,
3497 data_t *expected_data,
3498 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003499{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003500 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003501 psa_key_type_t key_type = key_type_arg;
3502 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003503 unsigned char *output_data = NULL;
3504 size_t output_size = 0;
3505 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003506 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003507 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003508 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003509
Gilles Peskine003a4a92019-05-14 16:09:40 +02003510 output_size = input_data->len - tag_length;
3511 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3512 * should be exact. */
3513 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3514 TEST_EQUAL( output_size,
3515 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003516 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003517
Gilles Peskine8817f612018-12-18 00:18:46 +01003518 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003519
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003520 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3521 psa_set_key_algorithm( &attributes, alg );
3522 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003523
Gilles Peskine049c7532019-05-15 20:22:09 +02003524 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3525 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003526
Gilles Peskinefe11b722018-12-18 00:24:04 +01003527 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3528 nonce->x, nonce->len,
3529 additional_data->x,
3530 additional_data->len,
3531 input_data->x, input_data->len,
3532 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003533 &output_length ),
3534 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003535
Gilles Peskine2d277862018-06-18 15:41:12 +02003536 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003537 ASSERT_COMPARE( expected_data->x, expected_data->len,
3538 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003539
Gilles Peskinea1cac842018-06-11 19:33:02 +02003540exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003541 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003542 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003543 mbedtls_psa_crypto_free( );
3544}
3545/* END_CASE */
3546
3547/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003548void signature_size( int type_arg,
3549 int bits,
3550 int alg_arg,
3551 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003552{
3553 psa_key_type_t type = type_arg;
3554 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003555 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003556 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003557exit:
3558 ;
3559}
3560/* END_CASE */
3561
3562/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003563void sign_deterministic( int key_type_arg, data_t *key_data,
3564 int alg_arg, data_t *input_data,
3565 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003566{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003567 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003568 psa_key_type_t key_type = key_type_arg;
3569 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003570 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003571 unsigned char *signature = NULL;
3572 size_t signature_size;
3573 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003574 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003575
Gilles Peskine8817f612018-12-18 00:18:46 +01003576 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003577
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003578 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3579 psa_set_key_algorithm( &attributes, alg );
3580 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003581
Gilles Peskine049c7532019-05-15 20:22:09 +02003582 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3583 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003584 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3585 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003586
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003587 /* Allocate a buffer which has the size advertized by the
3588 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003589 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3590 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003591 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003592 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003593 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003594
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003595 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003596 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3597 input_data->x, input_data->len,
3598 signature, signature_size,
3599 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003600 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003601 ASSERT_COMPARE( output_data->x, output_data->len,
3602 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003603
3604exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003605 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003606 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003607 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003608 mbedtls_psa_crypto_free( );
3609}
3610/* END_CASE */
3611
3612/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003613void sign_fail( int key_type_arg, data_t *key_data,
3614 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003615 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003616{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003617 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003618 psa_key_type_t key_type = key_type_arg;
3619 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003620 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003621 psa_status_t actual_status;
3622 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003623 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003624 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003625 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003626
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003627 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003628
Gilles Peskine8817f612018-12-18 00:18:46 +01003629 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003630
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003631 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3632 psa_set_key_algorithm( &attributes, alg );
3633 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003634
Gilles Peskine049c7532019-05-15 20:22:09 +02003635 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3636 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003637
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003638 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003639 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003640 signature, signature_size,
3641 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003642 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003643 /* The value of *signature_length is unspecified on error, but
3644 * whatever it is, it should be less than signature_size, so that
3645 * if the caller tries to read *signature_length bytes without
3646 * checking the error code then they don't overflow a buffer. */
3647 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003648
3649exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003650 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003651 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003652 mbedtls_free( signature );
3653 mbedtls_psa_crypto_free( );
3654}
3655/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003656
3657/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003658void sign_verify( int key_type_arg, data_t *key_data,
3659 int alg_arg, data_t *input_data )
3660{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003661 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003662 psa_key_type_t key_type = key_type_arg;
3663 psa_algorithm_t alg = alg_arg;
3664 size_t key_bits;
3665 unsigned char *signature = NULL;
3666 size_t signature_size;
3667 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003668 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003669
Gilles Peskine8817f612018-12-18 00:18:46 +01003670 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003671
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003672 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3673 psa_set_key_algorithm( &attributes, alg );
3674 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003675
Gilles Peskine049c7532019-05-15 20:22:09 +02003676 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3677 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003678 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3679 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003680
3681 /* Allocate a buffer which has the size advertized by the
3682 * library. */
3683 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3684 key_bits, alg );
3685 TEST_ASSERT( signature_size != 0 );
3686 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003687 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003688
3689 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003690 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3691 input_data->x, input_data->len,
3692 signature, signature_size,
3693 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003694 /* Check that the signature length looks sensible. */
3695 TEST_ASSERT( signature_length <= signature_size );
3696 TEST_ASSERT( signature_length > 0 );
3697
3698 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003699 PSA_ASSERT( psa_asymmetric_verify(
3700 handle, alg,
3701 input_data->x, input_data->len,
3702 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003703
3704 if( input_data->len != 0 )
3705 {
3706 /* Flip a bit in the input and verify that the signature is now
3707 * detected as invalid. Flip a bit at the beginning, not at the end,
3708 * because ECDSA may ignore the last few bits of the input. */
3709 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003710 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3711 input_data->x, input_data->len,
3712 signature, signature_length ),
3713 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003714 }
3715
3716exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003717 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003718 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003719 mbedtls_free( signature );
3720 mbedtls_psa_crypto_free( );
3721}
3722/* END_CASE */
3723
3724/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003725void asymmetric_verify( int key_type_arg, data_t *key_data,
3726 int alg_arg, data_t *hash_data,
3727 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003728{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003729 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003730 psa_key_type_t key_type = key_type_arg;
3731 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003732 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003733
Gilles Peskine69c12672018-06-28 00:07:19 +02003734 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3735
Gilles Peskine8817f612018-12-18 00:18:46 +01003736 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003737
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003738 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3739 psa_set_key_algorithm( &attributes, alg );
3740 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003741
Gilles Peskine049c7532019-05-15 20:22:09 +02003742 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3743 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003744
Gilles Peskine8817f612018-12-18 00:18:46 +01003745 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3746 hash_data->x, hash_data->len,
3747 signature_data->x,
3748 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003749exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003750 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003751 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003752 mbedtls_psa_crypto_free( );
3753}
3754/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003755
3756/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003757void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3758 int alg_arg, data_t *hash_data,
3759 data_t *signature_data,
3760 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003761{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003762 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003763 psa_key_type_t key_type = key_type_arg;
3764 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003765 psa_status_t actual_status;
3766 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003767 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003768
Gilles Peskine8817f612018-12-18 00:18:46 +01003769 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003770
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003771 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3772 psa_set_key_algorithm( &attributes, alg );
3773 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003774
Gilles Peskine049c7532019-05-15 20:22:09 +02003775 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3776 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003777
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003778 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003779 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003780 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003781 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003782
Gilles Peskinefe11b722018-12-18 00:24:04 +01003783 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003784
3785exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003786 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003787 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003788 mbedtls_psa_crypto_free( );
3789}
3790/* END_CASE */
3791
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003792/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003793void asymmetric_encrypt( int key_type_arg,
3794 data_t *key_data,
3795 int alg_arg,
3796 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003797 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003798 int expected_output_length_arg,
3799 int expected_status_arg )
3800{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003801 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003802 psa_key_type_t key_type = key_type_arg;
3803 psa_algorithm_t alg = alg_arg;
3804 size_t expected_output_length = expected_output_length_arg;
3805 size_t key_bits;
3806 unsigned char *output = NULL;
3807 size_t output_size;
3808 size_t output_length = ~0;
3809 psa_status_t actual_status;
3810 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003811 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003812
Gilles Peskine8817f612018-12-18 00:18:46 +01003813 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003814
Gilles Peskine656896e2018-06-29 19:12:28 +02003815 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003816 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3817 psa_set_key_algorithm( &attributes, alg );
3818 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003819 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3820 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003821
3822 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003823 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3824 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003825 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003826 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003827
3828 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003829 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003830 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003831 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003832 output, output_size,
3833 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003834 TEST_EQUAL( actual_status, expected_status );
3835 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003836
Gilles Peskine68428122018-06-30 18:42:41 +02003837 /* If the label is empty, the test framework puts a non-null pointer
3838 * in label->x. Test that a null pointer works as well. */
3839 if( label->len == 0 )
3840 {
3841 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003842 if( output_size != 0 )
3843 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003844 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003845 input_data->x, input_data->len,
3846 NULL, label->len,
3847 output, output_size,
3848 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003849 TEST_EQUAL( actual_status, expected_status );
3850 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003851 }
3852
Gilles Peskine656896e2018-06-29 19:12:28 +02003853exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003854 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003855 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003856 mbedtls_free( output );
3857 mbedtls_psa_crypto_free( );
3858}
3859/* END_CASE */
3860
3861/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003862void asymmetric_encrypt_decrypt( int key_type_arg,
3863 data_t *key_data,
3864 int alg_arg,
3865 data_t *input_data,
3866 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003867{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003868 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003869 psa_key_type_t key_type = key_type_arg;
3870 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003871 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003872 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003873 size_t output_size;
3874 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003875 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003876 size_t output2_size;
3877 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003878 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003879
Gilles Peskine8817f612018-12-18 00:18:46 +01003880 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003882 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3883 psa_set_key_algorithm( &attributes, alg );
3884 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003885
Gilles Peskine049c7532019-05-15 20:22:09 +02003886 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3887 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003888
3889 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003890 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3891 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003892 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003893 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003894 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003895 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003896
Gilles Peskineeebd7382018-06-08 18:11:54 +02003897 /* We test encryption by checking that encrypt-then-decrypt gives back
3898 * the original plaintext because of the non-optional random
3899 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003900 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3901 input_data->x, input_data->len,
3902 label->x, label->len,
3903 output, output_size,
3904 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003905 /* We don't know what ciphertext length to expect, but check that
3906 * it looks sensible. */
3907 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003908
Gilles Peskine8817f612018-12-18 00:18:46 +01003909 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3910 output, output_length,
3911 label->x, label->len,
3912 output2, output2_size,
3913 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003914 ASSERT_COMPARE( input_data->x, input_data->len,
3915 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003916
3917exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003918 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003919 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003920 mbedtls_free( output );
3921 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003922 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003923}
3924/* END_CASE */
3925
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003926/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003927void asymmetric_decrypt( int key_type_arg,
3928 data_t *key_data,
3929 int alg_arg,
3930 data_t *input_data,
3931 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003932 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003933{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003934 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003935 psa_key_type_t key_type = key_type_arg;
3936 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003937 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003938 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003939 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003940 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003941
Jaeden Amero412654a2019-02-06 12:57:46 +00003942 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003943 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003944
Gilles Peskine8817f612018-12-18 00:18:46 +01003945 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003946
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003947 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3948 psa_set_key_algorithm( &attributes, alg );
3949 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003950
Gilles Peskine049c7532019-05-15 20:22:09 +02003951 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3952 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003953
Gilles Peskine8817f612018-12-18 00:18:46 +01003954 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3955 input_data->x, input_data->len,
3956 label->x, label->len,
3957 output,
3958 output_size,
3959 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003960 ASSERT_COMPARE( expected_data->x, expected_data->len,
3961 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003962
Gilles Peskine68428122018-06-30 18:42:41 +02003963 /* If the label is empty, the test framework puts a non-null pointer
3964 * in label->x. Test that a null pointer works as well. */
3965 if( label->len == 0 )
3966 {
3967 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003968 if( output_size != 0 )
3969 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003970 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3971 input_data->x, input_data->len,
3972 NULL, label->len,
3973 output,
3974 output_size,
3975 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003976 ASSERT_COMPARE( expected_data->x, expected_data->len,
3977 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003978 }
3979
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003980exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003981 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003982 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003983 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003984 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003985}
3986/* END_CASE */
3987
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003988/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003989void asymmetric_decrypt_fail( int key_type_arg,
3990 data_t *key_data,
3991 int alg_arg,
3992 data_t *input_data,
3993 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003994 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003995 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003996{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003997 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003998 psa_key_type_t key_type = key_type_arg;
3999 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004000 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004001 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004002 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004003 psa_status_t actual_status;
4004 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004005 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004006
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004007 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004008
Gilles Peskine8817f612018-12-18 00:18:46 +01004009 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004010
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004011 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4012 psa_set_key_algorithm( &attributes, alg );
4013 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004014
Gilles Peskine049c7532019-05-15 20:22:09 +02004015 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4016 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004017
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004018 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004019 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004020 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004021 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004022 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004023 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004024 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004025
Gilles Peskine68428122018-06-30 18:42:41 +02004026 /* If the label is empty, the test framework puts a non-null pointer
4027 * in label->x. Test that a null pointer works as well. */
4028 if( label->len == 0 )
4029 {
4030 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004031 if( output_size != 0 )
4032 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004033 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004034 input_data->x, input_data->len,
4035 NULL, label->len,
4036 output, output_size,
4037 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004038 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004039 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004040 }
4041
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004042exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004043 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004044 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004045 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004046 mbedtls_psa_crypto_free( );
4047}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004048/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004049
4050/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004051void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004052{
4053 /* Test each valid way of initializing the object, except for `= {0}`, as
4054 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4055 * though it's OK by the C standard. We could test for this, but we'd need
4056 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004057 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004058 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4059 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4060 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004061
4062 memset( &zero, 0, sizeof( zero ) );
4063
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004064 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004065 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004066 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004067 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004068 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004069 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004070 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004071
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004072 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004073 PSA_ASSERT( psa_key_derivation_abort(&func) );
4074 PSA_ASSERT( psa_key_derivation_abort(&init) );
4075 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004076}
4077/* END_CASE */
4078
4079/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004080void derive_setup( int key_type_arg,
4081 data_t *key_data,
4082 int alg_arg,
4083 data_t *salt,
4084 data_t *label,
4085 int requested_capacity_arg,
4086 int expected_status_arg )
4087{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004088 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004089 size_t key_type = key_type_arg;
4090 psa_algorithm_t alg = alg_arg;
4091 size_t requested_capacity = requested_capacity_arg;
4092 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004093 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004094 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004095
Gilles Peskine8817f612018-12-18 00:18:46 +01004096 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004097
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004098 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4099 psa_set_key_algorithm( &attributes, alg );
4100 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004101
Gilles Peskine049c7532019-05-15 20:22:09 +02004102 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4103 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004104
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004105 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004106 salt->x, salt->len,
4107 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004108 requested_capacity ),
4109 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004110
4111exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004112 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004113 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004114 mbedtls_psa_crypto_free( );
4115}
4116/* END_CASE */
4117
4118/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004119void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004120{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004121 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004122 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004123 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004124 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004125 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004126 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004127 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4128 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4129 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004130 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004131
Gilles Peskine8817f612018-12-18 00:18:46 +01004132 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004133
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004134 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4135 psa_set_key_algorithm( &attributes, alg );
4136 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004137
Gilles Peskine73676cb2019-05-15 20:15:10 +02004138 PSA_ASSERT( psa_import_key( &attributes,
4139 key_data, sizeof( key_data ),
4140 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004141
4142 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004143 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004144 NULL, 0,
4145 NULL, 0,
4146 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004147
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004148 /* state of operation shouldn't allow additional generation */
4149 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004150 NULL, 0,
4151 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004152 capacity ),
4153 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004154
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004155 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004156
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004157 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004158 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004159
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004160exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004161 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004162 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004163 mbedtls_psa_crypto_free( );
4164}
4165/* END_CASE */
4166
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004167/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004168void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004169{
4170 uint8_t output_buffer[16];
4171 size_t buffer_size = 16;
4172 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004173 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004174
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004175 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4176 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004177 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004178
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004179 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004180 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004181
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004182 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004183
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004184 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4185 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004186 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004187
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004188 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004189 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004190
4191exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004192 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004193}
4194/* END_CASE */
4195
4196/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004197void derive_output( int alg_arg,
4198 data_t *key_data,
4199 data_t *salt,
4200 data_t *label,
4201 int requested_capacity_arg,
4202 data_t *expected_output1,
4203 data_t *expected_output2 )
4204{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004205 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004206 psa_algorithm_t alg = alg_arg;
4207 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004208 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004209 uint8_t *expected_outputs[2] =
4210 {expected_output1->x, expected_output2->x};
4211 size_t output_sizes[2] =
4212 {expected_output1->len, expected_output2->len};
4213 size_t output_buffer_size = 0;
4214 uint8_t *output_buffer = NULL;
4215 size_t expected_capacity;
4216 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004217 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004218 psa_status_t status;
4219 unsigned i;
4220
4221 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4222 {
4223 if( output_sizes[i] > output_buffer_size )
4224 output_buffer_size = output_sizes[i];
4225 if( output_sizes[i] == 0 )
4226 expected_outputs[i] = NULL;
4227 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004228 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004229 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004230
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004231 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4232 psa_set_key_algorithm( &attributes, alg );
4233 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004234
Gilles Peskine049c7532019-05-15 20:22:09 +02004235 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4236 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004237
4238 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004239 if( PSA_ALG_IS_HKDF( alg ) )
4240 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004241 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4242 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004243 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004244 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004245 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004246 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004247 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004248 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004249 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004250 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004251 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004252 label->x, label->len ) );
4253 }
4254 else
4255 {
4256 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004257 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004258 salt->x, salt->len,
4259 label->x, label->len,
4260 requested_capacity ) );
4261 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004262 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004263 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004264 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004265 expected_capacity = requested_capacity;
4266
4267 /* Expansion phase. */
4268 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4269 {
4270 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004271 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004272 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004273 if( expected_capacity == 0 && output_sizes[i] == 0 )
4274 {
4275 /* Reading 0 bytes when 0 bytes are available can go either way. */
4276 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004277 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004278 continue;
4279 }
4280 else if( expected_capacity == 0 ||
4281 output_sizes[i] > expected_capacity )
4282 {
4283 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004284 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004285 expected_capacity = 0;
4286 continue;
4287 }
4288 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004289 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004290 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004291 ASSERT_COMPARE( output_buffer, output_sizes[i],
4292 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004293 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004294 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004295 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004296 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004297 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004298 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004299 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004300
4301exit:
4302 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004303 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004304 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004305 mbedtls_psa_crypto_free( );
4306}
4307/* END_CASE */
4308
4309/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004310void derive_full( int alg_arg,
4311 data_t *key_data,
4312 data_t *salt,
4313 data_t *label,
4314 int requested_capacity_arg )
4315{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004316 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004317 psa_algorithm_t alg = alg_arg;
4318 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004319 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004320 unsigned char output_buffer[16];
4321 size_t expected_capacity = requested_capacity;
4322 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004323 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004324
Gilles Peskine8817f612018-12-18 00:18:46 +01004325 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004326
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004327 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4328 psa_set_key_algorithm( &attributes, alg );
4329 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004330
Gilles Peskine049c7532019-05-15 20:22:09 +02004331 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4332 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004333
4334 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004335 if( PSA_ALG_IS_HKDF( alg ) )
4336 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004337 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4338 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004339 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004340 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004341 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004342 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004343 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004344 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004345 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004346 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004347 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004348 label->x, label->len ) );
4349 }
4350 else
4351 {
4352 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004353 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004354 salt->x, salt->len,
4355 label->x, label->len,
4356 requested_capacity ) );
4357 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004358 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004359 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004360 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004361
4362 /* Expansion phase. */
4363 while( current_capacity > 0 )
4364 {
4365 size_t read_size = sizeof( output_buffer );
4366 if( read_size > current_capacity )
4367 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004368 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004369 output_buffer,
4370 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004371 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004372 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004373 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004374 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004375 }
4376
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004377 /* Check that the operation refuses to go over capacity. */
4378 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004379 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004380
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004381 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004382
4383exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004384 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004385 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004386 mbedtls_psa_crypto_free( );
4387}
4388/* END_CASE */
4389
4390/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004391void derive_key_exercise( int alg_arg,
4392 data_t *key_data,
4393 data_t *salt,
4394 data_t *label,
4395 int derived_type_arg,
4396 int derived_bits_arg,
4397 int derived_usage_arg,
4398 int derived_alg_arg )
4399{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004400 psa_key_handle_t base_handle = 0;
4401 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004402 psa_algorithm_t alg = alg_arg;
4403 psa_key_type_t derived_type = derived_type_arg;
4404 size_t derived_bits = derived_bits_arg;
4405 psa_key_usage_t derived_usage = derived_usage_arg;
4406 psa_algorithm_t derived_alg = derived_alg_arg;
4407 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004408 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004409 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004410 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004411
Gilles Peskine8817f612018-12-18 00:18:46 +01004412 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004413
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004414 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4415 psa_set_key_algorithm( &attributes, alg );
4416 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004417 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4418 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004419
4420 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004421 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004422 salt->x, salt->len,
4423 label->x, label->len,
4424 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004425 psa_set_key_usage_flags( &attributes, derived_usage );
4426 psa_set_key_algorithm( &attributes, derived_alg );
4427 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004428 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004429 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004430 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004431
4432 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004433 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4434 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4435 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004436
4437 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004438 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004439 goto exit;
4440
4441exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004442 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004443 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004444 psa_destroy_key( base_handle );
4445 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004446 mbedtls_psa_crypto_free( );
4447}
4448/* END_CASE */
4449
4450/* BEGIN_CASE */
4451void derive_key_export( int alg_arg,
4452 data_t *key_data,
4453 data_t *salt,
4454 data_t *label,
4455 int bytes1_arg,
4456 int bytes2_arg )
4457{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004458 psa_key_handle_t base_handle = 0;
4459 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004460 psa_algorithm_t alg = alg_arg;
4461 size_t bytes1 = bytes1_arg;
4462 size_t bytes2 = bytes2_arg;
4463 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004464 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004465 uint8_t *output_buffer = NULL;
4466 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004467 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4468 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004469 size_t length;
4470
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004471 ASSERT_ALLOC( output_buffer, capacity );
4472 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004473 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004474
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004475 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4476 psa_set_key_algorithm( &base_attributes, alg );
4477 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004478 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4479 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004480
4481 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004482 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004483 salt->x, salt->len,
4484 label->x, label->len,
4485 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004486 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004487 output_buffer,
4488 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004489 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004490
4491 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004492 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004493 salt->x, salt->len,
4494 label->x, label->len,
4495 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004496 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4497 psa_set_key_algorithm( &derived_attributes, 0 );
4498 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004499 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004500 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004501 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004502 PSA_ASSERT( psa_export_key( derived_handle,
4503 export_buffer, bytes1,
4504 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004505 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004506 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004507 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004508 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004509 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004510 PSA_ASSERT( psa_export_key( derived_handle,
4511 export_buffer + bytes1, bytes2,
4512 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004513 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004514
4515 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004516 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4517 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004518
4519exit:
4520 mbedtls_free( output_buffer );
4521 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004522 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004523 psa_destroy_key( base_handle );
4524 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004525 mbedtls_psa_crypto_free( );
4526}
4527/* END_CASE */
4528
4529/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004530void key_agreement_setup( int alg_arg,
4531 int our_key_type_arg, data_t *our_key_data,
4532 data_t *peer_key_data,
4533 int expected_status_arg )
4534{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004535 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004536 psa_algorithm_t alg = alg_arg;
4537 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004538 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004539 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004540 psa_status_t expected_status = expected_status_arg;
4541 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004542
Gilles Peskine8817f612018-12-18 00:18:46 +01004543 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004544
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004545 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4546 psa_set_key_algorithm( &attributes, alg );
4547 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004548 PSA_ASSERT( psa_import_key( &attributes,
4549 our_key_data->x, our_key_data->len,
4550 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004551
Gilles Peskine77f40d82019-04-11 21:27:06 +02004552 /* The tests currently include inputs that should fail at either step.
4553 * Test cases that fail at the setup step should be changed to call
4554 * key_derivation_setup instead, and this function should be renamed
4555 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004556 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004557 if( status == PSA_SUCCESS )
4558 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004559 TEST_EQUAL( psa_key_derivation_key_agreement(
4560 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4561 our_key,
4562 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004563 expected_status );
4564 }
4565 else
4566 {
4567 TEST_ASSERT( status == expected_status );
4568 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004569
4570exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004571 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004572 psa_destroy_key( our_key );
4573 mbedtls_psa_crypto_free( );
4574}
4575/* END_CASE */
4576
4577/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004578void raw_key_agreement( int alg_arg,
4579 int our_key_type_arg, data_t *our_key_data,
4580 data_t *peer_key_data,
4581 data_t *expected_output )
4582{
4583 psa_key_handle_t our_key = 0;
4584 psa_algorithm_t alg = alg_arg;
4585 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004586 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004587 unsigned char *output = NULL;
4588 size_t output_length = ~0;
4589
4590 ASSERT_ALLOC( output, expected_output->len );
4591 PSA_ASSERT( psa_crypto_init( ) );
4592
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004593 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4594 psa_set_key_algorithm( &attributes, alg );
4595 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004596 PSA_ASSERT( psa_import_key( &attributes,
4597 our_key_data->x, our_key_data->len,
4598 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004599
Gilles Peskinebe697d82019-05-16 18:00:41 +02004600 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4601 peer_key_data->x, peer_key_data->len,
4602 output, expected_output->len,
4603 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004604 ASSERT_COMPARE( output, output_length,
4605 expected_output->x, expected_output->len );
4606
4607exit:
4608 mbedtls_free( output );
4609 psa_destroy_key( our_key );
4610 mbedtls_psa_crypto_free( );
4611}
4612/* END_CASE */
4613
4614/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004615void key_agreement_capacity( int alg_arg,
4616 int our_key_type_arg, data_t *our_key_data,
4617 data_t *peer_key_data,
4618 int expected_capacity_arg )
4619{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004620 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004621 psa_algorithm_t alg = alg_arg;
4622 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004623 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004624 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004625 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004626 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004627
Gilles Peskine8817f612018-12-18 00:18:46 +01004628 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004629
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004630 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4631 psa_set_key_algorithm( &attributes, alg );
4632 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004633 PSA_ASSERT( psa_import_key( &attributes,
4634 our_key_data->x, our_key_data->len,
4635 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004636
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004637 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004638 PSA_ASSERT( psa_key_derivation_key_agreement(
4639 &operation,
4640 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4641 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004642 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4643 {
4644 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004645 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004646 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004647 NULL, 0 ) );
4648 }
Gilles Peskine59685592018-09-18 12:11:34 +02004649
Gilles Peskinebf491972018-10-25 22:36:12 +02004650 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004651 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004652 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004653 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004654
Gilles Peskinebf491972018-10-25 22:36:12 +02004655 /* Test the actual capacity by reading the output. */
4656 while( actual_capacity > sizeof( output ) )
4657 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004658 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004659 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004660 actual_capacity -= sizeof( output );
4661 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004662 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004663 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004664 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004665 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004666
Gilles Peskine59685592018-09-18 12:11:34 +02004667exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004668 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004669 psa_destroy_key( our_key );
4670 mbedtls_psa_crypto_free( );
4671}
4672/* END_CASE */
4673
4674/* BEGIN_CASE */
4675void key_agreement_output( int alg_arg,
4676 int our_key_type_arg, data_t *our_key_data,
4677 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004678 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004679{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004680 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004681 psa_algorithm_t alg = alg_arg;
4682 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004683 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004684 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004685 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004686
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004687 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4688 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004689
Gilles Peskine8817f612018-12-18 00:18:46 +01004690 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004691
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004692 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4693 psa_set_key_algorithm( &attributes, alg );
4694 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004695 PSA_ASSERT( psa_import_key( &attributes,
4696 our_key_data->x, our_key_data->len,
4697 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004698
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004699 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004700 PSA_ASSERT( psa_key_derivation_key_agreement(
4701 &operation,
4702 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4703 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004704 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4705 {
4706 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004707 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004708 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004709 NULL, 0 ) );
4710 }
Gilles Peskine59685592018-09-18 12:11:34 +02004711
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004712 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004713 actual_output,
4714 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004715 ASSERT_COMPARE( actual_output, expected_output1->len,
4716 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004717 if( expected_output2->len != 0 )
4718 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004719 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004720 actual_output,
4721 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004722 ASSERT_COMPARE( actual_output, expected_output2->len,
4723 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004724 }
Gilles Peskine59685592018-09-18 12:11:34 +02004725
4726exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004727 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004728 psa_destroy_key( our_key );
4729 mbedtls_psa_crypto_free( );
4730 mbedtls_free( actual_output );
4731}
4732/* END_CASE */
4733
4734/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004735void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004736{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004737 size_t bytes = bytes_arg;
4738 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004739 unsigned char *output = NULL;
4740 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004741 size_t i;
4742 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004743
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004744 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4745 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004746 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004747
Gilles Peskine8817f612018-12-18 00:18:46 +01004748 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004749
Gilles Peskinea50d7392018-06-21 10:22:13 +02004750 /* Run several times, to ensure that every output byte will be
4751 * nonzero at least once with overwhelming probability
4752 * (2^(-8*number_of_runs)). */
4753 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004754 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004755 if( bytes != 0 )
4756 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004757 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004758
4759 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004760 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4761 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004762
4763 for( i = 0; i < bytes; i++ )
4764 {
4765 if( output[i] != 0 )
4766 ++changed[i];
4767 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004768 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004769
4770 /* Check that every byte was changed to nonzero at least once. This
4771 * validates that psa_generate_random is overwriting every byte of
4772 * the output buffer. */
4773 for( i = 0; i < bytes; i++ )
4774 {
4775 TEST_ASSERT( changed[i] != 0 );
4776 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004777
4778exit:
4779 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004780 mbedtls_free( output );
4781 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004782}
4783/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004784
4785/* BEGIN_CASE */
4786void generate_key( int type_arg,
4787 int bits_arg,
4788 int usage_arg,
4789 int alg_arg,
4790 int expected_status_arg )
4791{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004792 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004793 psa_key_type_t type = type_arg;
4794 psa_key_usage_t usage = usage_arg;
4795 size_t bits = bits_arg;
4796 psa_algorithm_t alg = alg_arg;
4797 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004798 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004799 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004800
Gilles Peskine8817f612018-12-18 00:18:46 +01004801 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004802
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004803 psa_set_key_usage_flags( &attributes, usage );
4804 psa_set_key_algorithm( &attributes, alg );
4805 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004806 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004807
4808 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004809 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004810 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004811 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004812
4813 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004814 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4815 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4816 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004817
Gilles Peskine818ca122018-06-20 18:16:48 +02004818 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004819 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004820 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004821
4822exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004823 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004824 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004825 mbedtls_psa_crypto_free( );
4826}
4827/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004828
Gilles Peskinee56e8782019-04-26 17:34:02 +02004829/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4830void generate_key_rsa( int bits_arg,
4831 data_t *e_arg,
4832 int expected_status_arg )
4833{
4834 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02004835 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02004836 size_t bits = bits_arg;
4837 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4838 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4839 psa_status_t expected_status = expected_status_arg;
4840 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4841 uint8_t *exported = NULL;
4842 size_t exported_size =
4843 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4844 size_t exported_length = SIZE_MAX;
4845 uint8_t *e_read_buffer = NULL;
4846 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004847 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004848 size_t e_read_length = SIZE_MAX;
4849
4850 if( e_arg->len == 0 ||
4851 ( e_arg->len == 3 &&
4852 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4853 {
4854 is_default_public_exponent = 1;
4855 e_read_size = 0;
4856 }
4857 ASSERT_ALLOC( e_read_buffer, e_read_size );
4858 ASSERT_ALLOC( exported, exported_size );
4859
4860 PSA_ASSERT( psa_crypto_init( ) );
4861
4862 psa_set_key_usage_flags( &attributes, usage );
4863 psa_set_key_algorithm( &attributes, alg );
4864 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4865 e_arg->x, e_arg->len ) );
4866 psa_set_key_bits( &attributes, bits );
4867
4868 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004869 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004870 if( expected_status != PSA_SUCCESS )
4871 goto exit;
4872
4873 /* Test the key information */
4874 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4875 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4876 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4877 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4878 e_read_buffer, e_read_size,
4879 &e_read_length ) );
4880 if( is_default_public_exponent )
4881 TEST_EQUAL( e_read_length, 0 );
4882 else
4883 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4884
4885 /* Do something with the key according to its type and permitted usage. */
4886 if( ! exercise_key( handle, usage, alg ) )
4887 goto exit;
4888
4889 /* Export the key and check the public exponent. */
4890 PSA_ASSERT( psa_export_public_key( handle,
4891 exported, exported_size,
4892 &exported_length ) );
4893 {
4894 uint8_t *p = exported;
4895 uint8_t *end = exported + exported_length;
4896 size_t len;
4897 /* RSAPublicKey ::= SEQUENCE {
4898 * modulus INTEGER, -- n
4899 * publicExponent INTEGER } -- e
4900 */
4901 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004902 MBEDTLS_ASN1_SEQUENCE |
4903 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004904 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4905 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4906 MBEDTLS_ASN1_INTEGER ) );
4907 if( len >= 1 && p[0] == 0 )
4908 {
4909 ++p;
4910 --len;
4911 }
4912 if( e_arg->len == 0 )
4913 {
4914 TEST_EQUAL( len, 3 );
4915 TEST_EQUAL( p[0], 1 );
4916 TEST_EQUAL( p[1], 0 );
4917 TEST_EQUAL( p[2], 1 );
4918 }
4919 else
4920 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4921 }
4922
4923exit:
4924 psa_reset_key_attributes( &attributes );
4925 psa_destroy_key( handle );
4926 mbedtls_psa_crypto_free( );
4927 mbedtls_free( e_read_buffer );
4928 mbedtls_free( exported );
4929}
4930/* END_CASE */
4931
Darryl Greend49a4992018-06-18 17:27:26 +01004932/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004933void persistent_key_load_key_from_storage( data_t *data,
4934 int type_arg, int bits_arg,
4935 int usage_flags_arg, int alg_arg,
4936 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004937{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004938 psa_key_id_t key_id = 1;
4939 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004940 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004941 psa_key_handle_t base_key = 0;
4942 psa_key_type_t type = type_arg;
4943 size_t bits = bits_arg;
4944 psa_key_usage_t usage_flags = usage_flags_arg;
4945 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004946 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004947 unsigned char *first_export = NULL;
4948 unsigned char *second_export = NULL;
4949 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4950 size_t first_exported_length;
4951 size_t second_exported_length;
4952
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004953 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4954 {
4955 ASSERT_ALLOC( first_export, export_size );
4956 ASSERT_ALLOC( second_export, export_size );
4957 }
Darryl Greend49a4992018-06-18 17:27:26 +01004958
Gilles Peskine8817f612018-12-18 00:18:46 +01004959 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004960
Gilles Peskinec87af662019-05-15 16:12:22 +02004961 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004962 psa_set_key_usage_flags( &attributes, usage_flags );
4963 psa_set_key_algorithm( &attributes, alg );
4964 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004965 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004966
Darryl Green0c6575a2018-11-07 16:05:30 +00004967 switch( generation_method )
4968 {
4969 case IMPORT_KEY:
4970 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004971 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4972 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004973 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004974
Darryl Green0c6575a2018-11-07 16:05:30 +00004975 case GENERATE_KEY:
4976 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004977 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004978 break;
4979
4980 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004981 {
4982 /* Create base key */
4983 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4984 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4985 psa_set_key_usage_flags( &base_attributes,
4986 PSA_KEY_USAGE_DERIVE );
4987 psa_set_key_algorithm( &base_attributes, derive_alg );
4988 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004989 PSA_ASSERT( psa_import_key( &base_attributes,
4990 data->x, data->len,
4991 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004992 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004993 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004994 PSA_ASSERT( psa_key_derivation_input_key(
4995 &operation,
4996 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004997 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004998 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004999 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005000 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5001 &operation,
5002 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005003 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005004 PSA_ASSERT( psa_destroy_key( base_key ) );
5005 base_key = 0;
5006 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005007 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005008 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005009 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005010
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005011 /* Export the key if permitted by the key policy. */
5012 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5013 {
5014 PSA_ASSERT( psa_export_key( handle,
5015 first_export, export_size,
5016 &first_exported_length ) );
5017 if( generation_method == IMPORT_KEY )
5018 ASSERT_COMPARE( data->x, data->len,
5019 first_export, first_exported_length );
5020 }
Darryl Greend49a4992018-06-18 17:27:26 +01005021
5022 /* Shutdown and restart */
5023 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01005024 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005025
Darryl Greend49a4992018-06-18 17:27:26 +01005026 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005027 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005028 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5029 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5030 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5031 PSA_KEY_LIFETIME_PERSISTENT );
5032 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5033 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5034 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5035 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005036
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005037 /* Export the key again if permitted by the key policy. */
5038 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005039 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005040 PSA_ASSERT( psa_export_key( handle,
5041 second_export, export_size,
5042 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005043 ASSERT_COMPARE( first_export, first_exported_length,
5044 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005045 }
5046
5047 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005048 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005049 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005050
5051exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005052 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005053 mbedtls_free( first_export );
5054 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005055 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005056 psa_destroy_key( base_key );
5057 if( handle == 0 )
5058 {
5059 /* In case there was a test failure after creating the persistent key
5060 * but while it was not open, try to re-open the persistent key
5061 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005062 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005063 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005064 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01005065 mbedtls_psa_crypto_free();
5066}
5067/* END_CASE */