blob: e9fd3f612ca4f74fd702dc50c97c61f95a2a2359 [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 Peskinec7998b72018-11-07 18:45:02 +0100593 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
594 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 Peskine2e46e9c2019-04-11 21:24:55 +0200630 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
631 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
637 status = psa_key_agreement_raw_shared_secret(
638 alg, handle,
639 public_key, public_key_length,
640 output, sizeof( output ), &output_length );
641exit:
642 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200643 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200644 return( status );
645}
646
647static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
648 psa_key_usage_t usage,
649 psa_algorithm_t alg )
650{
651 int ok = 0;
652
653 if( usage & PSA_KEY_USAGE_DERIVE )
654 {
655 /* We need two keys to exercise key agreement. Exercise the
656 * private key against its own public key. */
657 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
658 }
659 ok = 1;
660
661exit:
662 return( ok );
663}
664
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100665static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200666 psa_key_usage_t usage,
667 psa_algorithm_t alg )
668{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200669 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200670 unsigned char output[1];
671 int ok = 0;
672
673 if( usage & PSA_KEY_USAGE_DERIVE )
674 {
675 /* We need two keys to exercise key agreement. Exercise the
676 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200677 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
678 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
679 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200680 output,
681 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200682 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200683 }
684 ok = 1;
685
686exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200687 return( ok );
688}
689
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200690static int is_oid_of_key_type( psa_key_type_t type,
691 const uint8_t *oid, size_t oid_length )
692{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200693 const uint8_t *expected_oid = NULL;
694 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200695#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200696 if( PSA_KEY_TYPE_IS_RSA( type ) )
697 {
698 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
699 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
700 }
701 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200702#endif /* MBEDTLS_RSA_C */
703#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200704 if( PSA_KEY_TYPE_IS_ECC( type ) )
705 {
706 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
707 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
708 }
709 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200710#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200711 {
712 char message[40];
713 mbedtls_snprintf( message, sizeof( message ),
714 "OID not known for key type=0x%08lx",
715 (unsigned long) type );
716 test_fail( message, __LINE__, __FILE__ );
717 return( 0 );
718 }
719
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200720 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200721 return( 1 );
722
723exit:
724 return( 0 );
725}
726
727static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
728 size_t min_bits, size_t max_bits,
729 int must_be_odd )
730{
731 size_t len;
732 size_t actual_bits;
733 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100734 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100735 MBEDTLS_ASN1_INTEGER ),
736 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200737 /* Tolerate a slight departure from DER encoding:
738 * - 0 may be represented by an empty string or a 1-byte string.
739 * - The sign bit may be used as a value bit. */
740 if( ( len == 1 && ( *p )[0] == 0 ) ||
741 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
742 {
743 ++( *p );
744 --len;
745 }
746 if( min_bits == 0 && len == 0 )
747 return( 1 );
748 msb = ( *p )[0];
749 TEST_ASSERT( msb != 0 );
750 actual_bits = 8 * ( len - 1 );
751 while( msb != 0 )
752 {
753 msb >>= 1;
754 ++actual_bits;
755 }
756 TEST_ASSERT( actual_bits >= min_bits );
757 TEST_ASSERT( actual_bits <= max_bits );
758 if( must_be_odd )
759 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
760 *p += len;
761 return( 1 );
762exit:
763 return( 0 );
764}
765
766static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
767 size_t *len,
768 unsigned char n, unsigned char tag )
769{
770 int ret;
771 ret = mbedtls_asn1_get_tag( p, end, len,
772 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
773 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
774 if( ret != 0 )
775 return( ret );
776 end = *p + *len;
777 ret = mbedtls_asn1_get_tag( p, end, len, tag );
778 if( ret != 0 )
779 return( ret );
780 if( *p + *len != end )
781 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
782 return( 0 );
783}
784
785static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
786 uint8_t *exported, size_t exported_length )
787{
788 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100789 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200790 else
791 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200792
793#if defined(MBEDTLS_DES_C)
794 if( type == PSA_KEY_TYPE_DES )
795 {
796 /* Check the parity bits. */
797 unsigned i;
798 for( i = 0; i < bits / 8; i++ )
799 {
800 unsigned bit_count = 0;
801 unsigned m;
802 for( m = 1; m <= 0x100; m <<= 1 )
803 {
804 if( exported[i] & m )
805 ++bit_count;
806 }
807 TEST_ASSERT( bit_count % 2 != 0 );
808 }
809 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200810 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200811#endif
812
813#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
814 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
815 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200816 uint8_t *p = exported;
817 uint8_t *end = exported + exported_length;
818 size_t len;
819 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200820 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200821 * modulus INTEGER, -- n
822 * publicExponent INTEGER, -- e
823 * privateExponent INTEGER, -- d
824 * prime1 INTEGER, -- p
825 * prime2 INTEGER, -- q
826 * exponent1 INTEGER, -- d mod (p-1)
827 * exponent2 INTEGER, -- d mod (q-1)
828 * coefficient INTEGER, -- (inverse of q) mod p
829 * }
830 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100831 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
832 MBEDTLS_ASN1_SEQUENCE |
833 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
834 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200835 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
836 goto exit;
837 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
838 goto exit;
839 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
840 goto exit;
841 /* Require d to be at least half the size of n. */
842 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
843 goto exit;
844 /* Require p and q to be at most half the size of n, rounded up. */
845 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
846 goto exit;
847 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
848 goto exit;
849 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
850 goto exit;
851 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
852 goto exit;
853 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
854 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100855 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100856 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200857 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200858#endif /* MBEDTLS_RSA_C */
859
860#if defined(MBEDTLS_ECP_C)
861 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
862 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100863 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100864 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100865 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200866 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200867#endif /* MBEDTLS_ECP_C */
868
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200869 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
870 {
871 uint8_t *p = exported;
872 uint8_t *end = exported + exported_length;
873 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200874#if defined(MBEDTLS_RSA_C)
875 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
876 {
877 /* RSAPublicKey ::= SEQUENCE {
878 * modulus INTEGER, -- n
879 * publicExponent INTEGER } -- e
880 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100881 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
882 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100883 MBEDTLS_ASN1_CONSTRUCTED ),
884 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100885 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200886 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
887 goto exit;
888 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
889 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100890 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200891 }
892 else
893#endif /* MBEDTLS_RSA_C */
894#if defined(MBEDTLS_ECP_C)
895 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
896 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000897 /* The representation of an ECC public key is:
898 * - The byte 0x04;
899 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
900 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
901 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000902 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100903 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
904 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200905 }
906 else
907#endif /* MBEDTLS_ECP_C */
908 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100909 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200910 mbedtls_snprintf( message, sizeof( message ),
911 "No sanity check for public key type=0x%08lx",
912 (unsigned long) type );
913 test_fail( message, __LINE__, __FILE__ );
914 return( 0 );
915 }
916 }
917 else
918
919 {
920 /* No sanity checks for other types */
921 }
922
923 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200924
925exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200926 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200927}
928
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100929static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200930 psa_key_usage_t usage )
931{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200932 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200933 uint8_t *exported = NULL;
934 size_t exported_size = 0;
935 size_t exported_length = 0;
936 int ok = 0;
937
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200938 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200939
940 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200941 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200942 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100943 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
944 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200945 ok = 1;
946 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200947 }
948
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200949 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
950 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200951 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200952
Gilles Peskine8817f612018-12-18 00:18:46 +0100953 PSA_ASSERT( psa_export_key( handle,
954 exported, exported_size,
955 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200956 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
957 psa_get_key_bits( &attributes ),
958 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200959
960exit:
961 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200962 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200963 return( ok );
964}
965
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100966static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200967{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200968 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200969 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200970 uint8_t *exported = NULL;
971 size_t exported_size = 0;
972 size_t exported_length = 0;
973 int ok = 0;
974
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200975 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
976 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200977 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100978 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100979 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200980 return( 1 );
981 }
982
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200983 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
984 psa_get_key_type( &attributes ) );
985 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
986 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200987 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200988
Gilles Peskine8817f612018-12-18 00:18:46 +0100989 PSA_ASSERT( psa_export_public_key( handle,
990 exported, exported_size,
991 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200992 ok = exported_key_sanity_check( public_type,
993 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200994 exported, exported_length );
995
996exit:
997 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200998 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200999 return( ok );
1000}
1001
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001002/** Do smoke tests on a key.
1003 *
1004 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1005 * sign/verify, or derivation) that is permitted according to \p usage.
1006 * \p usage and \p alg should correspond to the expected policy on the
1007 * key.
1008 *
1009 * Export the key if permitted by \p usage, and check that the output
1010 * looks sensible. If \p usage forbids export, check that
1011 * \p psa_export_key correctly rejects the attempt. If the key is
1012 * asymmetric, also check \p psa_export_public_key.
1013 *
1014 * If the key fails the tests, this function calls the test framework's
1015 * `test_fail` function and returns false. Otherwise this function returns
1016 * true. Therefore it should be used as follows:
1017 * ```
1018 * if( ! exercise_key( ... ) ) goto exit;
1019 * ```
1020 *
1021 * \param handle The key to exercise. It should be capable of performing
1022 * \p alg.
1023 * \param usage The usage flags to assume.
1024 * \param alg The algorithm to exercise.
1025 *
1026 * \retval 0 The key failed the smoke tests.
1027 * \retval 1 The key passed the smoke tests.
1028 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001029static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001030 psa_key_usage_t usage,
1031 psa_algorithm_t alg )
1032{
1033 int ok;
1034 if( alg == 0 )
1035 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1036 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001037 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001038 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001039 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001040 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001041 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001042 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001043 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001044 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001045 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001046 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001047 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001048 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1049 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001050 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001051 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001052 else
1053 {
1054 char message[40];
1055 mbedtls_snprintf( message, sizeof( message ),
1056 "No code to exercise alg=0x%08lx",
1057 (unsigned long) alg );
1058 test_fail( message, __LINE__, __FILE__ );
1059 ok = 0;
1060 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001061
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001062 ok = ok && exercise_export_key( handle, usage );
1063 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001064
Gilles Peskine02b75072018-07-01 22:31:34 +02001065 return( ok );
1066}
1067
Gilles Peskine10df3412018-10-25 22:35:43 +02001068static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1069 psa_algorithm_t alg )
1070{
1071 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1072 {
1073 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1074 PSA_KEY_USAGE_VERIFY :
1075 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1076 }
1077 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1078 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1079 {
1080 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1081 PSA_KEY_USAGE_ENCRYPT :
1082 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1083 }
1084 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1085 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1086 {
1087 return( PSA_KEY_USAGE_DERIVE );
1088 }
1089 else
1090 {
1091 return( 0 );
1092 }
1093
1094}
Darryl Green0c6575a2018-11-07 16:05:30 +00001095
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001096static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1097{
1098 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1099 uint8_t buffer[1];
1100 size_t length;
1101 int ok = 0;
1102
Gilles Peskinec87af662019-05-15 16:12:22 +02001103 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001104 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1105 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1106 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1107 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1108 PSA_ERROR_INVALID_HANDLE );
1109 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001110 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001111 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1112 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1113 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1114 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1115
1116 TEST_EQUAL( psa_export_key( handle,
1117 buffer, sizeof( buffer ), &length ),
1118 PSA_ERROR_INVALID_HANDLE );
1119 TEST_EQUAL( psa_export_public_key( handle,
1120 buffer, sizeof( buffer ), &length ),
1121 PSA_ERROR_INVALID_HANDLE );
1122
1123 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1124 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1125
1126 ok = 1;
1127
1128exit:
1129 psa_reset_key_attributes( &attributes );
1130 return( ok );
1131}
1132
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001133/* An overapproximation of the amount of storage needed for a key of the
1134 * given type and with the given content. The API doesn't make it easy
1135 * to find a good value for the size. The current implementation doesn't
1136 * care about the value anyway. */
1137#define KEY_BITS_FROM_DATA( type, data ) \
1138 ( data )->len
1139
Darryl Green0c6575a2018-11-07 16:05:30 +00001140typedef enum {
1141 IMPORT_KEY = 0,
1142 GENERATE_KEY = 1,
1143 DERIVE_KEY = 2
1144} generate_method;
1145
Gilles Peskinee59236f2018-01-27 23:32:46 +01001146/* END_HEADER */
1147
1148/* BEGIN_DEPENDENCIES
1149 * depends_on:MBEDTLS_PSA_CRYPTO_C
1150 * END_DEPENDENCIES
1151 */
1152
1153/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001154void static_checks( )
1155{
1156 size_t max_truncated_mac_size =
1157 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1158
1159 /* Check that the length for a truncated MAC always fits in the algorithm
1160 * encoding. The shifted mask is the maximum truncated value. The
1161 * untruncated algorithm may be one byte larger. */
1162 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1163}
1164/* END_CASE */
1165
1166/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001167void attributes_set_get( int id_arg, int lifetime_arg,
1168 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001169 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001170{
Gilles Peskine4747d192019-04-17 15:05:45 +02001171 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001172 psa_key_id_t id = id_arg;
1173 psa_key_lifetime_t lifetime = lifetime_arg;
1174 psa_key_usage_t usage_flags = usage_flags_arg;
1175 psa_algorithm_t alg = alg_arg;
1176 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001177 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001178
1179 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1182 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1183 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001184 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001185
Gilles Peskinec87af662019-05-15 16:12:22 +02001186 psa_set_key_id( &attributes, id );
1187 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001188 psa_set_key_usage_flags( &attributes, usage_flags );
1189 psa_set_key_algorithm( &attributes, alg );
1190 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001191 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001192
1193 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1194 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1195 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1196 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1197 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001198 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001199
1200 psa_reset_key_attributes( &attributes );
1201
1202 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1203 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1204 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1205 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1206 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001207 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001208}
1209/* END_CASE */
1210
1211/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001212void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1213 int expected_id_arg, int expected_lifetime_arg )
1214{
1215 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1216 psa_key_id_t id1 = id1_arg;
1217 psa_key_lifetime_t lifetime = lifetime_arg;
1218 psa_key_id_t id2 = id2_arg;
1219 psa_key_id_t expected_id = expected_id_arg;
1220 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1221
1222 if( id1_arg != -1 )
1223 psa_set_key_id( &attributes, id1 );
1224 if( lifetime_arg != -1 )
1225 psa_set_key_lifetime( &attributes, lifetime );
1226 if( id2_arg != -1 )
1227 psa_set_key_id( &attributes, id2 );
1228
1229 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1230 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1231}
1232/* END_CASE */
1233
1234/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001235void import( data_t *data, int type_arg,
1236 int attr_bits_arg,
1237 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001238{
1239 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1240 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001241 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001242 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001243 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001244 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001245 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001246
Gilles Peskine8817f612018-12-18 00:18:46 +01001247 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001248
Gilles Peskine4747d192019-04-17 15:05:45 +02001249 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001250 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001251 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001252 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001253 if( status != PSA_SUCCESS )
1254 goto exit;
1255
1256 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1257 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001258 if( attr_bits != 0 )
1259 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001260
1261 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001262 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001263
1264exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001265 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001266 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001267 mbedtls_psa_crypto_free( );
1268}
1269/* END_CASE */
1270
1271/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001272void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1273{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001274 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001275 size_t bits = bits_arg;
1276 psa_status_t expected_status = expected_status_arg;
1277 psa_status_t status;
1278 psa_key_type_t type =
1279 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1280 size_t buffer_size = /* Slight overapproximations */
1281 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001282 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001283 unsigned char *p;
1284 int ret;
1285 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001286 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001287
Gilles Peskine8817f612018-12-18 00:18:46 +01001288 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001289 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001290
1291 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1292 bits, keypair ) ) >= 0 );
1293 length = ret;
1294
1295 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001296 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001297 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001298 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001299 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001300 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001301
1302exit:
1303 mbedtls_free( buffer );
1304 mbedtls_psa_crypto_free( );
1305}
1306/* END_CASE */
1307
1308/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001309void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001310 int type_arg,
1311 int alg_arg,
1312 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001313 int expected_bits,
1314 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001315 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001316 int canonical_input )
1317{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001318 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001319 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001320 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001321 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001322 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001323 unsigned char *exported = NULL;
1324 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001325 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001326 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001327 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001328 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001329 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001330
Moran Pekercb088e72018-07-17 17:36:59 +03001331 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001332 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001333 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001334 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001335 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001336
Gilles Peskine4747d192019-04-17 15:05:45 +02001337 psa_set_key_usage_flags( &attributes, usage_arg );
1338 psa_set_key_algorithm( &attributes, alg );
1339 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001340
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001341 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001342 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001343
1344 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001345 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1346 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1347 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001348
1349 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001350 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001351 exported, export_size,
1352 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001353 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001354
1355 /* The exported length must be set by psa_export_key() to a value between 0
1356 * and export_size. On errors, the exported length must be 0. */
1357 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1358 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1359 TEST_ASSERT( exported_length <= export_size );
1360
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001361 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001362 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001363 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001364 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001365 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001366 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001367 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001368
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001369 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001370 goto exit;
1371
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001372 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001373 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001374 else
1375 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001376 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001377 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1378 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001379 PSA_ASSERT( psa_export_key( handle2,
1380 reexported,
1381 export_size,
1382 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001383 ASSERT_COMPARE( exported, exported_length,
1384 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001385 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001386 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001387 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001388
1389destroy:
1390 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001391 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001392 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001393
1394exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001395 mbedtls_free( exported );
1396 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001397 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001398 mbedtls_psa_crypto_free( );
1399}
1400/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001401
Moran Pekerf709f4a2018-06-06 17:26:04 +03001402/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001403void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001404{
Gilles Peskine8817f612018-12-18 00:18:46 +01001405 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001406 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001407
1408exit:
1409 mbedtls_psa_crypto_free( );
1410}
1411/* END_CASE */
1412
1413/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001414void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001415 int type_arg,
1416 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001417 int export_size_delta,
1418 int expected_export_status_arg,
1419 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001420{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001421 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001422 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001423 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001424 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001425 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001426 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001427 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001428 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001429 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001430
Gilles Peskine8817f612018-12-18 00:18:46 +01001431 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001432
Gilles Peskine4747d192019-04-17 15:05:45 +02001433 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1434 psa_set_key_algorithm( &attributes, alg );
1435 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001436
1437 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001438 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001439
Gilles Peskine49c25912018-10-29 15:15:31 +01001440 /* Export the public key */
1441 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001442 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001443 exported, export_size,
1444 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001445 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001446 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001447 {
1448 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1449 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001450 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1451 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001452 TEST_ASSERT( expected_public_key->len <=
1453 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001454 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1455 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001456 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001457
1458exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001459 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001460 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001461 psa_reset_key_attributes( &attributes );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001462 mbedtls_psa_crypto_free( );
1463}
1464/* END_CASE */
1465
Gilles Peskine20035e32018-02-03 22:44:14 +01001466/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001467void import_and_exercise_key( data_t *data,
1468 int type_arg,
1469 int bits_arg,
1470 int alg_arg )
1471{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001472 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001473 psa_key_type_t type = type_arg;
1474 size_t bits = bits_arg;
1475 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001476 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001477 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001478 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001479
Gilles Peskine8817f612018-12-18 00:18:46 +01001480 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001481
Gilles Peskine4747d192019-04-17 15:05:45 +02001482 psa_set_key_usage_flags( &attributes, usage );
1483 psa_set_key_algorithm( &attributes, alg );
1484 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001485
1486 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001487 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001488
1489 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001490 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1491 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1492 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001493
1494 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001495 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001496 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001497
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001498 PSA_ASSERT( psa_destroy_key( handle ) );
1499 test_operations_on_invalid_handle( handle );
1500
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001501exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001502 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001503 psa_reset_key_attributes( &got_attributes );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001504 mbedtls_psa_crypto_free( );
1505}
1506/* END_CASE */
1507
1508/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001509void key_policy( int usage_arg, int alg_arg )
1510{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001511 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001512 psa_algorithm_t alg = alg_arg;
1513 psa_key_usage_t usage = usage_arg;
1514 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1515 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001516 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001517
1518 memset( key, 0x2a, sizeof( key ) );
1519
Gilles Peskine8817f612018-12-18 00:18:46 +01001520 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001521
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001522 psa_set_key_usage_flags( &attributes, usage );
1523 psa_set_key_algorithm( &attributes, alg );
1524 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001525
Gilles Peskine73676cb2019-05-15 20:15:10 +02001526 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001527
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001528 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1529 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1530 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1531 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001532
1533exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001534 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001535 psa_reset_key_attributes( &attributes );
Gilles Peskined5b33222018-06-18 22:20:03 +02001536 mbedtls_psa_crypto_free( );
1537}
1538/* END_CASE */
1539
1540/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001541void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001542{
1543 /* Test each valid way of initializing the object, except for `= {0}`, as
1544 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1545 * though it's OK by the C standard. We could test for this, but we'd need
1546 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001547 psa_key_attributes_t func = psa_key_attributes_init( );
1548 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1549 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001550
1551 memset( &zero, 0, sizeof( zero ) );
1552
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001553 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1554 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1555 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001556
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001557 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1558 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1559 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1560
1561 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1562 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1563 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1564
1565 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1566 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1567 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1568
1569 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1570 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1571 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001572}
1573/* END_CASE */
1574
1575/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001576void mac_key_policy( int policy_usage,
1577 int policy_alg,
1578 int key_type,
1579 data_t *key_data,
1580 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001581{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001582 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001583 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001584 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001585 psa_status_t status;
1586 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001587
Gilles Peskine8817f612018-12-18 00:18:46 +01001588 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001589
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001590 psa_set_key_usage_flags( &attributes, policy_usage );
1591 psa_set_key_algorithm( &attributes, policy_alg );
1592 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001593
Gilles Peskine049c7532019-05-15 20:22:09 +02001594 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1595 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001596
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001597 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001598 if( policy_alg == exercise_alg &&
1599 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001600 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001601 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001602 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001603 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001604
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001605 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001606 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001607 if( policy_alg == exercise_alg &&
1608 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001609 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001610 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001611 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001612
1613exit:
1614 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001615 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001616 mbedtls_psa_crypto_free( );
1617}
1618/* END_CASE */
1619
1620/* BEGIN_CASE */
1621void cipher_key_policy( int policy_usage,
1622 int policy_alg,
1623 int key_type,
1624 data_t *key_data,
1625 int exercise_alg )
1626{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001627 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001628 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001629 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001630 psa_status_t status;
1631
Gilles Peskine8817f612018-12-18 00:18:46 +01001632 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001633
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001634 psa_set_key_usage_flags( &attributes, policy_usage );
1635 psa_set_key_algorithm( &attributes, policy_alg );
1636 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001637
Gilles Peskine049c7532019-05-15 20:22:09 +02001638 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1639 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001640
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001641 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001642 if( policy_alg == exercise_alg &&
1643 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001644 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001645 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001646 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001647 psa_cipher_abort( &operation );
1648
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001649 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001650 if( policy_alg == exercise_alg &&
1651 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001652 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001653 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001654 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001655
1656exit:
1657 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001658 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001659 mbedtls_psa_crypto_free( );
1660}
1661/* END_CASE */
1662
1663/* BEGIN_CASE */
1664void aead_key_policy( int policy_usage,
1665 int policy_alg,
1666 int key_type,
1667 data_t *key_data,
1668 int nonce_length_arg,
1669 int tag_length_arg,
1670 int exercise_alg )
1671{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001672 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001673 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001674 psa_status_t status;
1675 unsigned char nonce[16] = {0};
1676 size_t nonce_length = nonce_length_arg;
1677 unsigned char tag[16];
1678 size_t tag_length = tag_length_arg;
1679 size_t output_length;
1680
1681 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1682 TEST_ASSERT( tag_length <= sizeof( tag ) );
1683
Gilles Peskine8817f612018-12-18 00:18:46 +01001684 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001685
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001686 psa_set_key_usage_flags( &attributes, policy_usage );
1687 psa_set_key_algorithm( &attributes, policy_alg );
1688 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001689
Gilles Peskine049c7532019-05-15 20:22:09 +02001690 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1691 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001693 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001694 nonce, nonce_length,
1695 NULL, 0,
1696 NULL, 0,
1697 tag, tag_length,
1698 &output_length );
1699 if( policy_alg == exercise_alg &&
1700 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001701 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001702 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001703 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001704
1705 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001706 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001707 nonce, nonce_length,
1708 NULL, 0,
1709 tag, tag_length,
1710 NULL, 0,
1711 &output_length );
1712 if( policy_alg == exercise_alg &&
1713 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001714 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001715 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001716 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001717
1718exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001719 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001720 mbedtls_psa_crypto_free( );
1721}
1722/* END_CASE */
1723
1724/* BEGIN_CASE */
1725void asymmetric_encryption_key_policy( int policy_usage,
1726 int policy_alg,
1727 int key_type,
1728 data_t *key_data,
1729 int exercise_alg )
1730{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001731 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001732 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001733 psa_status_t status;
1734 size_t key_bits;
1735 size_t buffer_length;
1736 unsigned char *buffer = NULL;
1737 size_t output_length;
1738
Gilles Peskine8817f612018-12-18 00:18:46 +01001739 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001740
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001741 psa_set_key_usage_flags( &attributes, policy_usage );
1742 psa_set_key_algorithm( &attributes, policy_alg );
1743 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001744
Gilles Peskine049c7532019-05-15 20:22:09 +02001745 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1746 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001747
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001748 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1749 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001750 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1751 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001752 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001753
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001754 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001755 NULL, 0,
1756 NULL, 0,
1757 buffer, buffer_length,
1758 &output_length );
1759 if( policy_alg == exercise_alg &&
1760 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001761 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001763 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001764
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001765 if( buffer_length != 0 )
1766 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001767 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001768 buffer, buffer_length,
1769 NULL, 0,
1770 buffer, buffer_length,
1771 &output_length );
1772 if( policy_alg == exercise_alg &&
1773 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001774 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001775 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001776 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001777
1778exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001779 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001780 psa_reset_key_attributes( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001781 mbedtls_psa_crypto_free( );
1782 mbedtls_free( buffer );
1783}
1784/* END_CASE */
1785
1786/* BEGIN_CASE */
1787void asymmetric_signature_key_policy( int policy_usage,
1788 int policy_alg,
1789 int key_type,
1790 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001791 int exercise_alg,
1792 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001793{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001794 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001795 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001797 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1798 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1799 * compatible with the policy and `payload_length_arg` is supposed to be
1800 * a valid input length to sign. If `payload_length_arg <= 0`,
1801 * `exercise_alg` is supposed to be forbidden by the policy. */
1802 int compatible_alg = payload_length_arg > 0;
1803 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001804 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1805 size_t signature_length;
1806
Gilles Peskine8817f612018-12-18 00:18:46 +01001807 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001808
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001809 psa_set_key_usage_flags( &attributes, policy_usage );
1810 psa_set_key_algorithm( &attributes, policy_alg );
1811 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001812
Gilles Peskine049c7532019-05-15 20:22:09 +02001813 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1814 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001815
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001816 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001817 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001818 signature, sizeof( signature ),
1819 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001820 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001821 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001823 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001824
1825 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001826 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001827 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001828 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001829 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001830 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001831 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001832 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001833
1834exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001835 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001836 mbedtls_psa_crypto_free( );
1837}
1838/* END_CASE */
1839
1840/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001841void derive_key_policy( int policy_usage,
1842 int policy_alg,
1843 int key_type,
1844 data_t *key_data,
1845 int exercise_alg )
1846{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001847 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001848 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001849 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001850 psa_status_t status;
1851
Gilles Peskine8817f612018-12-18 00:18:46 +01001852 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001853
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001854 psa_set_key_usage_flags( &attributes, policy_usage );
1855 psa_set_key_algorithm( &attributes, policy_alg );
1856 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001857
Gilles Peskine049c7532019-05-15 20:22:09 +02001858 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1859 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001860
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001861 status = psa_key_derivation( &operation, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001862 exercise_alg,
1863 NULL, 0,
1864 NULL, 0,
1865 1 );
1866 if( policy_alg == exercise_alg &&
1867 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001868 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001869 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001870 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001871
1872exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001873 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001874 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001875 mbedtls_psa_crypto_free( );
1876}
1877/* END_CASE */
1878
1879/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001880void agreement_key_policy( int policy_usage,
1881 int policy_alg,
1882 int key_type_arg,
1883 data_t *key_data,
1884 int exercise_alg )
1885{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001886 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001887 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001888 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001889 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001890 psa_status_t status;
1891
Gilles Peskine8817f612018-12-18 00:18:46 +01001892 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001893
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001894 psa_set_key_usage_flags( &attributes, policy_usage );
1895 psa_set_key_algorithm( &attributes, policy_alg );
1896 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001897
Gilles Peskine049c7532019-05-15 20:22:09 +02001898 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1899 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001900
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001901 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1902 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001903
Gilles Peskine01d718c2018-09-18 12:01:02 +02001904 if( policy_alg == exercise_alg &&
1905 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001906 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001907 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001908 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001909
1910exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001911 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001912 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001913 mbedtls_psa_crypto_free( );
1914}
1915/* END_CASE */
1916
1917/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001918void raw_agreement_key_policy( int policy_usage,
1919 int policy_alg,
1920 int key_type_arg,
1921 data_t *key_data,
1922 int exercise_alg )
1923{
1924 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001925 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001926 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001927 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001928 psa_status_t status;
1929
1930 PSA_ASSERT( psa_crypto_init( ) );
1931
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001932 psa_set_key_usage_flags( &attributes, policy_usage );
1933 psa_set_key_algorithm( &attributes, policy_alg );
1934 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001935
Gilles Peskine049c7532019-05-15 20:22:09 +02001936 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1937 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001938
1939 status = raw_key_agreement_with_self( exercise_alg, handle );
1940
1941 if( policy_alg == exercise_alg &&
1942 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1943 PSA_ASSERT( status );
1944 else
1945 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1946
1947exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001948 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001949 psa_destroy_key( handle );
1950 mbedtls_psa_crypto_free( );
1951}
1952/* END_CASE */
1953
1954/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02001955void copy_success( int source_usage_arg, int source_alg_arg,
1956 int type_arg, data_t *material,
1957 int copy_attributes,
1958 int target_usage_arg, int target_alg_arg,
1959 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001960{
Gilles Peskineca25db92019-04-19 11:43:08 +02001961 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1962 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001963 psa_key_usage_t expected_usage = expected_usage_arg;
1964 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001965 psa_key_handle_t source_handle = 0;
1966 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001967 uint8_t *export_buffer = NULL;
1968
Gilles Peskine57ab7212019-01-28 13:03:09 +01001969 PSA_ASSERT( psa_crypto_init( ) );
1970
Gilles Peskineca25db92019-04-19 11:43:08 +02001971 /* Prepare the source key. */
1972 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1973 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1974 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02001975 PSA_ASSERT( psa_import_key( &source_attributes,
1976 material->x, material->len,
1977 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001978 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001979
Gilles Peskineca25db92019-04-19 11:43:08 +02001980 /* Prepare the target attributes. */
1981 if( copy_attributes )
1982 target_attributes = source_attributes;
1983 if( target_usage_arg != -1 )
1984 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1985 if( target_alg_arg != -1 )
1986 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001987
1988 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02001989 PSA_ASSERT( psa_copy_key( source_handle,
1990 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001991
1992 /* Destroy the source to ensure that this doesn't affect the target. */
1993 PSA_ASSERT( psa_destroy_key( source_handle ) );
1994
1995 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001996 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1997 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1998 psa_get_key_type( &target_attributes ) );
1999 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2000 psa_get_key_bits( &target_attributes ) );
2001 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2002 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002003 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2004 {
2005 size_t length;
2006 ASSERT_ALLOC( export_buffer, material->len );
2007 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2008 material->len, &length ) );
2009 ASSERT_COMPARE( material->x, material->len,
2010 export_buffer, length );
2011 }
2012 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2013 goto exit;
2014
2015 PSA_ASSERT( psa_close_key( target_handle ) );
2016
2017exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002018 psa_reset_key_attributes( &source_attributes );
2019 psa_reset_key_attributes( &target_attributes );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002020 mbedtls_psa_crypto_free( );
2021 mbedtls_free( export_buffer );
2022}
2023/* END_CASE */
2024
2025/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02002026void copy_fail( int source_usage_arg, int source_alg_arg,
2027 int type_arg, data_t *material,
2028 int target_type_arg, int target_bits_arg,
2029 int target_usage_arg, int target_alg_arg,
2030 int expected_status_arg )
2031{
2032 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2033 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2034 psa_key_handle_t source_handle = 0;
2035 psa_key_handle_t target_handle = 0;
2036
2037 PSA_ASSERT( psa_crypto_init( ) );
2038
2039 /* Prepare the source key. */
2040 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2041 psa_set_key_algorithm( &source_attributes, source_alg_arg );
2042 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002043 PSA_ASSERT( psa_import_key( &source_attributes,
2044 material->x, material->len,
2045 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002046
2047 /* Prepare the target attributes. */
2048 psa_set_key_type( &target_attributes, target_type_arg );
2049 psa_set_key_bits( &target_attributes, target_bits_arg );
2050 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2051 psa_set_key_algorithm( &target_attributes, target_alg_arg );
2052
2053 /* Try to copy the key. */
2054 TEST_EQUAL( psa_copy_key( source_handle,
2055 &target_attributes, &target_handle ),
2056 expected_status_arg );
2057exit:
2058 psa_reset_key_attributes( &source_attributes );
2059 psa_reset_key_attributes( &target_attributes );
2060 mbedtls_psa_crypto_free( );
2061}
2062/* END_CASE */
2063
2064/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002065void hash_operation_init( )
2066{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002067 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002068 /* Test each valid way of initializing the object, except for `= {0}`, as
2069 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2070 * though it's OK by the C standard. We could test for this, but we'd need
2071 * to supress the Clang warning for the test. */
2072 psa_hash_operation_t func = psa_hash_operation_init( );
2073 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2074 psa_hash_operation_t zero;
2075
2076 memset( &zero, 0, sizeof( zero ) );
2077
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002078 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002079 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2080 PSA_ERROR_BAD_STATE );
2081 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2082 PSA_ERROR_BAD_STATE );
2083 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2084 PSA_ERROR_BAD_STATE );
2085
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002086 /* A default hash operation should be abortable without error. */
2087 PSA_ASSERT( psa_hash_abort( &func ) );
2088 PSA_ASSERT( psa_hash_abort( &init ) );
2089 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002090}
2091/* END_CASE */
2092
2093/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002094void hash_setup( int alg_arg,
2095 int expected_status_arg )
2096{
2097 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002098 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002099 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002100 psa_status_t status;
2101
Gilles Peskine8817f612018-12-18 00:18:46 +01002102 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002103
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002104 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002105 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002106
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002107 /* Whether setup succeeded or failed, abort must succeed. */
2108 PSA_ASSERT( psa_hash_abort( &operation ) );
2109
2110 /* If setup failed, reproduce the failure, so as to
2111 * test the resulting state of the operation object. */
2112 if( status != PSA_SUCCESS )
2113 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2114
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002115 /* Now the operation object should be reusable. */
2116#if defined(KNOWN_SUPPORTED_HASH_ALG)
2117 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2118 PSA_ASSERT( psa_hash_abort( &operation ) );
2119#endif
2120
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002121exit:
2122 mbedtls_psa_crypto_free( );
2123}
2124/* END_CASE */
2125
2126/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002127void hash_bad_order( )
2128{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002129 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002130 unsigned char input[] = "";
2131 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002132 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002133 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2134 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2135 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002136 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002137 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002138 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002139
Gilles Peskine8817f612018-12-18 00:18:46 +01002140 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002141
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002142 /* Call setup twice in a row. */
2143 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2144 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2145 PSA_ERROR_BAD_STATE );
2146 PSA_ASSERT( psa_hash_abort( &operation ) );
2147
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002148 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002149 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002150 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002151 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002152
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002153 /* Call update after finish. */
2154 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2155 PSA_ASSERT( psa_hash_finish( &operation,
2156 hash, sizeof( hash ), &hash_len ) );
2157 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002158 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002159 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002160
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002161 /* Call verify without calling setup beforehand. */
2162 TEST_EQUAL( psa_hash_verify( &operation,
2163 valid_hash, sizeof( valid_hash ) ),
2164 PSA_ERROR_BAD_STATE );
2165 PSA_ASSERT( psa_hash_abort( &operation ) );
2166
2167 /* Call verify after finish. */
2168 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2169 PSA_ASSERT( psa_hash_finish( &operation,
2170 hash, sizeof( hash ), &hash_len ) );
2171 TEST_EQUAL( psa_hash_verify( &operation,
2172 valid_hash, sizeof( valid_hash ) ),
2173 PSA_ERROR_BAD_STATE );
2174 PSA_ASSERT( psa_hash_abort( &operation ) );
2175
2176 /* Call verify twice in a row. */
2177 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2178 PSA_ASSERT( psa_hash_verify( &operation,
2179 valid_hash, sizeof( valid_hash ) ) );
2180 TEST_EQUAL( psa_hash_verify( &operation,
2181 valid_hash, sizeof( valid_hash ) ),
2182 PSA_ERROR_BAD_STATE );
2183 PSA_ASSERT( psa_hash_abort( &operation ) );
2184
2185 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002186 TEST_EQUAL( psa_hash_finish( &operation,
2187 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002188 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002189 PSA_ASSERT( psa_hash_abort( &operation ) );
2190
2191 /* Call finish twice in a row. */
2192 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2193 PSA_ASSERT( psa_hash_finish( &operation,
2194 hash, sizeof( hash ), &hash_len ) );
2195 TEST_EQUAL( psa_hash_finish( &operation,
2196 hash, sizeof( hash ), &hash_len ),
2197 PSA_ERROR_BAD_STATE );
2198 PSA_ASSERT( psa_hash_abort( &operation ) );
2199
2200 /* Call finish after calling verify. */
2201 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2202 PSA_ASSERT( psa_hash_verify( &operation,
2203 valid_hash, sizeof( valid_hash ) ) );
2204 TEST_EQUAL( psa_hash_finish( &operation,
2205 hash, sizeof( hash ), &hash_len ),
2206 PSA_ERROR_BAD_STATE );
2207 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002208
2209exit:
2210 mbedtls_psa_crypto_free( );
2211}
2212/* END_CASE */
2213
itayzafrir27e69452018-11-01 14:26:34 +02002214/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2215void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002216{
2217 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002218 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2219 * appended to it */
2220 unsigned char hash[] = {
2221 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2222 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2223 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002224 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002225 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002226
Gilles Peskine8817f612018-12-18 00:18:46 +01002227 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002228
itayzafrir27e69452018-11-01 14:26:34 +02002229 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002230 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002231 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002232 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002233
itayzafrir27e69452018-11-01 14:26:34 +02002234 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002235 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002236 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002237 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002238
itayzafrir27e69452018-11-01 14:26:34 +02002239 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002240 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002241 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002242 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002243
itayzafrirec93d302018-10-18 18:01:10 +03002244exit:
2245 mbedtls_psa_crypto_free( );
2246}
2247/* END_CASE */
2248
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002249/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2250void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002251{
2252 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002253 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002254 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002255 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002256 size_t hash_len;
2257
Gilles Peskine8817f612018-12-18 00:18:46 +01002258 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002259
itayzafrir58028322018-10-25 10:22:01 +03002260 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002261 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002262 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002263 hash, expected_size - 1, &hash_len ),
2264 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002265
2266exit:
2267 mbedtls_psa_crypto_free( );
2268}
2269/* END_CASE */
2270
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002271/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2272void hash_clone_source_state( )
2273{
2274 psa_algorithm_t alg = PSA_ALG_SHA_256;
2275 unsigned char hash[PSA_HASH_MAX_SIZE];
2276 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2277 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2278 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2279 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2280 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2281 size_t hash_len;
2282
2283 PSA_ASSERT( psa_crypto_init( ) );
2284 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2285
2286 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2287 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2288 PSA_ASSERT( psa_hash_finish( &op_finished,
2289 hash, sizeof( hash ), &hash_len ) );
2290 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2291 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2292
2293 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2294 PSA_ERROR_BAD_STATE );
2295
2296 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2297 PSA_ASSERT( psa_hash_finish( &op_init,
2298 hash, sizeof( hash ), &hash_len ) );
2299 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2300 PSA_ASSERT( psa_hash_finish( &op_finished,
2301 hash, sizeof( hash ), &hash_len ) );
2302 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2303 PSA_ASSERT( psa_hash_finish( &op_aborted,
2304 hash, sizeof( hash ), &hash_len ) );
2305
2306exit:
2307 psa_hash_abort( &op_source );
2308 psa_hash_abort( &op_init );
2309 psa_hash_abort( &op_setup );
2310 psa_hash_abort( &op_finished );
2311 psa_hash_abort( &op_aborted );
2312 mbedtls_psa_crypto_free( );
2313}
2314/* END_CASE */
2315
2316/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2317void hash_clone_target_state( )
2318{
2319 psa_algorithm_t alg = PSA_ALG_SHA_256;
2320 unsigned char hash[PSA_HASH_MAX_SIZE];
2321 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2322 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2323 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2324 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2325 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2326 size_t hash_len;
2327
2328 PSA_ASSERT( psa_crypto_init( ) );
2329
2330 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2331 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2332 PSA_ASSERT( psa_hash_finish( &op_finished,
2333 hash, sizeof( hash ), &hash_len ) );
2334 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2335 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2336
2337 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2338 PSA_ASSERT( psa_hash_finish( &op_target,
2339 hash, sizeof( hash ), &hash_len ) );
2340
2341 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2342 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2343 PSA_ERROR_BAD_STATE );
2344 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2345 PSA_ERROR_BAD_STATE );
2346
2347exit:
2348 psa_hash_abort( &op_target );
2349 psa_hash_abort( &op_init );
2350 psa_hash_abort( &op_setup );
2351 psa_hash_abort( &op_finished );
2352 psa_hash_abort( &op_aborted );
2353 mbedtls_psa_crypto_free( );
2354}
2355/* END_CASE */
2356
itayzafrir58028322018-10-25 10:22:01 +03002357/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002358void mac_operation_init( )
2359{
Jaeden Amero252ef282019-02-15 14:05:35 +00002360 const uint8_t input[1] = { 0 };
2361
Jaeden Amero769ce272019-01-04 11:48:03 +00002362 /* Test each valid way of initializing the object, except for `= {0}`, as
2363 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2364 * though it's OK by the C standard. We could test for this, but we'd need
2365 * to supress the Clang warning for the test. */
2366 psa_mac_operation_t func = psa_mac_operation_init( );
2367 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2368 psa_mac_operation_t zero;
2369
2370 memset( &zero, 0, sizeof( zero ) );
2371
Jaeden Amero252ef282019-02-15 14:05:35 +00002372 /* A freshly-initialized MAC operation should not be usable. */
2373 TEST_EQUAL( psa_mac_update( &func,
2374 input, sizeof( input ) ),
2375 PSA_ERROR_BAD_STATE );
2376 TEST_EQUAL( psa_mac_update( &init,
2377 input, sizeof( input ) ),
2378 PSA_ERROR_BAD_STATE );
2379 TEST_EQUAL( psa_mac_update( &zero,
2380 input, sizeof( input ) ),
2381 PSA_ERROR_BAD_STATE );
2382
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002383 /* A default MAC operation should be abortable without error. */
2384 PSA_ASSERT( psa_mac_abort( &func ) );
2385 PSA_ASSERT( psa_mac_abort( &init ) );
2386 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002387}
2388/* END_CASE */
2389
2390/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002391void mac_setup( int key_type_arg,
2392 data_t *key,
2393 int alg_arg,
2394 int expected_status_arg )
2395{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002396 psa_key_type_t key_type = key_type_arg;
2397 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002398 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002399 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002400 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2401#if defined(KNOWN_SUPPORTED_MAC_ALG)
2402 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2403#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002404
Gilles Peskine8817f612018-12-18 00:18:46 +01002405 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002406
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002407 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2408 &operation, &status ) )
2409 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002410 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002411
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002412 /* The operation object should be reusable. */
2413#if defined(KNOWN_SUPPORTED_MAC_ALG)
2414 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2415 smoke_test_key_data,
2416 sizeof( smoke_test_key_data ),
2417 KNOWN_SUPPORTED_MAC_ALG,
2418 &operation, &status ) )
2419 goto exit;
2420 TEST_EQUAL( status, PSA_SUCCESS );
2421#endif
2422
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002423exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002424 mbedtls_psa_crypto_free( );
2425}
2426/* END_CASE */
2427
2428/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002429void mac_bad_order( )
2430{
2431 psa_key_handle_t handle = 0;
2432 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2433 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2434 const uint8_t key[] = {
2435 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2436 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2437 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002438 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002439 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2440 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2441 size_t sign_mac_length = 0;
2442 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2443 const uint8_t verify_mac[] = {
2444 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2445 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2446 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2447
2448 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002449 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2450 psa_set_key_algorithm( &attributes, alg );
2451 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002452
Gilles Peskine73676cb2019-05-15 20:15:10 +02002453 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002454
Jaeden Amero252ef282019-02-15 14:05:35 +00002455 /* Call update without calling setup beforehand. */
2456 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2457 PSA_ERROR_BAD_STATE );
2458 PSA_ASSERT( psa_mac_abort( &operation ) );
2459
2460 /* Call sign finish without calling setup beforehand. */
2461 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2462 &sign_mac_length),
2463 PSA_ERROR_BAD_STATE );
2464 PSA_ASSERT( psa_mac_abort( &operation ) );
2465
2466 /* Call verify finish without calling setup beforehand. */
2467 TEST_EQUAL( psa_mac_verify_finish( &operation,
2468 verify_mac, sizeof( verify_mac ) ),
2469 PSA_ERROR_BAD_STATE );
2470 PSA_ASSERT( psa_mac_abort( &operation ) );
2471
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002472 /* Call setup twice in a row. */
2473 PSA_ASSERT( psa_mac_sign_setup( &operation,
2474 handle, alg ) );
2475 TEST_EQUAL( psa_mac_sign_setup( &operation,
2476 handle, alg ),
2477 PSA_ERROR_BAD_STATE );
2478 PSA_ASSERT( psa_mac_abort( &operation ) );
2479
Jaeden Amero252ef282019-02-15 14:05:35 +00002480 /* Call update after sign finish. */
2481 PSA_ASSERT( psa_mac_sign_setup( &operation,
2482 handle, alg ) );
2483 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2484 PSA_ASSERT( psa_mac_sign_finish( &operation,
2485 sign_mac, sizeof( sign_mac ),
2486 &sign_mac_length ) );
2487 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2488 PSA_ERROR_BAD_STATE );
2489 PSA_ASSERT( psa_mac_abort( &operation ) );
2490
2491 /* Call update after verify finish. */
2492 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002493 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002494 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2495 PSA_ASSERT( psa_mac_verify_finish( &operation,
2496 verify_mac, sizeof( verify_mac ) ) );
2497 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2498 PSA_ERROR_BAD_STATE );
2499 PSA_ASSERT( psa_mac_abort( &operation ) );
2500
2501 /* Call sign finish twice in a row. */
2502 PSA_ASSERT( psa_mac_sign_setup( &operation,
2503 handle, alg ) );
2504 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2505 PSA_ASSERT( psa_mac_sign_finish( &operation,
2506 sign_mac, sizeof( sign_mac ),
2507 &sign_mac_length ) );
2508 TEST_EQUAL( psa_mac_sign_finish( &operation,
2509 sign_mac, sizeof( sign_mac ),
2510 &sign_mac_length ),
2511 PSA_ERROR_BAD_STATE );
2512 PSA_ASSERT( psa_mac_abort( &operation ) );
2513
2514 /* Call verify finish twice in a row. */
2515 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002516 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002517 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2518 PSA_ASSERT( psa_mac_verify_finish( &operation,
2519 verify_mac, sizeof( verify_mac ) ) );
2520 TEST_EQUAL( psa_mac_verify_finish( &operation,
2521 verify_mac, sizeof( verify_mac ) ),
2522 PSA_ERROR_BAD_STATE );
2523 PSA_ASSERT( psa_mac_abort( &operation ) );
2524
2525 /* Setup sign but try verify. */
2526 PSA_ASSERT( psa_mac_sign_setup( &operation,
2527 handle, alg ) );
2528 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2529 TEST_EQUAL( psa_mac_verify_finish( &operation,
2530 verify_mac, sizeof( verify_mac ) ),
2531 PSA_ERROR_BAD_STATE );
2532 PSA_ASSERT( psa_mac_abort( &operation ) );
2533
2534 /* Setup verify but try sign. */
2535 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002536 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002537 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2538 TEST_EQUAL( psa_mac_sign_finish( &operation,
2539 sign_mac, sizeof( sign_mac ),
2540 &sign_mac_length ),
2541 PSA_ERROR_BAD_STATE );
2542 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002543
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002544exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002545 mbedtls_psa_crypto_free( );
2546}
2547/* END_CASE */
2548
2549/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002550void mac_sign( int key_type_arg,
2551 data_t *key,
2552 int alg_arg,
2553 data_t *input,
2554 data_t *expected_mac )
2555{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002556 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002557 psa_key_type_t key_type = key_type_arg;
2558 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002559 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002560 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002561 /* Leave a little extra room in the output buffer. At the end of the
2562 * test, we'll check that the implementation didn't overwrite onto
2563 * this extra room. */
2564 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2565 size_t mac_buffer_size =
2566 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2567 size_t mac_length = 0;
2568
2569 memset( actual_mac, '+', sizeof( actual_mac ) );
2570 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2571 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2572
Gilles Peskine8817f612018-12-18 00:18:46 +01002573 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002574
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002575 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2576 psa_set_key_algorithm( &attributes, alg );
2577 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002578
Gilles Peskine73676cb2019-05-15 20:15:10 +02002579 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002580
2581 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002582 PSA_ASSERT( psa_mac_sign_setup( &operation,
2583 handle, alg ) );
2584 PSA_ASSERT( psa_mac_update( &operation,
2585 input->x, input->len ) );
2586 PSA_ASSERT( psa_mac_sign_finish( &operation,
2587 actual_mac, mac_buffer_size,
2588 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002589
2590 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002591 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2592 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002593
2594 /* Verify that the end of the buffer is untouched. */
2595 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2596 sizeof( actual_mac ) - mac_length ) );
2597
2598exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002599 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002600 mbedtls_psa_crypto_free( );
2601}
2602/* END_CASE */
2603
2604/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002605void mac_verify( int key_type_arg,
2606 data_t *key,
2607 int alg_arg,
2608 data_t *input,
2609 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002610{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002611 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002612 psa_key_type_t key_type = key_type_arg;
2613 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002614 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002615 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002616
Gilles Peskine69c12672018-06-28 00:07:19 +02002617 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2618
Gilles Peskine8817f612018-12-18 00:18:46 +01002619 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002620
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002621 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2622 psa_set_key_algorithm( &attributes, alg );
2623 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002624
Gilles Peskine73676cb2019-05-15 20:15:10 +02002625 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002626
Gilles Peskine8817f612018-12-18 00:18:46 +01002627 PSA_ASSERT( psa_mac_verify_setup( &operation,
2628 handle, alg ) );
2629 PSA_ASSERT( psa_destroy_key( handle ) );
2630 PSA_ASSERT( psa_mac_update( &operation,
2631 input->x, input->len ) );
2632 PSA_ASSERT( psa_mac_verify_finish( &operation,
2633 expected_mac->x,
2634 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002635
2636exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002637 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002638 mbedtls_psa_crypto_free( );
2639}
2640/* END_CASE */
2641
2642/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002643void cipher_operation_init( )
2644{
Jaeden Ameroab439972019-02-15 14:12:05 +00002645 const uint8_t input[1] = { 0 };
2646 unsigned char output[1] = { 0 };
2647 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002648 /* Test each valid way of initializing the object, except for `= {0}`, as
2649 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2650 * though it's OK by the C standard. We could test for this, but we'd need
2651 * to supress the Clang warning for the test. */
2652 psa_cipher_operation_t func = psa_cipher_operation_init( );
2653 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2654 psa_cipher_operation_t zero;
2655
2656 memset( &zero, 0, sizeof( zero ) );
2657
Jaeden Ameroab439972019-02-15 14:12:05 +00002658 /* A freshly-initialized cipher operation should not be usable. */
2659 TEST_EQUAL( psa_cipher_update( &func,
2660 input, sizeof( input ),
2661 output, sizeof( output ),
2662 &output_length ),
2663 PSA_ERROR_BAD_STATE );
2664 TEST_EQUAL( psa_cipher_update( &init,
2665 input, sizeof( input ),
2666 output, sizeof( output ),
2667 &output_length ),
2668 PSA_ERROR_BAD_STATE );
2669 TEST_EQUAL( psa_cipher_update( &zero,
2670 input, sizeof( input ),
2671 output, sizeof( output ),
2672 &output_length ),
2673 PSA_ERROR_BAD_STATE );
2674
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002675 /* A default cipher operation should be abortable without error. */
2676 PSA_ASSERT( psa_cipher_abort( &func ) );
2677 PSA_ASSERT( psa_cipher_abort( &init ) );
2678 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002679}
2680/* END_CASE */
2681
2682/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002683void cipher_setup( int key_type_arg,
2684 data_t *key,
2685 int alg_arg,
2686 int expected_status_arg )
2687{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002688 psa_key_type_t key_type = key_type_arg;
2689 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002690 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002691 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002692 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002693#if defined(KNOWN_SUPPORTED_MAC_ALG)
2694 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2695#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002696
Gilles Peskine8817f612018-12-18 00:18:46 +01002697 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002698
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002699 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2700 &operation, &status ) )
2701 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002702 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002703
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002704 /* The operation object should be reusable. */
2705#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2706 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2707 smoke_test_key_data,
2708 sizeof( smoke_test_key_data ),
2709 KNOWN_SUPPORTED_CIPHER_ALG,
2710 &operation, &status ) )
2711 goto exit;
2712 TEST_EQUAL( status, PSA_SUCCESS );
2713#endif
2714
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002715exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002716 mbedtls_psa_crypto_free( );
2717}
2718/* END_CASE */
2719
2720/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002721void cipher_bad_order( )
2722{
2723 psa_key_handle_t handle = 0;
2724 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2725 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002726 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002727 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2728 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2729 const uint8_t key[] = {
2730 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2731 0xaa, 0xaa, 0xaa, 0xaa };
2732 const uint8_t text[] = {
2733 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2734 0xbb, 0xbb, 0xbb, 0xbb };
2735 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2736 size_t length = 0;
2737
2738 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002739 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2740 psa_set_key_algorithm( &attributes, alg );
2741 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002742 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002743
2744
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002745 /* Call encrypt setup twice in a row. */
2746 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2747 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2748 PSA_ERROR_BAD_STATE );
2749 PSA_ASSERT( psa_cipher_abort( &operation ) );
2750
2751 /* Call decrypt setup twice in a row. */
2752 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2753 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2754 PSA_ERROR_BAD_STATE );
2755 PSA_ASSERT( psa_cipher_abort( &operation ) );
2756
Jaeden Ameroab439972019-02-15 14:12:05 +00002757 /* Generate an IV without calling setup beforehand. */
2758 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2759 buffer, sizeof( buffer ),
2760 &length ),
2761 PSA_ERROR_BAD_STATE );
2762 PSA_ASSERT( psa_cipher_abort( &operation ) );
2763
2764 /* Generate an IV twice in a row. */
2765 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2766 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2767 buffer, sizeof( buffer ),
2768 &length ) );
2769 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2770 buffer, sizeof( buffer ),
2771 &length ),
2772 PSA_ERROR_BAD_STATE );
2773 PSA_ASSERT( psa_cipher_abort( &operation ) );
2774
2775 /* Generate an IV after it's already set. */
2776 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2777 PSA_ASSERT( psa_cipher_set_iv( &operation,
2778 iv, sizeof( iv ) ) );
2779 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2780 buffer, sizeof( buffer ),
2781 &length ),
2782 PSA_ERROR_BAD_STATE );
2783 PSA_ASSERT( psa_cipher_abort( &operation ) );
2784
2785 /* Set an IV without calling setup beforehand. */
2786 TEST_EQUAL( psa_cipher_set_iv( &operation,
2787 iv, sizeof( iv ) ),
2788 PSA_ERROR_BAD_STATE );
2789 PSA_ASSERT( psa_cipher_abort( &operation ) );
2790
2791 /* Set an IV after it's already set. */
2792 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2793 PSA_ASSERT( psa_cipher_set_iv( &operation,
2794 iv, sizeof( iv ) ) );
2795 TEST_EQUAL( psa_cipher_set_iv( &operation,
2796 iv, sizeof( iv ) ),
2797 PSA_ERROR_BAD_STATE );
2798 PSA_ASSERT( psa_cipher_abort( &operation ) );
2799
2800 /* Set an IV after it's already generated. */
2801 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2802 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2803 buffer, sizeof( buffer ),
2804 &length ) );
2805 TEST_EQUAL( psa_cipher_set_iv( &operation,
2806 iv, sizeof( iv ) ),
2807 PSA_ERROR_BAD_STATE );
2808 PSA_ASSERT( psa_cipher_abort( &operation ) );
2809
2810 /* Call update without calling setup beforehand. */
2811 TEST_EQUAL( psa_cipher_update( &operation,
2812 text, sizeof( text ),
2813 buffer, sizeof( buffer ),
2814 &length ),
2815 PSA_ERROR_BAD_STATE );
2816 PSA_ASSERT( psa_cipher_abort( &operation ) );
2817
2818 /* Call update without an IV where an IV is required. */
2819 TEST_EQUAL( psa_cipher_update( &operation,
2820 text, sizeof( text ),
2821 buffer, sizeof( buffer ),
2822 &length ),
2823 PSA_ERROR_BAD_STATE );
2824 PSA_ASSERT( psa_cipher_abort( &operation ) );
2825
2826 /* Call update after finish. */
2827 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2828 PSA_ASSERT( psa_cipher_set_iv( &operation,
2829 iv, sizeof( iv ) ) );
2830 PSA_ASSERT( psa_cipher_finish( &operation,
2831 buffer, sizeof( buffer ), &length ) );
2832 TEST_EQUAL( psa_cipher_update( &operation,
2833 text, sizeof( text ),
2834 buffer, sizeof( buffer ),
2835 &length ),
2836 PSA_ERROR_BAD_STATE );
2837 PSA_ASSERT( psa_cipher_abort( &operation ) );
2838
2839 /* Call finish without calling setup beforehand. */
2840 TEST_EQUAL( psa_cipher_finish( &operation,
2841 buffer, sizeof( buffer ), &length ),
2842 PSA_ERROR_BAD_STATE );
2843 PSA_ASSERT( psa_cipher_abort( &operation ) );
2844
2845 /* Call finish without an IV where an IV is required. */
2846 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2847 /* Not calling update means we are encrypting an empty buffer, which is OK
2848 * for cipher modes with padding. */
2849 TEST_EQUAL( psa_cipher_finish( &operation,
2850 buffer, sizeof( buffer ), &length ),
2851 PSA_ERROR_BAD_STATE );
2852 PSA_ASSERT( psa_cipher_abort( &operation ) );
2853
2854 /* Call finish twice in a row. */
2855 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2856 PSA_ASSERT( psa_cipher_set_iv( &operation,
2857 iv, sizeof( iv ) ) );
2858 PSA_ASSERT( psa_cipher_finish( &operation,
2859 buffer, sizeof( buffer ), &length ) );
2860 TEST_EQUAL( psa_cipher_finish( &operation,
2861 buffer, sizeof( buffer ), &length ),
2862 PSA_ERROR_BAD_STATE );
2863 PSA_ASSERT( psa_cipher_abort( &operation ) );
2864
2865exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002866 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002867}
2868/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002869
Gilles Peskine50e586b2018-06-08 14:28:46 +02002870/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002871void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002872 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002873 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002874 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002875{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002876 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002877 psa_status_t status;
2878 psa_key_type_t key_type = key_type_arg;
2879 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002880 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002881 unsigned char *output = NULL;
2882 size_t output_buffer_size = 0;
2883 size_t function_output_length = 0;
2884 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002885 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002886 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002887
Gilles Peskine8817f612018-12-18 00:18:46 +01002888 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002889
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002890 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2891 psa_set_key_algorithm( &attributes, alg );
2892 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002893
Gilles Peskine73676cb2019-05-15 20:15:10 +02002894 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002895
Gilles Peskine8817f612018-12-18 00:18:46 +01002896 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2897 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002898
Gilles Peskine423005e2019-05-06 15:22:57 +02002899 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002900 output_buffer_size = ( (size_t) input->len +
2901 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002902 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002903
Gilles Peskine8817f612018-12-18 00:18:46 +01002904 PSA_ASSERT( psa_cipher_update( &operation,
2905 input->x, input->len,
2906 output, output_buffer_size,
2907 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002908 total_output_length += function_output_length;
2909 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002910 output + total_output_length,
2911 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002912 &function_output_length );
2913 total_output_length += function_output_length;
2914
Gilles Peskinefe11b722018-12-18 00:24:04 +01002915 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002916 if( expected_status == PSA_SUCCESS )
2917 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002918 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002919 ASSERT_COMPARE( expected_output->x, expected_output->len,
2920 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002921 }
2922
2923exit:
2924 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002925 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002926 mbedtls_psa_crypto_free( );
2927}
2928/* END_CASE */
2929
2930/* BEGIN_CASE */
2931void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002932 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002934 int first_part_size_arg,
2935 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002936 data_t *expected_output )
2937{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002938 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002939 psa_key_type_t key_type = key_type_arg;
2940 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002941 size_t first_part_size = first_part_size_arg;
2942 size_t output1_length = output1_length_arg;
2943 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002944 unsigned char *output = NULL;
2945 size_t output_buffer_size = 0;
2946 size_t function_output_length = 0;
2947 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002948 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002949 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002950
Gilles Peskine8817f612018-12-18 00:18:46 +01002951 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002953 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2954 psa_set_key_algorithm( &attributes, alg );
2955 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002956
Gilles Peskine73676cb2019-05-15 20:15:10 +02002957 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002958
Gilles Peskine8817f612018-12-18 00:18:46 +01002959 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2960 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002961
Gilles Peskine423005e2019-05-06 15:22:57 +02002962 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002963 output_buffer_size = ( (size_t) input->len +
2964 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002965 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002966
Gilles Peskinee0866522019-02-19 19:44:00 +01002967 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002968 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2969 output, output_buffer_size,
2970 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002971 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002972 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002973 PSA_ASSERT( psa_cipher_update( &operation,
2974 input->x + first_part_size,
2975 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002976 output + total_output_length,
2977 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002978 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002979 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002980 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002981 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002982 output + total_output_length,
2983 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002984 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002985 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002986 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002987
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002988 ASSERT_COMPARE( expected_output->x, expected_output->len,
2989 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002990
2991exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002992 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002993 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002994 mbedtls_psa_crypto_free( );
2995}
2996/* END_CASE */
2997
2998/* BEGIN_CASE */
2999void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003000 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003001 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003002 int first_part_size_arg,
3003 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003004 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003005{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003006 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003007
3008 psa_key_type_t key_type = key_type_arg;
3009 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003010 size_t first_part_size = first_part_size_arg;
3011 size_t output1_length = output1_length_arg;
3012 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003013 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003014 size_t output_buffer_size = 0;
3015 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003016 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003017 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003018 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003019
Gilles Peskine8817f612018-12-18 00:18:46 +01003020 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003021
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003022 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3023 psa_set_key_algorithm( &attributes, alg );
3024 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003025
Gilles Peskine73676cb2019-05-15 20:15:10 +02003026 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003027
Gilles Peskine8817f612018-12-18 00:18:46 +01003028 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3029 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003030
Gilles Peskine423005e2019-05-06 15:22:57 +02003031 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003032
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003033 output_buffer_size = ( (size_t) input->len +
3034 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003035 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003036
Gilles Peskinee0866522019-02-19 19:44:00 +01003037 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003038 PSA_ASSERT( psa_cipher_update( &operation,
3039 input->x, first_part_size,
3040 output, output_buffer_size,
3041 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003042 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003043 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003044 PSA_ASSERT( psa_cipher_update( &operation,
3045 input->x + first_part_size,
3046 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003047 output + total_output_length,
3048 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003049 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003050 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003051 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003052 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003053 output + total_output_length,
3054 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003055 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003056 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003057 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003058
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003059 ASSERT_COMPARE( expected_output->x, expected_output->len,
3060 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003061
3062exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003063 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003064 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065 mbedtls_psa_crypto_free( );
3066}
3067/* END_CASE */
3068
Gilles Peskine50e586b2018-06-08 14:28:46 +02003069/* BEGIN_CASE */
3070void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003071 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003072 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003073 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003075 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003076 psa_status_t status;
3077 psa_key_type_t key_type = key_type_arg;
3078 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003079 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003080 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003081 size_t output_buffer_size = 0;
3082 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003083 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003084 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003085 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086
Gilles Peskine8817f612018-12-18 00:18:46 +01003087 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003088
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003089 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3090 psa_set_key_algorithm( &attributes, alg );
3091 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003092
Gilles Peskine73676cb2019-05-15 20:15:10 +02003093 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003094
Gilles Peskine8817f612018-12-18 00:18:46 +01003095 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3096 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003097
Gilles Peskine423005e2019-05-06 15:22:57 +02003098 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003099
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003100 output_buffer_size = ( (size_t) input->len +
3101 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003102 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003103
Gilles Peskine8817f612018-12-18 00:18:46 +01003104 PSA_ASSERT( psa_cipher_update( &operation,
3105 input->x, input->len,
3106 output, output_buffer_size,
3107 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003108 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003109 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003110 output + total_output_length,
3111 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003112 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003113 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003114 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003115
3116 if( expected_status == PSA_SUCCESS )
3117 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003118 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003119 ASSERT_COMPARE( expected_output->x, expected_output->len,
3120 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003121 }
3122
Gilles Peskine50e586b2018-06-08 14:28:46 +02003123exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003124 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003125 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003126 mbedtls_psa_crypto_free( );
3127}
3128/* END_CASE */
3129
Gilles Peskine50e586b2018-06-08 14:28:46 +02003130/* BEGIN_CASE */
3131void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003132 data_t *key,
3133 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003134{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003135 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003136 psa_key_type_t key_type = key_type_arg;
3137 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003138 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003139 size_t iv_size = 16;
3140 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003141 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003142 size_t output1_size = 0;
3143 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003144 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003145 size_t output2_size = 0;
3146 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003147 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003148 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3149 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003150 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003151
Gilles Peskine8817f612018-12-18 00:18:46 +01003152 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003153
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003154 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3155 psa_set_key_algorithm( &attributes, alg );
3156 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003157
Gilles Peskine73676cb2019-05-15 20:15:10 +02003158 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003159
Gilles Peskine8817f612018-12-18 00:18:46 +01003160 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3161 handle, alg ) );
3162 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3163 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003164
Gilles Peskine8817f612018-12-18 00:18:46 +01003165 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3166 iv, iv_size,
3167 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003168 output1_size = ( (size_t) input->len +
3169 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003170 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003171
Gilles Peskine8817f612018-12-18 00:18:46 +01003172 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3173 output1, output1_size,
3174 &output1_length ) );
3175 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003176 output1 + output1_length,
3177 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003178 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003179
Gilles Peskine048b7f02018-06-08 14:20:49 +02003180 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003181
Gilles Peskine8817f612018-12-18 00:18:46 +01003182 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003183
3184 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003185 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003186
Gilles Peskine8817f612018-12-18 00:18:46 +01003187 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3188 iv, iv_length ) );
3189 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3190 output2, output2_size,
3191 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003192 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003193 PSA_ASSERT( psa_cipher_finish( &operation2,
3194 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003195 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003196 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003197
Gilles Peskine048b7f02018-06-08 14:20:49 +02003198 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003199
Gilles Peskine8817f612018-12-18 00:18:46 +01003200 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003201
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003202 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003203
3204exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003205 mbedtls_free( output1 );
3206 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003207 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003208 mbedtls_psa_crypto_free( );
3209}
3210/* END_CASE */
3211
3212/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003213void cipher_verify_output_multipart( int alg_arg,
3214 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003215 data_t *key,
3216 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003217 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003218{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003219 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003220 psa_key_type_t key_type = key_type_arg;
3221 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003222 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003223 unsigned char iv[16] = {0};
3224 size_t iv_size = 16;
3225 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003226 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003227 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003228 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003229 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003230 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003231 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003232 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003233 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3234 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003235 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003236
Gilles Peskine8817f612018-12-18 00:18:46 +01003237 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003238
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003239 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3240 psa_set_key_algorithm( &attributes, alg );
3241 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003242
Gilles Peskine73676cb2019-05-15 20:15:10 +02003243 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003244
Gilles Peskine8817f612018-12-18 00:18:46 +01003245 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3246 handle, alg ) );
3247 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3248 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003249
Gilles Peskine8817f612018-12-18 00:18:46 +01003250 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3251 iv, iv_size,
3252 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003253 output1_buffer_size = ( (size_t) input->len +
3254 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003255 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003256
Gilles Peskinee0866522019-02-19 19:44:00 +01003257 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003258
Gilles Peskine8817f612018-12-18 00:18:46 +01003259 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3260 output1, output1_buffer_size,
3261 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003262 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003263
Gilles Peskine8817f612018-12-18 00:18:46 +01003264 PSA_ASSERT( psa_cipher_update( &operation1,
3265 input->x + first_part_size,
3266 input->len - first_part_size,
3267 output1, output1_buffer_size,
3268 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003269 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003270
Gilles Peskine8817f612018-12-18 00:18:46 +01003271 PSA_ASSERT( psa_cipher_finish( &operation1,
3272 output1 + output1_length,
3273 output1_buffer_size - output1_length,
3274 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003275 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003276
Gilles Peskine8817f612018-12-18 00:18:46 +01003277 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003278
Gilles Peskine048b7f02018-06-08 14:20:49 +02003279 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003280 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003281
Gilles Peskine8817f612018-12-18 00:18:46 +01003282 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3283 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003284
Gilles Peskine8817f612018-12-18 00:18:46 +01003285 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3286 output2, output2_buffer_size,
3287 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003288 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003289
Gilles Peskine8817f612018-12-18 00:18:46 +01003290 PSA_ASSERT( psa_cipher_update( &operation2,
3291 output1 + first_part_size,
3292 output1_length - first_part_size,
3293 output2, output2_buffer_size,
3294 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003295 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003296
Gilles Peskine8817f612018-12-18 00:18:46 +01003297 PSA_ASSERT( psa_cipher_finish( &operation2,
3298 output2 + output2_length,
3299 output2_buffer_size - output2_length,
3300 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003301 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003302
Gilles Peskine8817f612018-12-18 00:18:46 +01003303 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003304
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003305 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003306
3307exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003308 mbedtls_free( output1 );
3309 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003310 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003311 mbedtls_psa_crypto_free( );
3312}
3313/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003314
Gilles Peskine20035e32018-02-03 22:44:14 +01003315/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003316void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003317 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003318 data_t *nonce,
3319 data_t *additional_data,
3320 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003321 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003322{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003323 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003324 psa_key_type_t key_type = key_type_arg;
3325 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003326 unsigned char *output_data = NULL;
3327 size_t output_size = 0;
3328 size_t output_length = 0;
3329 unsigned char *output_data2 = NULL;
3330 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003331 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003332 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003333 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003334
Gilles Peskine4abf7412018-06-18 16:35:34 +02003335 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003336 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3337 * should be exact. */
3338 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3339 TEST_EQUAL( output_size,
3340 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003341 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003342
Gilles Peskine8817f612018-12-18 00:18:46 +01003343 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003344
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003345 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3346 psa_set_key_algorithm( &attributes, alg );
3347 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003348
Gilles Peskine049c7532019-05-15 20:22:09 +02003349 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3350 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003351
Gilles Peskinefe11b722018-12-18 00:24:04 +01003352 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3353 nonce->x, nonce->len,
3354 additional_data->x,
3355 additional_data->len,
3356 input_data->x, input_data->len,
3357 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003358 &output_length ),
3359 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003360
3361 if( PSA_SUCCESS == expected_result )
3362 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003363 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003364
Gilles Peskine003a4a92019-05-14 16:09:40 +02003365 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3366 * should be exact. */
3367 TEST_EQUAL( input_data->len,
3368 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3369
Gilles Peskinefe11b722018-12-18 00:24:04 +01003370 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3371 nonce->x, nonce->len,
3372 additional_data->x,
3373 additional_data->len,
3374 output_data, output_length,
3375 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003376 &output_length2 ),
3377 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003378
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003379 ASSERT_COMPARE( input_data->x, input_data->len,
3380 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003381 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003382
Gilles Peskinea1cac842018-06-11 19:33:02 +02003383exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003384 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003385 mbedtls_free( output_data );
3386 mbedtls_free( output_data2 );
3387 mbedtls_psa_crypto_free( );
3388}
3389/* END_CASE */
3390
3391/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003392void aead_encrypt( int key_type_arg, data_t *key_data,
3393 int alg_arg,
3394 data_t *nonce,
3395 data_t *additional_data,
3396 data_t *input_data,
3397 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003399 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400 psa_key_type_t key_type = key_type_arg;
3401 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003402 unsigned char *output_data = NULL;
3403 size_t output_size = 0;
3404 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003405 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003406 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003407
Gilles Peskine4abf7412018-06-18 16:35:34 +02003408 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003409 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3410 * should be exact. */
3411 TEST_EQUAL( output_size,
3412 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003413 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003414
Gilles Peskine8817f612018-12-18 00:18:46 +01003415 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003416
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003417 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3418 psa_set_key_algorithm( &attributes, alg );
3419 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003420
Gilles Peskine049c7532019-05-15 20:22:09 +02003421 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3422 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003423
Gilles Peskine8817f612018-12-18 00:18:46 +01003424 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3425 nonce->x, nonce->len,
3426 additional_data->x, additional_data->len,
3427 input_data->x, input_data->len,
3428 output_data, output_size,
3429 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003430
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003431 ASSERT_COMPARE( expected_result->x, expected_result->len,
3432 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003433
Gilles Peskinea1cac842018-06-11 19:33:02 +02003434exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003435 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003436 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003437 mbedtls_psa_crypto_free( );
3438}
3439/* END_CASE */
3440
3441/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003442void aead_decrypt( 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_data,
3448 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003449{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003450 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003451 psa_key_type_t key_type = key_type_arg;
3452 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003453 unsigned char *output_data = NULL;
3454 size_t output_size = 0;
3455 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003456 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003457 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003458 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003459
Gilles Peskine003a4a92019-05-14 16:09:40 +02003460 output_size = input_data->len - tag_length;
3461 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3462 * should be exact. */
3463 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3464 TEST_EQUAL( output_size,
3465 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003466 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003467
Gilles Peskine8817f612018-12-18 00:18:46 +01003468 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003469
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003470 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3471 psa_set_key_algorithm( &attributes, alg );
3472 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003473
Gilles Peskine049c7532019-05-15 20:22:09 +02003474 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3475 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003476
Gilles Peskinefe11b722018-12-18 00:24:04 +01003477 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3478 nonce->x, nonce->len,
3479 additional_data->x,
3480 additional_data->len,
3481 input_data->x, input_data->len,
3482 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003483 &output_length ),
3484 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003485
Gilles Peskine2d277862018-06-18 15:41:12 +02003486 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003487 ASSERT_COMPARE( expected_data->x, expected_data->len,
3488 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003489
Gilles Peskinea1cac842018-06-11 19:33:02 +02003490exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003491 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003492 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003493 mbedtls_psa_crypto_free( );
3494}
3495/* END_CASE */
3496
3497/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003498void signature_size( int type_arg,
3499 int bits,
3500 int alg_arg,
3501 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003502{
3503 psa_key_type_t type = type_arg;
3504 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003505 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003506 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003507exit:
3508 ;
3509}
3510/* END_CASE */
3511
3512/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003513void sign_deterministic( int key_type_arg, data_t *key_data,
3514 int alg_arg, data_t *input_data,
3515 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003516{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003517 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003518 psa_key_type_t key_type = key_type_arg;
3519 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003520 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003521 unsigned char *signature = NULL;
3522 size_t signature_size;
3523 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003524 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003525
Gilles Peskine8817f612018-12-18 00:18:46 +01003526 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003527
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003528 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3529 psa_set_key_algorithm( &attributes, alg );
3530 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003531
Gilles Peskine049c7532019-05-15 20:22:09 +02003532 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3533 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003534 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3535 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003536
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003537 /* Allocate a buffer which has the size advertized by the
3538 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003539 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3540 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003541 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003542 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003543 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003544
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003545 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003546 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3547 input_data->x, input_data->len,
3548 signature, signature_size,
3549 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003550 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003551 ASSERT_COMPARE( output_data->x, output_data->len,
3552 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003553
3554exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003555 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003556 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003557 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003558 mbedtls_psa_crypto_free( );
3559}
3560/* END_CASE */
3561
3562/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003563void sign_fail( int key_type_arg, data_t *key_data,
3564 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003565 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003566{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003567 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003568 psa_key_type_t key_type = key_type_arg;
3569 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003570 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003571 psa_status_t actual_status;
3572 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003573 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003574 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003575 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003576
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003577 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003578
Gilles Peskine8817f612018-12-18 00:18:46 +01003579 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003580
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003581 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3582 psa_set_key_algorithm( &attributes, alg );
3583 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003584
Gilles Peskine049c7532019-05-15 20:22:09 +02003585 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3586 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003587
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003588 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003589 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003590 signature, signature_size,
3591 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003592 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003593 /* The value of *signature_length is unspecified on error, but
3594 * whatever it is, it should be less than signature_size, so that
3595 * if the caller tries to read *signature_length bytes without
3596 * checking the error code then they don't overflow a buffer. */
3597 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003598
3599exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003600 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003601 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003602 mbedtls_free( signature );
3603 mbedtls_psa_crypto_free( );
3604}
3605/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003606
3607/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003608void sign_verify( int key_type_arg, data_t *key_data,
3609 int alg_arg, data_t *input_data )
3610{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003611 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003612 psa_key_type_t key_type = key_type_arg;
3613 psa_algorithm_t alg = alg_arg;
3614 size_t key_bits;
3615 unsigned char *signature = NULL;
3616 size_t signature_size;
3617 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003618 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003619
Gilles Peskine8817f612018-12-18 00:18:46 +01003620 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003621
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003622 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3623 psa_set_key_algorithm( &attributes, alg );
3624 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003625
Gilles Peskine049c7532019-05-15 20:22:09 +02003626 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3627 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003628 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3629 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003630
3631 /* Allocate a buffer which has the size advertized by the
3632 * library. */
3633 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3634 key_bits, alg );
3635 TEST_ASSERT( signature_size != 0 );
3636 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003637 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003638
3639 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003640 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3641 input_data->x, input_data->len,
3642 signature, signature_size,
3643 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003644 /* Check that the signature length looks sensible. */
3645 TEST_ASSERT( signature_length <= signature_size );
3646 TEST_ASSERT( signature_length > 0 );
3647
3648 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003649 PSA_ASSERT( psa_asymmetric_verify(
3650 handle, alg,
3651 input_data->x, input_data->len,
3652 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003653
3654 if( input_data->len != 0 )
3655 {
3656 /* Flip a bit in the input and verify that the signature is now
3657 * detected as invalid. Flip a bit at the beginning, not at the end,
3658 * because ECDSA may ignore the last few bits of the input. */
3659 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003660 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3661 input_data->x, input_data->len,
3662 signature, signature_length ),
3663 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003664 }
3665
3666exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003667 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003668 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003669 mbedtls_free( signature );
3670 mbedtls_psa_crypto_free( );
3671}
3672/* END_CASE */
3673
3674/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003675void asymmetric_verify( int key_type_arg, data_t *key_data,
3676 int alg_arg, data_t *hash_data,
3677 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003678{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003679 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003680 psa_key_type_t key_type = key_type_arg;
3681 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003682 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003683
Gilles Peskine69c12672018-06-28 00:07:19 +02003684 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3685
Gilles Peskine8817f612018-12-18 00:18:46 +01003686 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003687
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003688 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3689 psa_set_key_algorithm( &attributes, alg );
3690 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003691
Gilles Peskine049c7532019-05-15 20:22:09 +02003692 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3693 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003694
Gilles Peskine8817f612018-12-18 00:18:46 +01003695 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3696 hash_data->x, hash_data->len,
3697 signature_data->x,
3698 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003699exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003700 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003701 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003702 mbedtls_psa_crypto_free( );
3703}
3704/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003705
3706/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003707void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3708 int alg_arg, data_t *hash_data,
3709 data_t *signature_data,
3710 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003711{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003712 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003713 psa_key_type_t key_type = key_type_arg;
3714 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003715 psa_status_t actual_status;
3716 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003717 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003718
Gilles Peskine8817f612018-12-18 00:18:46 +01003719 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003720
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003721 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3722 psa_set_key_algorithm( &attributes, alg );
3723 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003724
Gilles Peskine049c7532019-05-15 20:22:09 +02003725 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3726 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003727
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003728 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003729 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003730 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003731 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003732
Gilles Peskinefe11b722018-12-18 00:24:04 +01003733 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003734
3735exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003736 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003737 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003738 mbedtls_psa_crypto_free( );
3739}
3740/* END_CASE */
3741
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003742/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003743void asymmetric_encrypt( int key_type_arg,
3744 data_t *key_data,
3745 int alg_arg,
3746 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003747 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003748 int expected_output_length_arg,
3749 int expected_status_arg )
3750{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003751 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003752 psa_key_type_t key_type = key_type_arg;
3753 psa_algorithm_t alg = alg_arg;
3754 size_t expected_output_length = expected_output_length_arg;
3755 size_t key_bits;
3756 unsigned char *output = NULL;
3757 size_t output_size;
3758 size_t output_length = ~0;
3759 psa_status_t actual_status;
3760 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003761 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003762
Gilles Peskine8817f612018-12-18 00:18:46 +01003763 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003764
Gilles Peskine656896e2018-06-29 19:12:28 +02003765 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003766 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3767 psa_set_key_algorithm( &attributes, alg );
3768 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003769 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3770 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003771
3772 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003773 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3774 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003775 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003776 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003777
3778 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003779 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003780 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003781 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003782 output, output_size,
3783 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003784 TEST_EQUAL( actual_status, expected_status );
3785 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003786
Gilles Peskine68428122018-06-30 18:42:41 +02003787 /* If the label is empty, the test framework puts a non-null pointer
3788 * in label->x. Test that a null pointer works as well. */
3789 if( label->len == 0 )
3790 {
3791 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003792 if( output_size != 0 )
3793 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003794 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003795 input_data->x, input_data->len,
3796 NULL, label->len,
3797 output, output_size,
3798 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003799 TEST_EQUAL( actual_status, expected_status );
3800 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003801 }
3802
Gilles Peskine656896e2018-06-29 19:12:28 +02003803exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003804 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003805 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003806 mbedtls_free( output );
3807 mbedtls_psa_crypto_free( );
3808}
3809/* END_CASE */
3810
3811/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003812void asymmetric_encrypt_decrypt( int key_type_arg,
3813 data_t *key_data,
3814 int alg_arg,
3815 data_t *input_data,
3816 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003817{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003818 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003819 psa_key_type_t key_type = key_type_arg;
3820 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003821 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003822 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003823 size_t output_size;
3824 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003825 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003826 size_t output2_size;
3827 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003828 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003829
Gilles Peskine8817f612018-12-18 00:18:46 +01003830 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003831
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003832 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3833 psa_set_key_algorithm( &attributes, alg );
3834 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003835
Gilles Peskine049c7532019-05-15 20:22:09 +02003836 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3837 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003838
3839 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003840 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3841 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003842 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003843 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003844 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003845 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003846
Gilles Peskineeebd7382018-06-08 18:11:54 +02003847 /* We test encryption by checking that encrypt-then-decrypt gives back
3848 * the original plaintext because of the non-optional random
3849 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003850 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3851 input_data->x, input_data->len,
3852 label->x, label->len,
3853 output, output_size,
3854 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003855 /* We don't know what ciphertext length to expect, but check that
3856 * it looks sensible. */
3857 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003858
Gilles Peskine8817f612018-12-18 00:18:46 +01003859 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3860 output, output_length,
3861 label->x, label->len,
3862 output2, output2_size,
3863 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003864 ASSERT_COMPARE( input_data->x, input_data->len,
3865 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003866
3867exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003868 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003869 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003870 mbedtls_free( output );
3871 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003872 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003873}
3874/* END_CASE */
3875
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003876/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003877void asymmetric_decrypt( int key_type_arg,
3878 data_t *key_data,
3879 int alg_arg,
3880 data_t *input_data,
3881 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003882 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003884 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003885 psa_key_type_t key_type = key_type_arg;
3886 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003887 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003888 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003889 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003890 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003891
Jaeden Amero412654a2019-02-06 12:57:46 +00003892 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003893 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003894
Gilles Peskine8817f612018-12-18 00:18:46 +01003895 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003896
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003897 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3898 psa_set_key_algorithm( &attributes, alg );
3899 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003900
Gilles Peskine049c7532019-05-15 20:22:09 +02003901 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3902 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003903
Gilles Peskine8817f612018-12-18 00:18:46 +01003904 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3905 input_data->x, input_data->len,
3906 label->x, label->len,
3907 output,
3908 output_size,
3909 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003910 ASSERT_COMPARE( expected_data->x, expected_data->len,
3911 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003912
Gilles Peskine68428122018-06-30 18:42:41 +02003913 /* If the label is empty, the test framework puts a non-null pointer
3914 * in label->x. Test that a null pointer works as well. */
3915 if( label->len == 0 )
3916 {
3917 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003918 if( output_size != 0 )
3919 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003920 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3921 input_data->x, input_data->len,
3922 NULL, label->len,
3923 output,
3924 output_size,
3925 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003926 ASSERT_COMPARE( expected_data->x, expected_data->len,
3927 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003928 }
3929
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003930exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003931 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003932 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003933 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003934 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003935}
3936/* END_CASE */
3937
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003938/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003939void asymmetric_decrypt_fail( int key_type_arg,
3940 data_t *key_data,
3941 int alg_arg,
3942 data_t *input_data,
3943 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003944 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003945 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003946{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003947 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003948 psa_key_type_t key_type = key_type_arg;
3949 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003950 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003951 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003952 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003953 psa_status_t actual_status;
3954 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003955 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003956
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003957 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003958
Gilles Peskine8817f612018-12-18 00:18:46 +01003959 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003960
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003961 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3962 psa_set_key_algorithm( &attributes, alg );
3963 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003964
Gilles Peskine049c7532019-05-15 20:22:09 +02003965 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3966 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003967
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003968 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003969 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003970 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003971 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003972 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003973 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003974 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003975
Gilles Peskine68428122018-06-30 18:42:41 +02003976 /* If the label is empty, the test framework puts a non-null pointer
3977 * in label->x. Test that a null pointer works as well. */
3978 if( label->len == 0 )
3979 {
3980 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003981 if( output_size != 0 )
3982 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003983 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003984 input_data->x, input_data->len,
3985 NULL, label->len,
3986 output, output_size,
3987 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003988 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003989 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003990 }
3991
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003992exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003993 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003994 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003995 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003996 mbedtls_psa_crypto_free( );
3997}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003998/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003999
4000/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004001void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004002{
4003 /* Test each valid way of initializing the object, except for `= {0}`, as
4004 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4005 * though it's OK by the C standard. We could test for this, but we'd need
4006 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004007 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004008 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4009 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4010 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004011
4012 memset( &zero, 0, sizeof( zero ) );
4013
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004014 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004015 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004016 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004017 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004018 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004019 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004020 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004021
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004022 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004023 PSA_ASSERT( psa_key_derivation_abort(&func) );
4024 PSA_ASSERT( psa_key_derivation_abort(&init) );
4025 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004026}
4027/* END_CASE */
4028
4029/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004030void derive_setup( int key_type_arg,
4031 data_t *key_data,
4032 int alg_arg,
4033 data_t *salt,
4034 data_t *label,
4035 int requested_capacity_arg,
4036 int expected_status_arg )
4037{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004038 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004039 size_t key_type = key_type_arg;
4040 psa_algorithm_t alg = alg_arg;
4041 size_t requested_capacity = requested_capacity_arg;
4042 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004043 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004044 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004045
Gilles Peskine8817f612018-12-18 00:18:46 +01004046 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004047
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004048 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4049 psa_set_key_algorithm( &attributes, alg );
4050 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004051
Gilles Peskine049c7532019-05-15 20:22:09 +02004052 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4053 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004054
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004055 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004056 salt->x, salt->len,
4057 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004058 requested_capacity ),
4059 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004060
4061exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004062 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004063 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004064 mbedtls_psa_crypto_free( );
4065}
4066/* END_CASE */
4067
4068/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004069void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004070{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004071 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004072 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004073 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004074 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004075 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004076 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004077 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4078 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4079 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004080 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004081
Gilles Peskine8817f612018-12-18 00:18:46 +01004082 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004083
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004084 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4085 psa_set_key_algorithm( &attributes, alg );
4086 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004087
Gilles Peskine73676cb2019-05-15 20:15:10 +02004088 PSA_ASSERT( psa_import_key( &attributes,
4089 key_data, sizeof( key_data ),
4090 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004091
4092 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004093 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004094 NULL, 0,
4095 NULL, 0,
4096 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004097
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004098 /* state of operation shouldn't allow additional generation */
4099 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004100 NULL, 0,
4101 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004102 capacity ),
4103 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004104
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004105 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004106
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004107 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004108 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004109
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004110exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004111 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004112 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004113 mbedtls_psa_crypto_free( );
4114}
4115/* END_CASE */
4116
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004117/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004118void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004119{
4120 uint8_t output_buffer[16];
4121 size_t buffer_size = 16;
4122 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004123 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004124
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004125 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4126 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004127 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004128
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004129 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004130 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004131
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004132 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004133
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004134 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4135 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004136 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004137
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004138 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004139 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004140
4141exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004142 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004143}
4144/* END_CASE */
4145
4146/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004147void derive_output( int alg_arg,
4148 data_t *key_data,
4149 data_t *salt,
4150 data_t *label,
4151 int requested_capacity_arg,
4152 data_t *expected_output1,
4153 data_t *expected_output2 )
4154{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004155 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004156 psa_algorithm_t alg = alg_arg;
4157 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004158 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004159 uint8_t *expected_outputs[2] =
4160 {expected_output1->x, expected_output2->x};
4161 size_t output_sizes[2] =
4162 {expected_output1->len, expected_output2->len};
4163 size_t output_buffer_size = 0;
4164 uint8_t *output_buffer = NULL;
4165 size_t expected_capacity;
4166 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004167 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004168 psa_status_t status;
4169 unsigned i;
4170
4171 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4172 {
4173 if( output_sizes[i] > output_buffer_size )
4174 output_buffer_size = output_sizes[i];
4175 if( output_sizes[i] == 0 )
4176 expected_outputs[i] = NULL;
4177 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004178 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004179 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004180
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004181 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4182 psa_set_key_algorithm( &attributes, alg );
4183 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004184
Gilles Peskine049c7532019-05-15 20:22:09 +02004185 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4186 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004187
4188 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004189 if( PSA_ALG_IS_HKDF( alg ) )
4190 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004191 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4192 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004193 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004194 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004195 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004196 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004197 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004198 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004199 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004200 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004201 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004202 label->x, label->len ) );
4203 }
4204 else
4205 {
4206 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004207 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004208 salt->x, salt->len,
4209 label->x, label->len,
4210 requested_capacity ) );
4211 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004212 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004213 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004214 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004215 expected_capacity = requested_capacity;
4216
4217 /* Expansion phase. */
4218 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4219 {
4220 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004221 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004222 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004223 if( expected_capacity == 0 && output_sizes[i] == 0 )
4224 {
4225 /* Reading 0 bytes when 0 bytes are available can go either way. */
4226 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004227 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004228 continue;
4229 }
4230 else if( expected_capacity == 0 ||
4231 output_sizes[i] > expected_capacity )
4232 {
4233 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004234 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004235 expected_capacity = 0;
4236 continue;
4237 }
4238 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004239 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004240 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004241 ASSERT_COMPARE( output_buffer, output_sizes[i],
4242 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004243 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004244 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004245 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004246 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004247 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004248 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004249 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004250
4251exit:
4252 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004253 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004254 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004255 mbedtls_psa_crypto_free( );
4256}
4257/* END_CASE */
4258
4259/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004260void derive_full( int alg_arg,
4261 data_t *key_data,
4262 data_t *salt,
4263 data_t *label,
4264 int requested_capacity_arg )
4265{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004266 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004267 psa_algorithm_t alg = alg_arg;
4268 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004269 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004270 unsigned char output_buffer[16];
4271 size_t expected_capacity = requested_capacity;
4272 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004273 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004274
Gilles Peskine8817f612018-12-18 00:18:46 +01004275 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004276
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004277 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4278 psa_set_key_algorithm( &attributes, alg );
4279 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004280
Gilles Peskine049c7532019-05-15 20:22:09 +02004281 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4282 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004283
4284 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004285 if( PSA_ALG_IS_HKDF( alg ) )
4286 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004287 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4288 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004289 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004290 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004291 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004292 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004293 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004294 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004295 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004296 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004297 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004298 label->x, label->len ) );
4299 }
4300 else
4301 {
4302 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004303 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004304 salt->x, salt->len,
4305 label->x, label->len,
4306 requested_capacity ) );
4307 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004308 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004309 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004310 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004311
4312 /* Expansion phase. */
4313 while( current_capacity > 0 )
4314 {
4315 size_t read_size = sizeof( output_buffer );
4316 if( read_size > current_capacity )
4317 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004318 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004319 output_buffer,
4320 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004321 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004322 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004323 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004324 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004325 }
4326
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004327 /* Check that the operation refuses to go over capacity. */
4328 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004329 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004330
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004331 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004332
4333exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004334 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004335 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004336 mbedtls_psa_crypto_free( );
4337}
4338/* END_CASE */
4339
4340/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004341void derive_key_exercise( int alg_arg,
4342 data_t *key_data,
4343 data_t *salt,
4344 data_t *label,
4345 int derived_type_arg,
4346 int derived_bits_arg,
4347 int derived_usage_arg,
4348 int derived_alg_arg )
4349{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004350 psa_key_handle_t base_handle = 0;
4351 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004352 psa_algorithm_t alg = alg_arg;
4353 psa_key_type_t derived_type = derived_type_arg;
4354 size_t derived_bits = derived_bits_arg;
4355 psa_key_usage_t derived_usage = derived_usage_arg;
4356 psa_algorithm_t derived_alg = derived_alg_arg;
4357 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004358 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004359 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004360 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004361
Gilles Peskine8817f612018-12-18 00:18:46 +01004362 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004363
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004364 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4365 psa_set_key_algorithm( &attributes, alg );
4366 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004367 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4368 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004369
4370 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004371 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004372 salt->x, salt->len,
4373 label->x, label->len,
4374 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004375 psa_set_key_usage_flags( &attributes, derived_usage );
4376 psa_set_key_algorithm( &attributes, derived_alg );
4377 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004378 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004379 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004380 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004381
4382 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004383 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4384 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4385 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004386
4387 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004388 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004389 goto exit;
4390
4391exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004392 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004393 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004394 psa_destroy_key( base_handle );
4395 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004396 mbedtls_psa_crypto_free( );
4397}
4398/* END_CASE */
4399
4400/* BEGIN_CASE */
4401void derive_key_export( int alg_arg,
4402 data_t *key_data,
4403 data_t *salt,
4404 data_t *label,
4405 int bytes1_arg,
4406 int bytes2_arg )
4407{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004408 psa_key_handle_t base_handle = 0;
4409 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004410 psa_algorithm_t alg = alg_arg;
4411 size_t bytes1 = bytes1_arg;
4412 size_t bytes2 = bytes2_arg;
4413 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004414 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004415 uint8_t *output_buffer = NULL;
4416 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004417 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4418 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004419 size_t length;
4420
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004421 ASSERT_ALLOC( output_buffer, capacity );
4422 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004423 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004424
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004425 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4426 psa_set_key_algorithm( &base_attributes, alg );
4427 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004428 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4429 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004430
4431 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004432 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004433 salt->x, salt->len,
4434 label->x, label->len,
4435 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004436 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004437 output_buffer,
4438 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004439 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004440
4441 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004442 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004443 salt->x, salt->len,
4444 label->x, label->len,
4445 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004446 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4447 psa_set_key_algorithm( &derived_attributes, 0 );
4448 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004449 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004450 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004451 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004452 PSA_ASSERT( psa_export_key( derived_handle,
4453 export_buffer, bytes1,
4454 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004455 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004456 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004457 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004458 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004459 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004460 PSA_ASSERT( psa_export_key( derived_handle,
4461 export_buffer + bytes1, bytes2,
4462 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004463 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004464
4465 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004466 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4467 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004468
4469exit:
4470 mbedtls_free( output_buffer );
4471 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004472 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004473 psa_destroy_key( base_handle );
4474 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004475 mbedtls_psa_crypto_free( );
4476}
4477/* END_CASE */
4478
4479/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004480void key_agreement_setup( int alg_arg,
4481 int our_key_type_arg, data_t *our_key_data,
4482 data_t *peer_key_data,
4483 int expected_status_arg )
4484{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004485 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004486 psa_algorithm_t alg = alg_arg;
4487 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004488 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004489 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004490 psa_status_t expected_status = expected_status_arg;
4491 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004492
Gilles Peskine8817f612018-12-18 00:18:46 +01004493 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004494
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004495 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4496 psa_set_key_algorithm( &attributes, alg );
4497 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004498 PSA_ASSERT( psa_import_key( &attributes,
4499 our_key_data->x, our_key_data->len,
4500 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004501
Gilles Peskine77f40d82019-04-11 21:27:06 +02004502 /* The tests currently include inputs that should fail at either step.
4503 * Test cases that fail at the setup step should be changed to call
4504 * key_derivation_setup instead, and this function should be renamed
4505 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004506 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004507 if( status == PSA_SUCCESS )
4508 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004509 TEST_EQUAL( psa_key_derivation_key_agreement(
4510 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4511 our_key,
4512 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004513 expected_status );
4514 }
4515 else
4516 {
4517 TEST_ASSERT( status == expected_status );
4518 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004519
4520exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004521 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004522 psa_destroy_key( our_key );
4523 mbedtls_psa_crypto_free( );
4524}
4525/* END_CASE */
4526
4527/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004528void raw_key_agreement( int alg_arg,
4529 int our_key_type_arg, data_t *our_key_data,
4530 data_t *peer_key_data,
4531 data_t *expected_output )
4532{
4533 psa_key_handle_t our_key = 0;
4534 psa_algorithm_t alg = alg_arg;
4535 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004536 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004537 unsigned char *output = NULL;
4538 size_t output_length = ~0;
4539
4540 ASSERT_ALLOC( output, expected_output->len );
4541 PSA_ASSERT( psa_crypto_init( ) );
4542
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004543 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4544 psa_set_key_algorithm( &attributes, alg );
4545 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004546 PSA_ASSERT( psa_import_key( &attributes,
4547 our_key_data->x, our_key_data->len,
4548 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004549
4550 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4551 alg, our_key,
4552 peer_key_data->x, peer_key_data->len,
4553 output, expected_output->len, &output_length ) );
4554 ASSERT_COMPARE( output, output_length,
4555 expected_output->x, expected_output->len );
4556
4557exit:
4558 mbedtls_free( output );
4559 psa_destroy_key( our_key );
4560 mbedtls_psa_crypto_free( );
4561}
4562/* END_CASE */
4563
4564/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004565void key_agreement_capacity( int alg_arg,
4566 int our_key_type_arg, data_t *our_key_data,
4567 data_t *peer_key_data,
4568 int expected_capacity_arg )
4569{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004570 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004571 psa_algorithm_t alg = alg_arg;
4572 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004573 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004574 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004575 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004576 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004577
Gilles Peskine8817f612018-12-18 00:18:46 +01004578 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004579
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004580 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4581 psa_set_key_algorithm( &attributes, alg );
4582 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004583 PSA_ASSERT( psa_import_key( &attributes,
4584 our_key_data->x, our_key_data->len,
4585 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004586
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004587 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004588 PSA_ASSERT( psa_key_derivation_key_agreement(
4589 &operation,
4590 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4591 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004592 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4593 {
4594 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004595 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004596 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004597 NULL, 0 ) );
4598 }
Gilles Peskine59685592018-09-18 12:11:34 +02004599
Gilles Peskinebf491972018-10-25 22:36:12 +02004600 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004601 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004602 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004603 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004604
Gilles Peskinebf491972018-10-25 22:36:12 +02004605 /* Test the actual capacity by reading the output. */
4606 while( actual_capacity > sizeof( output ) )
4607 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004608 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004609 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004610 actual_capacity -= sizeof( output );
4611 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004612 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004613 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004614 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004615 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004616
Gilles Peskine59685592018-09-18 12:11:34 +02004617exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004618 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004619 psa_destroy_key( our_key );
4620 mbedtls_psa_crypto_free( );
4621}
4622/* END_CASE */
4623
4624/* BEGIN_CASE */
4625void key_agreement_output( int alg_arg,
4626 int our_key_type_arg, data_t *our_key_data,
4627 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004628 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004629{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004630 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004631 psa_algorithm_t alg = alg_arg;
4632 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004633 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004634 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004635 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004636
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004637 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4638 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004639
Gilles Peskine8817f612018-12-18 00:18:46 +01004640 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004641
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004642 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4643 psa_set_key_algorithm( &attributes, alg );
4644 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004645 PSA_ASSERT( psa_import_key( &attributes,
4646 our_key_data->x, our_key_data->len,
4647 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004648
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004649 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004650 PSA_ASSERT( psa_key_derivation_key_agreement(
4651 &operation,
4652 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4653 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004654 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4655 {
4656 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004657 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004658 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004659 NULL, 0 ) );
4660 }
Gilles Peskine59685592018-09-18 12:11:34 +02004661
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004662 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004663 actual_output,
4664 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004665 ASSERT_COMPARE( actual_output, expected_output1->len,
4666 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004667 if( expected_output2->len != 0 )
4668 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004669 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004670 actual_output,
4671 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004672 ASSERT_COMPARE( actual_output, expected_output2->len,
4673 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004674 }
Gilles Peskine59685592018-09-18 12:11:34 +02004675
4676exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004677 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004678 psa_destroy_key( our_key );
4679 mbedtls_psa_crypto_free( );
4680 mbedtls_free( actual_output );
4681}
4682/* END_CASE */
4683
4684/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004685void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004686{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004687 size_t bytes = bytes_arg;
4688 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004689 unsigned char *output = NULL;
4690 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004691 size_t i;
4692 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004693
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004694 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4695 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004696 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004697
Gilles Peskine8817f612018-12-18 00:18:46 +01004698 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004699
Gilles Peskinea50d7392018-06-21 10:22:13 +02004700 /* Run several times, to ensure that every output byte will be
4701 * nonzero at least once with overwhelming probability
4702 * (2^(-8*number_of_runs)). */
4703 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004704 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004705 if( bytes != 0 )
4706 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004707 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004708
4709 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004710 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4711 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004712
4713 for( i = 0; i < bytes; i++ )
4714 {
4715 if( output[i] != 0 )
4716 ++changed[i];
4717 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004718 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004719
4720 /* Check that every byte was changed to nonzero at least once. This
4721 * validates that psa_generate_random is overwriting every byte of
4722 * the output buffer. */
4723 for( i = 0; i < bytes; i++ )
4724 {
4725 TEST_ASSERT( changed[i] != 0 );
4726 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004727
4728exit:
4729 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004730 mbedtls_free( output );
4731 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004732}
4733/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004734
4735/* BEGIN_CASE */
4736void generate_key( int type_arg,
4737 int bits_arg,
4738 int usage_arg,
4739 int alg_arg,
4740 int expected_status_arg )
4741{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004742 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004743 psa_key_type_t type = type_arg;
4744 psa_key_usage_t usage = usage_arg;
4745 size_t bits = bits_arg;
4746 psa_algorithm_t alg = alg_arg;
4747 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004748 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004749 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004750
Gilles Peskine8817f612018-12-18 00:18:46 +01004751 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004752
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004753 psa_set_key_usage_flags( &attributes, usage );
4754 psa_set_key_algorithm( &attributes, alg );
4755 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004756 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004757
4758 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004759 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004760 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004761 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004762
4763 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004764 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4765 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4766 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004767
Gilles Peskine818ca122018-06-20 18:16:48 +02004768 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004769 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004770 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004771
4772exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004773 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004774 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004775 mbedtls_psa_crypto_free( );
4776}
4777/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004778
Gilles Peskinee56e8782019-04-26 17:34:02 +02004779/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4780void generate_key_rsa( int bits_arg,
4781 data_t *e_arg,
4782 int expected_status_arg )
4783{
4784 psa_key_handle_t handle = 0;
4785 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEYPAIR;
4786 size_t bits = bits_arg;
4787 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4788 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4789 psa_status_t expected_status = expected_status_arg;
4790 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4791 uint8_t *exported = NULL;
4792 size_t exported_size =
4793 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4794 size_t exported_length = SIZE_MAX;
4795 uint8_t *e_read_buffer = NULL;
4796 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004797 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004798 size_t e_read_length = SIZE_MAX;
4799
4800 if( e_arg->len == 0 ||
4801 ( e_arg->len == 3 &&
4802 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4803 {
4804 is_default_public_exponent = 1;
4805 e_read_size = 0;
4806 }
4807 ASSERT_ALLOC( e_read_buffer, e_read_size );
4808 ASSERT_ALLOC( exported, exported_size );
4809
4810 PSA_ASSERT( psa_crypto_init( ) );
4811
4812 psa_set_key_usage_flags( &attributes, usage );
4813 psa_set_key_algorithm( &attributes, alg );
4814 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4815 e_arg->x, e_arg->len ) );
4816 psa_set_key_bits( &attributes, bits );
4817
4818 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004819 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004820 if( expected_status != PSA_SUCCESS )
4821 goto exit;
4822
4823 /* Test the key information */
4824 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4825 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4826 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4827 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4828 e_read_buffer, e_read_size,
4829 &e_read_length ) );
4830 if( is_default_public_exponent )
4831 TEST_EQUAL( e_read_length, 0 );
4832 else
4833 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4834
4835 /* Do something with the key according to its type and permitted usage. */
4836 if( ! exercise_key( handle, usage, alg ) )
4837 goto exit;
4838
4839 /* Export the key and check the public exponent. */
4840 PSA_ASSERT( psa_export_public_key( handle,
4841 exported, exported_size,
4842 &exported_length ) );
4843 {
4844 uint8_t *p = exported;
4845 uint8_t *end = exported + exported_length;
4846 size_t len;
4847 /* RSAPublicKey ::= SEQUENCE {
4848 * modulus INTEGER, -- n
4849 * publicExponent INTEGER } -- e
4850 */
4851 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004852 MBEDTLS_ASN1_SEQUENCE |
4853 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004854 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4855 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4856 MBEDTLS_ASN1_INTEGER ) );
4857 if( len >= 1 && p[0] == 0 )
4858 {
4859 ++p;
4860 --len;
4861 }
4862 if( e_arg->len == 0 )
4863 {
4864 TEST_EQUAL( len, 3 );
4865 TEST_EQUAL( p[0], 1 );
4866 TEST_EQUAL( p[1], 0 );
4867 TEST_EQUAL( p[2], 1 );
4868 }
4869 else
4870 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4871 }
4872
4873exit:
4874 psa_reset_key_attributes( &attributes );
4875 psa_destroy_key( handle );
4876 mbedtls_psa_crypto_free( );
4877 mbedtls_free( e_read_buffer );
4878 mbedtls_free( exported );
4879}
4880/* END_CASE */
4881
Darryl Greend49a4992018-06-18 17:27:26 +01004882/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004883void persistent_key_load_key_from_storage( data_t *data,
4884 int type_arg, int bits_arg,
4885 int usage_flags_arg, int alg_arg,
4886 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004887{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004888 psa_key_id_t key_id = 1;
4889 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004890 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004891 psa_key_handle_t base_key = 0;
4892 psa_key_type_t type = type_arg;
4893 size_t bits = bits_arg;
4894 psa_key_usage_t usage_flags = usage_flags_arg;
4895 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004896 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004897 unsigned char *first_export = NULL;
4898 unsigned char *second_export = NULL;
4899 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4900 size_t first_exported_length;
4901 size_t second_exported_length;
4902
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004903 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4904 {
4905 ASSERT_ALLOC( first_export, export_size );
4906 ASSERT_ALLOC( second_export, export_size );
4907 }
Darryl Greend49a4992018-06-18 17:27:26 +01004908
Gilles Peskine8817f612018-12-18 00:18:46 +01004909 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004910
Gilles Peskinec87af662019-05-15 16:12:22 +02004911 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004912 psa_set_key_usage_flags( &attributes, usage_flags );
4913 psa_set_key_algorithm( &attributes, alg );
4914 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004915 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004916
Darryl Green0c6575a2018-11-07 16:05:30 +00004917 switch( generation_method )
4918 {
4919 case IMPORT_KEY:
4920 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004921 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4922 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004923 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004924
Darryl Green0c6575a2018-11-07 16:05:30 +00004925 case GENERATE_KEY:
4926 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004927 PSA_ASSERT( psa_generate_random_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004928 break;
4929
4930 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004931 {
4932 /* Create base key */
4933 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4934 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4935 psa_set_key_usage_flags( &base_attributes,
4936 PSA_KEY_USAGE_DERIVE );
4937 psa_set_key_algorithm( &base_attributes, derive_alg );
4938 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004939 PSA_ASSERT( psa_import_key( &base_attributes,
4940 data->x, data->len,
4941 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004942 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004943 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004944 PSA_ASSERT( psa_key_derivation_input_key(
4945 &operation,
4946 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004947 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004948 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004949 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004950 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
4951 &operation,
4952 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004953 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004954 PSA_ASSERT( psa_destroy_key( base_key ) );
4955 base_key = 0;
4956 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004957 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00004958 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004959 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004960
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004961 /* Export the key if permitted by the key policy. */
4962 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4963 {
4964 PSA_ASSERT( psa_export_key( handle,
4965 first_export, export_size,
4966 &first_exported_length ) );
4967 if( generation_method == IMPORT_KEY )
4968 ASSERT_COMPARE( data->x, data->len,
4969 first_export, first_exported_length );
4970 }
Darryl Greend49a4992018-06-18 17:27:26 +01004971
4972 /* Shutdown and restart */
4973 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004974 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004975
Darryl Greend49a4992018-06-18 17:27:26 +01004976 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02004977 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004978 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4979 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4980 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4981 PSA_KEY_LIFETIME_PERSISTENT );
4982 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4983 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4984 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4985 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004986
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004987 /* Export the key again if permitted by the key policy. */
4988 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004989 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004990 PSA_ASSERT( psa_export_key( handle,
4991 second_export, export_size,
4992 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004993 ASSERT_COMPARE( first_export, first_exported_length,
4994 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004995 }
4996
4997 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004998 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004999 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005000
5001exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005002 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005003 mbedtls_free( first_export );
5004 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005005 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005006 psa_destroy_key( base_key );
5007 if( handle == 0 )
5008 {
5009 /* In case there was a test failure after creating the persistent key
5010 * but while it was not open, try to re-open the persistent key
5011 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005012 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005013 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005014 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01005015 mbedtls_psa_crypto_free();
5016}
5017/* END_CASE */