blob: e695ea568c2d9af842ea2d53d902bedfe13bc10d [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
Gilles Peskinebe697d82019-05-16 18:00:41 +0200637 status = psa_raw_key_agreement( alg, handle,
638 public_key, public_key_length,
639 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200640exit:
641 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200642 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200643 return( status );
644}
645
646static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
647 psa_key_usage_t usage,
648 psa_algorithm_t alg )
649{
650 int ok = 0;
651
652 if( usage & PSA_KEY_USAGE_DERIVE )
653 {
654 /* We need two keys to exercise key agreement. Exercise the
655 * private key against its own public key. */
656 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
657 }
658 ok = 1;
659
660exit:
661 return( ok );
662}
663
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100664static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200665 psa_key_usage_t usage,
666 psa_algorithm_t alg )
667{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200668 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200669 unsigned char output[1];
670 int ok = 0;
671
672 if( usage & PSA_KEY_USAGE_DERIVE )
673 {
674 /* We need two keys to exercise key agreement. Exercise the
675 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200676 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
677 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
678 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200679 output,
680 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200681 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200682 }
683 ok = 1;
684
685exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200686 return( ok );
687}
688
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200689static int is_oid_of_key_type( psa_key_type_t type,
690 const uint8_t *oid, size_t oid_length )
691{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200692 const uint8_t *expected_oid = NULL;
693 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200694#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200695 if( PSA_KEY_TYPE_IS_RSA( type ) )
696 {
697 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
698 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
699 }
700 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200701#endif /* MBEDTLS_RSA_C */
702#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200703 if( PSA_KEY_TYPE_IS_ECC( type ) )
704 {
705 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
706 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
707 }
708 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200709#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200710 {
711 char message[40];
712 mbedtls_snprintf( message, sizeof( message ),
713 "OID not known for key type=0x%08lx",
714 (unsigned long) type );
715 test_fail( message, __LINE__, __FILE__ );
716 return( 0 );
717 }
718
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200719 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200720 return( 1 );
721
722exit:
723 return( 0 );
724}
725
726static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
727 size_t min_bits, size_t max_bits,
728 int must_be_odd )
729{
730 size_t len;
731 size_t actual_bits;
732 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100733 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100734 MBEDTLS_ASN1_INTEGER ),
735 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200736 /* Tolerate a slight departure from DER encoding:
737 * - 0 may be represented by an empty string or a 1-byte string.
738 * - The sign bit may be used as a value bit. */
739 if( ( len == 1 && ( *p )[0] == 0 ) ||
740 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
741 {
742 ++( *p );
743 --len;
744 }
745 if( min_bits == 0 && len == 0 )
746 return( 1 );
747 msb = ( *p )[0];
748 TEST_ASSERT( msb != 0 );
749 actual_bits = 8 * ( len - 1 );
750 while( msb != 0 )
751 {
752 msb >>= 1;
753 ++actual_bits;
754 }
755 TEST_ASSERT( actual_bits >= min_bits );
756 TEST_ASSERT( actual_bits <= max_bits );
757 if( must_be_odd )
758 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
759 *p += len;
760 return( 1 );
761exit:
762 return( 0 );
763}
764
765static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
766 size_t *len,
767 unsigned char n, unsigned char tag )
768{
769 int ret;
770 ret = mbedtls_asn1_get_tag( p, end, len,
771 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
772 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
773 if( ret != 0 )
774 return( ret );
775 end = *p + *len;
776 ret = mbedtls_asn1_get_tag( p, end, len, tag );
777 if( ret != 0 )
778 return( ret );
779 if( *p + *len != end )
780 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
781 return( 0 );
782}
783
784static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
785 uint8_t *exported, size_t exported_length )
786{
787 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100788 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200789 else
790 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200791
792#if defined(MBEDTLS_DES_C)
793 if( type == PSA_KEY_TYPE_DES )
794 {
795 /* Check the parity bits. */
796 unsigned i;
797 for( i = 0; i < bits / 8; i++ )
798 {
799 unsigned bit_count = 0;
800 unsigned m;
801 for( m = 1; m <= 0x100; m <<= 1 )
802 {
803 if( exported[i] & m )
804 ++bit_count;
805 }
806 TEST_ASSERT( bit_count % 2 != 0 );
807 }
808 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200809 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200810#endif
811
812#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
813 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
814 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200815 uint8_t *p = exported;
816 uint8_t *end = exported + exported_length;
817 size_t len;
818 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200819 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200820 * modulus INTEGER, -- n
821 * publicExponent INTEGER, -- e
822 * privateExponent INTEGER, -- d
823 * prime1 INTEGER, -- p
824 * prime2 INTEGER, -- q
825 * exponent1 INTEGER, -- d mod (p-1)
826 * exponent2 INTEGER, -- d mod (q-1)
827 * coefficient INTEGER, -- (inverse of q) mod p
828 * }
829 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100830 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
831 MBEDTLS_ASN1_SEQUENCE |
832 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
833 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200834 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
835 goto exit;
836 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
837 goto exit;
838 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
839 goto exit;
840 /* Require d to be at least half the size of n. */
841 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
842 goto exit;
843 /* Require p and q to be at most half the size of n, rounded up. */
844 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
845 goto exit;
846 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
847 goto exit;
848 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
849 goto exit;
850 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
851 goto exit;
852 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
853 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100854 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100855 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200856 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200857#endif /* MBEDTLS_RSA_C */
858
859#if defined(MBEDTLS_ECP_C)
860 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
861 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100862 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100863 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100864 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200865 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200866#endif /* MBEDTLS_ECP_C */
867
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200868 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
869 {
870 uint8_t *p = exported;
871 uint8_t *end = exported + exported_length;
872 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200873#if defined(MBEDTLS_RSA_C)
874 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
875 {
876 /* RSAPublicKey ::= SEQUENCE {
877 * modulus INTEGER, -- n
878 * publicExponent INTEGER } -- e
879 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100880 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
881 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100882 MBEDTLS_ASN1_CONSTRUCTED ),
883 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100884 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200885 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
886 goto exit;
887 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
888 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100889 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200890 }
891 else
892#endif /* MBEDTLS_RSA_C */
893#if defined(MBEDTLS_ECP_C)
894 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
895 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000896 /* The representation of an ECC public key is:
897 * - The byte 0x04;
898 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
899 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
900 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000901 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100902 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
903 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200904 }
905 else
906#endif /* MBEDTLS_ECP_C */
907 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100908 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200909 mbedtls_snprintf( message, sizeof( message ),
910 "No sanity check for public key type=0x%08lx",
911 (unsigned long) type );
912 test_fail( message, __LINE__, __FILE__ );
913 return( 0 );
914 }
915 }
916 else
917
918 {
919 /* No sanity checks for other types */
920 }
921
922 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200923
924exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200925 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200926}
927
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100928static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200929 psa_key_usage_t usage )
930{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200931 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200932 uint8_t *exported = NULL;
933 size_t exported_size = 0;
934 size_t exported_length = 0;
935 int ok = 0;
936
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200937 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200938
939 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200940 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200941 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100942 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
943 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200944 ok = 1;
945 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200946 }
947
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200948 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
949 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200950 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200951
Gilles Peskine8817f612018-12-18 00:18:46 +0100952 PSA_ASSERT( psa_export_key( handle,
953 exported, exported_size,
954 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200955 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
956 psa_get_key_bits( &attributes ),
957 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200958
959exit:
960 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200961 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200962 return( ok );
963}
964
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100965static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200966{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200968 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200969 uint8_t *exported = NULL;
970 size_t exported_size = 0;
971 size_t exported_length = 0;
972 int ok = 0;
973
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200974 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
975 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200976 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100977 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100978 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200979 return( 1 );
980 }
981
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200982 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
983 psa_get_key_type( &attributes ) );
984 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
985 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200986 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200987
Gilles Peskine8817f612018-12-18 00:18:46 +0100988 PSA_ASSERT( psa_export_public_key( handle,
989 exported, exported_size,
990 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200991 ok = exported_key_sanity_check( public_type,
992 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200993 exported, exported_length );
994
995exit:
996 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200997 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200998 return( ok );
999}
1000
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001001/** Do smoke tests on a key.
1002 *
1003 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1004 * sign/verify, or derivation) that is permitted according to \p usage.
1005 * \p usage and \p alg should correspond to the expected policy on the
1006 * key.
1007 *
1008 * Export the key if permitted by \p usage, and check that the output
1009 * looks sensible. If \p usage forbids export, check that
1010 * \p psa_export_key correctly rejects the attempt. If the key is
1011 * asymmetric, also check \p psa_export_public_key.
1012 *
1013 * If the key fails the tests, this function calls the test framework's
1014 * `test_fail` function and returns false. Otherwise this function returns
1015 * true. Therefore it should be used as follows:
1016 * ```
1017 * if( ! exercise_key( ... ) ) goto exit;
1018 * ```
1019 *
1020 * \param handle The key to exercise. It should be capable of performing
1021 * \p alg.
1022 * \param usage The usage flags to assume.
1023 * \param alg The algorithm to exercise.
1024 *
1025 * \retval 0 The key failed the smoke tests.
1026 * \retval 1 The key passed the smoke tests.
1027 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001029 psa_key_usage_t usage,
1030 psa_algorithm_t alg )
1031{
1032 int ok;
1033 if( alg == 0 )
1034 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1035 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001036 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001037 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001038 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001039 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001040 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001041 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001042 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001043 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001044 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001045 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001046 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001047 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1048 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001049 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001050 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001051 else
1052 {
1053 char message[40];
1054 mbedtls_snprintf( message, sizeof( message ),
1055 "No code to exercise alg=0x%08lx",
1056 (unsigned long) alg );
1057 test_fail( message, __LINE__, __FILE__ );
1058 ok = 0;
1059 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001060
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001061 ok = ok && exercise_export_key( handle, usage );
1062 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001063
Gilles Peskine02b75072018-07-01 22:31:34 +02001064 return( ok );
1065}
1066
Gilles Peskine10df3412018-10-25 22:35:43 +02001067static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1068 psa_algorithm_t alg )
1069{
1070 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1071 {
1072 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1073 PSA_KEY_USAGE_VERIFY :
1074 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1075 }
1076 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1077 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1078 {
1079 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1080 PSA_KEY_USAGE_ENCRYPT :
1081 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1082 }
1083 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1084 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1085 {
1086 return( PSA_KEY_USAGE_DERIVE );
1087 }
1088 else
1089 {
1090 return( 0 );
1091 }
1092
1093}
Darryl Green0c6575a2018-11-07 16:05:30 +00001094
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001095static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1096{
1097 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1098 uint8_t buffer[1];
1099 size_t length;
1100 int ok = 0;
1101
Gilles Peskinec87af662019-05-15 16:12:22 +02001102 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001103 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1104 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1105 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1106 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1107 PSA_ERROR_INVALID_HANDLE );
1108 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001109 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001110 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1111 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1112 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1113 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1114
1115 TEST_EQUAL( psa_export_key( handle,
1116 buffer, sizeof( buffer ), &length ),
1117 PSA_ERROR_INVALID_HANDLE );
1118 TEST_EQUAL( psa_export_public_key( handle,
1119 buffer, sizeof( buffer ), &length ),
1120 PSA_ERROR_INVALID_HANDLE );
1121
1122 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1123 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1124
1125 ok = 1;
1126
1127exit:
1128 psa_reset_key_attributes( &attributes );
1129 return( ok );
1130}
1131
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001132/* An overapproximation of the amount of storage needed for a key of the
1133 * given type and with the given content. The API doesn't make it easy
1134 * to find a good value for the size. The current implementation doesn't
1135 * care about the value anyway. */
1136#define KEY_BITS_FROM_DATA( type, data ) \
1137 ( data )->len
1138
Darryl Green0c6575a2018-11-07 16:05:30 +00001139typedef enum {
1140 IMPORT_KEY = 0,
1141 GENERATE_KEY = 1,
1142 DERIVE_KEY = 2
1143} generate_method;
1144
Gilles Peskinee59236f2018-01-27 23:32:46 +01001145/* END_HEADER */
1146
1147/* BEGIN_DEPENDENCIES
1148 * depends_on:MBEDTLS_PSA_CRYPTO_C
1149 * END_DEPENDENCIES
1150 */
1151
1152/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001153void static_checks( )
1154{
1155 size_t max_truncated_mac_size =
1156 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1157
1158 /* Check that the length for a truncated MAC always fits in the algorithm
1159 * encoding. The shifted mask is the maximum truncated value. The
1160 * untruncated algorithm may be one byte larger. */
1161 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1162}
1163/* END_CASE */
1164
1165/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001166void attributes_set_get( int id_arg, int lifetime_arg,
1167 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001168 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001169{
Gilles Peskine4747d192019-04-17 15:05:45 +02001170 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001171 psa_key_id_t id = id_arg;
1172 psa_key_lifetime_t lifetime = lifetime_arg;
1173 psa_key_usage_t usage_flags = usage_flags_arg;
1174 psa_algorithm_t alg = alg_arg;
1175 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001176 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001177
1178 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1179 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1182 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001183 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001184
Gilles Peskinec87af662019-05-15 16:12:22 +02001185 psa_set_key_id( &attributes, id );
1186 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001187 psa_set_key_usage_flags( &attributes, usage_flags );
1188 psa_set_key_algorithm( &attributes, alg );
1189 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001190 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001191
1192 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1193 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1194 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1195 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1196 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001197 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001198
1199 psa_reset_key_attributes( &attributes );
1200
1201 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1202 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1203 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1204 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1205 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001206 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001207}
1208/* END_CASE */
1209
1210/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001211void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1212 int expected_id_arg, int expected_lifetime_arg )
1213{
1214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1215 psa_key_id_t id1 = id1_arg;
1216 psa_key_lifetime_t lifetime = lifetime_arg;
1217 psa_key_id_t id2 = id2_arg;
1218 psa_key_id_t expected_id = expected_id_arg;
1219 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1220
1221 if( id1_arg != -1 )
1222 psa_set_key_id( &attributes, id1 );
1223 if( lifetime_arg != -1 )
1224 psa_set_key_lifetime( &attributes, lifetime );
1225 if( id2_arg != -1 )
1226 psa_set_key_id( &attributes, id2 );
1227
1228 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1229 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1230}
1231/* END_CASE */
1232
1233/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001234void import( data_t *data, int type_arg,
1235 int attr_bits_arg,
1236 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001237{
1238 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1239 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001240 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001241 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001242 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001243 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001244 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001245
Gilles Peskine8817f612018-12-18 00:18:46 +01001246 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001247
Gilles Peskine4747d192019-04-17 15:05:45 +02001248 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001249 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001250 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001251 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001252 if( status != PSA_SUCCESS )
1253 goto exit;
1254
1255 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1256 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001257 if( attr_bits != 0 )
1258 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001259
1260 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001261 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001262
1263exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001264 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001265 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001266 mbedtls_psa_crypto_free( );
1267}
1268/* END_CASE */
1269
1270/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001271void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1272{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001273 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001274 size_t bits = bits_arg;
1275 psa_status_t expected_status = expected_status_arg;
1276 psa_status_t status;
1277 psa_key_type_t type =
1278 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1279 size_t buffer_size = /* Slight overapproximations */
1280 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001281 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001282 unsigned char *p;
1283 int ret;
1284 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001285 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001286
Gilles Peskine8817f612018-12-18 00:18:46 +01001287 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001288 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001289
1290 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1291 bits, keypair ) ) >= 0 );
1292 length = ret;
1293
1294 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001295 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001296 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001297 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001298 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001299 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001300
1301exit:
1302 mbedtls_free( buffer );
1303 mbedtls_psa_crypto_free( );
1304}
1305/* END_CASE */
1306
1307/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001308void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001309 int type_arg,
1310 int alg_arg,
1311 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001312 int expected_bits,
1313 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001314 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001315 int canonical_input )
1316{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001317 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001318 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001319 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001320 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001321 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001322 unsigned char *exported = NULL;
1323 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001324 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001325 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001326 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001327 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001328 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001329
Moran Pekercb088e72018-07-17 17:36:59 +03001330 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001331 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001332 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001333 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001334 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001335
Gilles Peskine4747d192019-04-17 15:05:45 +02001336 psa_set_key_usage_flags( &attributes, usage_arg );
1337 psa_set_key_algorithm( &attributes, alg );
1338 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001339
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001340 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001341 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001342
1343 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001344 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1345 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1346 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001347
1348 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001349 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001350 exported, export_size,
1351 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001352 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001353
1354 /* The exported length must be set by psa_export_key() to a value between 0
1355 * and export_size. On errors, the exported length must be 0. */
1356 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1357 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1358 TEST_ASSERT( exported_length <= export_size );
1359
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001360 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001361 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001362 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001363 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001364 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001365 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001366 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001367
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001368 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001369 goto exit;
1370
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001371 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001372 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001373 else
1374 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001375 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001376 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1377 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001378 PSA_ASSERT( psa_export_key( handle2,
1379 reexported,
1380 export_size,
1381 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001382 ASSERT_COMPARE( exported, exported_length,
1383 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001384 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001385 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001386 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001387
1388destroy:
1389 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001390 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001391 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001392
1393exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001394 mbedtls_free( exported );
1395 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001396 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001397 mbedtls_psa_crypto_free( );
1398}
1399/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001400
Moran Pekerf709f4a2018-06-06 17:26:04 +03001401/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001402void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001403{
Gilles Peskine8817f612018-12-18 00:18:46 +01001404 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001405 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001406
1407exit:
1408 mbedtls_psa_crypto_free( );
1409}
1410/* END_CASE */
1411
1412/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001413void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001414 int type_arg,
1415 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001416 int export_size_delta,
1417 int expected_export_status_arg,
1418 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001419{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001420 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001421 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001422 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001423 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001424 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001425 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001426 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001427 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001428 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001429
Gilles Peskine8817f612018-12-18 00:18:46 +01001430 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001431
Gilles Peskine4747d192019-04-17 15:05:45 +02001432 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1433 psa_set_key_algorithm( &attributes, alg );
1434 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001435
1436 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001437 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001438
Gilles Peskine49c25912018-10-29 15:15:31 +01001439 /* Export the public key */
1440 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001441 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001442 exported, export_size,
1443 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001444 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001445 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001446 {
1447 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1448 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001449 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1450 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001451 TEST_ASSERT( expected_public_key->len <=
1452 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001453 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1454 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001455 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001456
1457exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001458 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001459 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001460 psa_reset_key_attributes( &attributes );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001461 mbedtls_psa_crypto_free( );
1462}
1463/* END_CASE */
1464
Gilles Peskine20035e32018-02-03 22:44:14 +01001465/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001466void import_and_exercise_key( data_t *data,
1467 int type_arg,
1468 int bits_arg,
1469 int alg_arg )
1470{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001471 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001472 psa_key_type_t type = type_arg;
1473 size_t bits = bits_arg;
1474 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001475 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001476 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001477 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001478
Gilles Peskine8817f612018-12-18 00:18:46 +01001479 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001480
Gilles Peskine4747d192019-04-17 15:05:45 +02001481 psa_set_key_usage_flags( &attributes, usage );
1482 psa_set_key_algorithm( &attributes, alg );
1483 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001484
1485 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001486 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001487
1488 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001489 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1490 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1491 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001492
1493 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001494 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001495 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001496
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001497 PSA_ASSERT( psa_destroy_key( handle ) );
1498 test_operations_on_invalid_handle( handle );
1499
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001500exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001501 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001502 psa_reset_key_attributes( &got_attributes );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001503 mbedtls_psa_crypto_free( );
1504}
1505/* END_CASE */
1506
1507/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001508void key_policy( int usage_arg, int alg_arg )
1509{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001510 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001511 psa_algorithm_t alg = alg_arg;
1512 psa_key_usage_t usage = usage_arg;
1513 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1514 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001515 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001516
1517 memset( key, 0x2a, sizeof( key ) );
1518
Gilles Peskine8817f612018-12-18 00:18:46 +01001519 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001520
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001521 psa_set_key_usage_flags( &attributes, usage );
1522 psa_set_key_algorithm( &attributes, alg );
1523 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001524
Gilles Peskine73676cb2019-05-15 20:15:10 +02001525 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001526
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001527 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1528 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1529 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1530 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001531
1532exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001533 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001534 psa_reset_key_attributes( &attributes );
Gilles Peskined5b33222018-06-18 22:20:03 +02001535 mbedtls_psa_crypto_free( );
1536}
1537/* END_CASE */
1538
1539/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001540void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001541{
1542 /* Test each valid way of initializing the object, except for `= {0}`, as
1543 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1544 * though it's OK by the C standard. We could test for this, but we'd need
1545 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001546 psa_key_attributes_t func = psa_key_attributes_init( );
1547 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1548 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001549
1550 memset( &zero, 0, sizeof( zero ) );
1551
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001552 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1553 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1554 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001555
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001556 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1557 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1558 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1559
1560 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1561 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1562 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1563
1564 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1565 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1566 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1567
1568 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1569 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1570 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001571}
1572/* END_CASE */
1573
1574/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001575void mac_key_policy( int policy_usage,
1576 int policy_alg,
1577 int key_type,
1578 data_t *key_data,
1579 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001580{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001581 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001582 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001583 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001584 psa_status_t status;
1585 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001586
Gilles Peskine8817f612018-12-18 00:18:46 +01001587 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001588
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001589 psa_set_key_usage_flags( &attributes, policy_usage );
1590 psa_set_key_algorithm( &attributes, policy_alg );
1591 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001592
Gilles Peskine049c7532019-05-15 20:22:09 +02001593 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1594 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001595
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001596 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001597 if( policy_alg == exercise_alg &&
1598 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001599 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001600 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001601 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001602 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001603
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001604 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001605 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001606 if( policy_alg == exercise_alg &&
1607 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001608 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001609 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001610 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001611
1612exit:
1613 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001614 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001615 mbedtls_psa_crypto_free( );
1616}
1617/* END_CASE */
1618
1619/* BEGIN_CASE */
1620void cipher_key_policy( int policy_usage,
1621 int policy_alg,
1622 int key_type,
1623 data_t *key_data,
1624 int exercise_alg )
1625{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001626 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001627 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001628 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001629 psa_status_t status;
1630
Gilles Peskine8817f612018-12-18 00:18:46 +01001631 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001632
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001633 psa_set_key_usage_flags( &attributes, policy_usage );
1634 psa_set_key_algorithm( &attributes, policy_alg );
1635 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001636
Gilles Peskine049c7532019-05-15 20:22:09 +02001637 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1638 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001639
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001640 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001641 if( policy_alg == exercise_alg &&
1642 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001643 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001644 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001645 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001646 psa_cipher_abort( &operation );
1647
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001648 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001649 if( policy_alg == exercise_alg &&
1650 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001651 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001652 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001653 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654
1655exit:
1656 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001657 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001658 mbedtls_psa_crypto_free( );
1659}
1660/* END_CASE */
1661
1662/* BEGIN_CASE */
1663void aead_key_policy( int policy_usage,
1664 int policy_alg,
1665 int key_type,
1666 data_t *key_data,
1667 int nonce_length_arg,
1668 int tag_length_arg,
1669 int exercise_alg )
1670{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001671 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001672 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001673 psa_status_t status;
1674 unsigned char nonce[16] = {0};
1675 size_t nonce_length = nonce_length_arg;
1676 unsigned char tag[16];
1677 size_t tag_length = tag_length_arg;
1678 size_t output_length;
1679
1680 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1681 TEST_ASSERT( tag_length <= sizeof( tag ) );
1682
Gilles Peskine8817f612018-12-18 00:18:46 +01001683 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001684
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001685 psa_set_key_usage_flags( &attributes, policy_usage );
1686 psa_set_key_algorithm( &attributes, policy_alg );
1687 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001688
Gilles Peskine049c7532019-05-15 20:22:09 +02001689 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1690 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001691
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001692 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001693 nonce, nonce_length,
1694 NULL, 0,
1695 NULL, 0,
1696 tag, tag_length,
1697 &output_length );
1698 if( policy_alg == exercise_alg &&
1699 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001700 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001701 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001702 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001703
1704 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001705 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001706 nonce, nonce_length,
1707 NULL, 0,
1708 tag, tag_length,
1709 NULL, 0,
1710 &output_length );
1711 if( policy_alg == exercise_alg &&
1712 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001713 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001714 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001715 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716
1717exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001718 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001719 mbedtls_psa_crypto_free( );
1720}
1721/* END_CASE */
1722
1723/* BEGIN_CASE */
1724void asymmetric_encryption_key_policy( int policy_usage,
1725 int policy_alg,
1726 int key_type,
1727 data_t *key_data,
1728 int exercise_alg )
1729{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001730 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001731 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001732 psa_status_t status;
1733 size_t key_bits;
1734 size_t buffer_length;
1735 unsigned char *buffer = NULL;
1736 size_t output_length;
1737
Gilles Peskine8817f612018-12-18 00:18:46 +01001738 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001739
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001740 psa_set_key_usage_flags( &attributes, policy_usage );
1741 psa_set_key_algorithm( &attributes, policy_alg );
1742 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001743
Gilles Peskine049c7532019-05-15 20:22:09 +02001744 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1745 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001746
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001747 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1748 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001749 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1750 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001751 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001752
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001753 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001754 NULL, 0,
1755 NULL, 0,
1756 buffer, buffer_length,
1757 &output_length );
1758 if( policy_alg == exercise_alg &&
1759 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001760 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001761 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001762 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001763
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001764 if( buffer_length != 0 )
1765 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001766 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767 buffer, buffer_length,
1768 NULL, 0,
1769 buffer, buffer_length,
1770 &output_length );
1771 if( policy_alg == exercise_alg &&
1772 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001773 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001774 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001775 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001776
1777exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001778 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001779 psa_reset_key_attributes( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001780 mbedtls_psa_crypto_free( );
1781 mbedtls_free( buffer );
1782}
1783/* END_CASE */
1784
1785/* BEGIN_CASE */
1786void asymmetric_signature_key_policy( int policy_usage,
1787 int policy_alg,
1788 int key_type,
1789 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001790 int exercise_alg,
1791 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001792{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001793 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001794 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001795 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001796 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1797 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1798 * compatible with the policy and `payload_length_arg` is supposed to be
1799 * a valid input length to sign. If `payload_length_arg <= 0`,
1800 * `exercise_alg` is supposed to be forbidden by the policy. */
1801 int compatible_alg = payload_length_arg > 0;
1802 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001803 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1804 size_t signature_length;
1805
Gilles Peskine8817f612018-12-18 00:18:46 +01001806 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001807
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001808 psa_set_key_usage_flags( &attributes, policy_usage );
1809 psa_set_key_algorithm( &attributes, policy_alg );
1810 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001811
Gilles Peskine049c7532019-05-15 20:22:09 +02001812 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1813 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001814
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001815 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001816 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001817 signature, sizeof( signature ),
1818 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001819 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001820 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001821 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001822 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001823
1824 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001825 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001826 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001827 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001828 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001829 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001830 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001831 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001832
1833exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001834 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001835 mbedtls_psa_crypto_free( );
1836}
1837/* END_CASE */
1838
1839/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001840void derive_key_policy( int policy_usage,
1841 int policy_alg,
1842 int key_type,
1843 data_t *key_data,
1844 int exercise_alg )
1845{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001846 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001847 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001848 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001849 psa_status_t status;
1850
Gilles Peskine8817f612018-12-18 00:18:46 +01001851 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001852
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001853 psa_set_key_usage_flags( &attributes, policy_usage );
1854 psa_set_key_algorithm( &attributes, policy_alg );
1855 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001856
Gilles Peskine049c7532019-05-15 20:22:09 +02001857 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1858 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001859
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001860 status = psa_key_derivation( &operation, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001861 exercise_alg,
1862 NULL, 0,
1863 NULL, 0,
1864 1 );
1865 if( policy_alg == exercise_alg &&
1866 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001867 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001868 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001869 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001870
1871exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001872 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001873 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001874 mbedtls_psa_crypto_free( );
1875}
1876/* END_CASE */
1877
1878/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001879void agreement_key_policy( int policy_usage,
1880 int policy_alg,
1881 int key_type_arg,
1882 data_t *key_data,
1883 int exercise_alg )
1884{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001885 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001886 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001887 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001888 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001889 psa_status_t status;
1890
Gilles Peskine8817f612018-12-18 00:18:46 +01001891 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001892
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001893 psa_set_key_usage_flags( &attributes, policy_usage );
1894 psa_set_key_algorithm( &attributes, policy_alg );
1895 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001896
Gilles Peskine049c7532019-05-15 20:22:09 +02001897 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1898 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001899
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001900 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1901 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001902
Gilles Peskine01d718c2018-09-18 12:01:02 +02001903 if( policy_alg == exercise_alg &&
1904 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001905 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001906 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001907 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001908
1909exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001910 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001911 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001912 mbedtls_psa_crypto_free( );
1913}
1914/* END_CASE */
1915
1916/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001917void raw_agreement_key_policy( int policy_usage,
1918 int policy_alg,
1919 int key_type_arg,
1920 data_t *key_data,
1921 int exercise_alg )
1922{
1923 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001924 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001925 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001926 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001927 psa_status_t status;
1928
1929 PSA_ASSERT( psa_crypto_init( ) );
1930
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001931 psa_set_key_usage_flags( &attributes, policy_usage );
1932 psa_set_key_algorithm( &attributes, policy_alg );
1933 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001934
Gilles Peskine049c7532019-05-15 20:22:09 +02001935 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1936 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001937
1938 status = raw_key_agreement_with_self( exercise_alg, handle );
1939
1940 if( policy_alg == exercise_alg &&
1941 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1942 PSA_ASSERT( status );
1943 else
1944 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1945
1946exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001947 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001948 psa_destroy_key( handle );
1949 mbedtls_psa_crypto_free( );
1950}
1951/* END_CASE */
1952
1953/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02001954void copy_success( int source_usage_arg, int source_alg_arg,
1955 int type_arg, data_t *material,
1956 int copy_attributes,
1957 int target_usage_arg, int target_alg_arg,
1958 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001959{
Gilles Peskineca25db92019-04-19 11:43:08 +02001960 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1961 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001962 psa_key_usage_t expected_usage = expected_usage_arg;
1963 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001964 psa_key_handle_t source_handle = 0;
1965 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001966 uint8_t *export_buffer = NULL;
1967
Gilles Peskine57ab7212019-01-28 13:03:09 +01001968 PSA_ASSERT( psa_crypto_init( ) );
1969
Gilles Peskineca25db92019-04-19 11:43:08 +02001970 /* Prepare the source key. */
1971 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1972 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1973 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02001974 PSA_ASSERT( psa_import_key( &source_attributes,
1975 material->x, material->len,
1976 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001977 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001978
Gilles Peskineca25db92019-04-19 11:43:08 +02001979 /* Prepare the target attributes. */
1980 if( copy_attributes )
1981 target_attributes = source_attributes;
1982 if( target_usage_arg != -1 )
1983 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1984 if( target_alg_arg != -1 )
1985 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001986
1987 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02001988 PSA_ASSERT( psa_copy_key( source_handle,
1989 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001990
1991 /* Destroy the source to ensure that this doesn't affect the target. */
1992 PSA_ASSERT( psa_destroy_key( source_handle ) );
1993
1994 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001995 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1996 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1997 psa_get_key_type( &target_attributes ) );
1998 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1999 psa_get_key_bits( &target_attributes ) );
2000 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2001 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002002 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2003 {
2004 size_t length;
2005 ASSERT_ALLOC( export_buffer, material->len );
2006 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2007 material->len, &length ) );
2008 ASSERT_COMPARE( material->x, material->len,
2009 export_buffer, length );
2010 }
2011 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2012 goto exit;
2013
2014 PSA_ASSERT( psa_close_key( target_handle ) );
2015
2016exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002017 psa_reset_key_attributes( &source_attributes );
2018 psa_reset_key_attributes( &target_attributes );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002019 mbedtls_psa_crypto_free( );
2020 mbedtls_free( export_buffer );
2021}
2022/* END_CASE */
2023
2024/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02002025void copy_fail( int source_usage_arg, int source_alg_arg,
2026 int type_arg, data_t *material,
2027 int target_type_arg, int target_bits_arg,
2028 int target_usage_arg, int target_alg_arg,
2029 int expected_status_arg )
2030{
2031 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2032 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2033 psa_key_handle_t source_handle = 0;
2034 psa_key_handle_t target_handle = 0;
2035
2036 PSA_ASSERT( psa_crypto_init( ) );
2037
2038 /* Prepare the source key. */
2039 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2040 psa_set_key_algorithm( &source_attributes, source_alg_arg );
2041 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002042 PSA_ASSERT( psa_import_key( &source_attributes,
2043 material->x, material->len,
2044 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002045
2046 /* Prepare the target attributes. */
2047 psa_set_key_type( &target_attributes, target_type_arg );
2048 psa_set_key_bits( &target_attributes, target_bits_arg );
2049 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2050 psa_set_key_algorithm( &target_attributes, target_alg_arg );
2051
2052 /* Try to copy the key. */
2053 TEST_EQUAL( psa_copy_key( source_handle,
2054 &target_attributes, &target_handle ),
2055 expected_status_arg );
2056exit:
2057 psa_reset_key_attributes( &source_attributes );
2058 psa_reset_key_attributes( &target_attributes );
2059 mbedtls_psa_crypto_free( );
2060}
2061/* END_CASE */
2062
2063/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002064void hash_operation_init( )
2065{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002066 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002067 /* Test each valid way of initializing the object, except for `= {0}`, as
2068 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2069 * though it's OK by the C standard. We could test for this, but we'd need
2070 * to supress the Clang warning for the test. */
2071 psa_hash_operation_t func = psa_hash_operation_init( );
2072 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2073 psa_hash_operation_t zero;
2074
2075 memset( &zero, 0, sizeof( zero ) );
2076
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002077 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002078 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2079 PSA_ERROR_BAD_STATE );
2080 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2081 PSA_ERROR_BAD_STATE );
2082 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2083 PSA_ERROR_BAD_STATE );
2084
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002085 /* A default hash operation should be abortable without error. */
2086 PSA_ASSERT( psa_hash_abort( &func ) );
2087 PSA_ASSERT( psa_hash_abort( &init ) );
2088 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002089}
2090/* END_CASE */
2091
2092/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002093void hash_setup( int alg_arg,
2094 int expected_status_arg )
2095{
2096 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002097 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002098 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002099 psa_status_t status;
2100
Gilles Peskine8817f612018-12-18 00:18:46 +01002101 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002102
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002103 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002104 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002105
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002106 /* Whether setup succeeded or failed, abort must succeed. */
2107 PSA_ASSERT( psa_hash_abort( &operation ) );
2108
2109 /* If setup failed, reproduce the failure, so as to
2110 * test the resulting state of the operation object. */
2111 if( status != PSA_SUCCESS )
2112 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2113
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002114 /* Now the operation object should be reusable. */
2115#if defined(KNOWN_SUPPORTED_HASH_ALG)
2116 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2117 PSA_ASSERT( psa_hash_abort( &operation ) );
2118#endif
2119
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002120exit:
2121 mbedtls_psa_crypto_free( );
2122}
2123/* END_CASE */
2124
2125/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002126void hash_bad_order( )
2127{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002128 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002129 unsigned char input[] = "";
2130 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002131 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002132 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2133 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2134 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002135 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002136 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002137 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002138
Gilles Peskine8817f612018-12-18 00:18:46 +01002139 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002140
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002141 /* Call setup twice in a row. */
2142 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2143 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2144 PSA_ERROR_BAD_STATE );
2145 PSA_ASSERT( psa_hash_abort( &operation ) );
2146
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002147 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002148 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002149 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002150 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002151
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002152 /* Call update after finish. */
2153 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2154 PSA_ASSERT( psa_hash_finish( &operation,
2155 hash, sizeof( hash ), &hash_len ) );
2156 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002157 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002158 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002159
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002160 /* Call verify without calling setup beforehand. */
2161 TEST_EQUAL( psa_hash_verify( &operation,
2162 valid_hash, sizeof( valid_hash ) ),
2163 PSA_ERROR_BAD_STATE );
2164 PSA_ASSERT( psa_hash_abort( &operation ) );
2165
2166 /* Call verify after finish. */
2167 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2168 PSA_ASSERT( psa_hash_finish( &operation,
2169 hash, sizeof( hash ), &hash_len ) );
2170 TEST_EQUAL( psa_hash_verify( &operation,
2171 valid_hash, sizeof( valid_hash ) ),
2172 PSA_ERROR_BAD_STATE );
2173 PSA_ASSERT( psa_hash_abort( &operation ) );
2174
2175 /* Call verify twice in a row. */
2176 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2177 PSA_ASSERT( psa_hash_verify( &operation,
2178 valid_hash, sizeof( valid_hash ) ) );
2179 TEST_EQUAL( psa_hash_verify( &operation,
2180 valid_hash, sizeof( valid_hash ) ),
2181 PSA_ERROR_BAD_STATE );
2182 PSA_ASSERT( psa_hash_abort( &operation ) );
2183
2184 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002185 TEST_EQUAL( psa_hash_finish( &operation,
2186 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002187 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002188 PSA_ASSERT( psa_hash_abort( &operation ) );
2189
2190 /* Call finish twice in a row. */
2191 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2192 PSA_ASSERT( psa_hash_finish( &operation,
2193 hash, sizeof( hash ), &hash_len ) );
2194 TEST_EQUAL( psa_hash_finish( &operation,
2195 hash, sizeof( hash ), &hash_len ),
2196 PSA_ERROR_BAD_STATE );
2197 PSA_ASSERT( psa_hash_abort( &operation ) );
2198
2199 /* Call finish after calling verify. */
2200 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2201 PSA_ASSERT( psa_hash_verify( &operation,
2202 valid_hash, sizeof( valid_hash ) ) );
2203 TEST_EQUAL( psa_hash_finish( &operation,
2204 hash, sizeof( hash ), &hash_len ),
2205 PSA_ERROR_BAD_STATE );
2206 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002207
2208exit:
2209 mbedtls_psa_crypto_free( );
2210}
2211/* END_CASE */
2212
itayzafrir27e69452018-11-01 14:26:34 +02002213/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2214void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002215{
2216 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002217 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2218 * appended to it */
2219 unsigned char hash[] = {
2220 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2221 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2222 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002223 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002224 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002225
Gilles Peskine8817f612018-12-18 00:18:46 +01002226 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002227
itayzafrir27e69452018-11-01 14:26:34 +02002228 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002229 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002230 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002231 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002232
itayzafrir27e69452018-11-01 14:26:34 +02002233 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002234 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002235 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002236 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002237
itayzafrir27e69452018-11-01 14:26:34 +02002238 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002239 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002240 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002241 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002242
itayzafrirec93d302018-10-18 18:01:10 +03002243exit:
2244 mbedtls_psa_crypto_free( );
2245}
2246/* END_CASE */
2247
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002248/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2249void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002250{
2251 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002252 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002253 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002254 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002255 size_t hash_len;
2256
Gilles Peskine8817f612018-12-18 00:18:46 +01002257 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002258
itayzafrir58028322018-10-25 10:22:01 +03002259 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002260 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002261 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002262 hash, expected_size - 1, &hash_len ),
2263 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002264
2265exit:
2266 mbedtls_psa_crypto_free( );
2267}
2268/* END_CASE */
2269
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002270/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2271void hash_clone_source_state( )
2272{
2273 psa_algorithm_t alg = PSA_ALG_SHA_256;
2274 unsigned char hash[PSA_HASH_MAX_SIZE];
2275 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2276 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2277 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2278 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2279 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2280 size_t hash_len;
2281
2282 PSA_ASSERT( psa_crypto_init( ) );
2283 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2284
2285 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2286 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2287 PSA_ASSERT( psa_hash_finish( &op_finished,
2288 hash, sizeof( hash ), &hash_len ) );
2289 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2290 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2291
2292 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2293 PSA_ERROR_BAD_STATE );
2294
2295 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2296 PSA_ASSERT( psa_hash_finish( &op_init,
2297 hash, sizeof( hash ), &hash_len ) );
2298 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2299 PSA_ASSERT( psa_hash_finish( &op_finished,
2300 hash, sizeof( hash ), &hash_len ) );
2301 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2302 PSA_ASSERT( psa_hash_finish( &op_aborted,
2303 hash, sizeof( hash ), &hash_len ) );
2304
2305exit:
2306 psa_hash_abort( &op_source );
2307 psa_hash_abort( &op_init );
2308 psa_hash_abort( &op_setup );
2309 psa_hash_abort( &op_finished );
2310 psa_hash_abort( &op_aborted );
2311 mbedtls_psa_crypto_free( );
2312}
2313/* END_CASE */
2314
2315/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2316void hash_clone_target_state( )
2317{
2318 psa_algorithm_t alg = PSA_ALG_SHA_256;
2319 unsigned char hash[PSA_HASH_MAX_SIZE];
2320 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2321 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2322 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2323 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2324 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2325 size_t hash_len;
2326
2327 PSA_ASSERT( psa_crypto_init( ) );
2328
2329 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2330 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2331 PSA_ASSERT( psa_hash_finish( &op_finished,
2332 hash, sizeof( hash ), &hash_len ) );
2333 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2334 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2335
2336 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2337 PSA_ASSERT( psa_hash_finish( &op_target,
2338 hash, sizeof( hash ), &hash_len ) );
2339
2340 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2341 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2342 PSA_ERROR_BAD_STATE );
2343 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2344 PSA_ERROR_BAD_STATE );
2345
2346exit:
2347 psa_hash_abort( &op_target );
2348 psa_hash_abort( &op_init );
2349 psa_hash_abort( &op_setup );
2350 psa_hash_abort( &op_finished );
2351 psa_hash_abort( &op_aborted );
2352 mbedtls_psa_crypto_free( );
2353}
2354/* END_CASE */
2355
itayzafrir58028322018-10-25 10:22:01 +03002356/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002357void mac_operation_init( )
2358{
Jaeden Amero252ef282019-02-15 14:05:35 +00002359 const uint8_t input[1] = { 0 };
2360
Jaeden Amero769ce272019-01-04 11:48:03 +00002361 /* Test each valid way of initializing the object, except for `= {0}`, as
2362 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2363 * though it's OK by the C standard. We could test for this, but we'd need
2364 * to supress the Clang warning for the test. */
2365 psa_mac_operation_t func = psa_mac_operation_init( );
2366 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2367 psa_mac_operation_t zero;
2368
2369 memset( &zero, 0, sizeof( zero ) );
2370
Jaeden Amero252ef282019-02-15 14:05:35 +00002371 /* A freshly-initialized MAC operation should not be usable. */
2372 TEST_EQUAL( psa_mac_update( &func,
2373 input, sizeof( input ) ),
2374 PSA_ERROR_BAD_STATE );
2375 TEST_EQUAL( psa_mac_update( &init,
2376 input, sizeof( input ) ),
2377 PSA_ERROR_BAD_STATE );
2378 TEST_EQUAL( psa_mac_update( &zero,
2379 input, sizeof( input ) ),
2380 PSA_ERROR_BAD_STATE );
2381
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002382 /* A default MAC operation should be abortable without error. */
2383 PSA_ASSERT( psa_mac_abort( &func ) );
2384 PSA_ASSERT( psa_mac_abort( &init ) );
2385 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002386}
2387/* END_CASE */
2388
2389/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002390void mac_setup( int key_type_arg,
2391 data_t *key,
2392 int alg_arg,
2393 int expected_status_arg )
2394{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002395 psa_key_type_t key_type = key_type_arg;
2396 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002397 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002398 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002399 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2400#if defined(KNOWN_SUPPORTED_MAC_ALG)
2401 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2402#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002403
Gilles Peskine8817f612018-12-18 00:18:46 +01002404 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002405
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002406 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2407 &operation, &status ) )
2408 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002409 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002410
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002411 /* The operation object should be reusable. */
2412#if defined(KNOWN_SUPPORTED_MAC_ALG)
2413 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2414 smoke_test_key_data,
2415 sizeof( smoke_test_key_data ),
2416 KNOWN_SUPPORTED_MAC_ALG,
2417 &operation, &status ) )
2418 goto exit;
2419 TEST_EQUAL( status, PSA_SUCCESS );
2420#endif
2421
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002422exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002423 mbedtls_psa_crypto_free( );
2424}
2425/* END_CASE */
2426
2427/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002428void mac_bad_order( )
2429{
2430 psa_key_handle_t handle = 0;
2431 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2432 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2433 const uint8_t key[] = {
2434 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2435 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2436 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002437 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002438 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2439 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2440 size_t sign_mac_length = 0;
2441 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2442 const uint8_t verify_mac[] = {
2443 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2444 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2445 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2446
2447 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002448 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2449 psa_set_key_algorithm( &attributes, alg );
2450 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002451
Gilles Peskine73676cb2019-05-15 20:15:10 +02002452 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002453
Jaeden Amero252ef282019-02-15 14:05:35 +00002454 /* Call update without calling setup beforehand. */
2455 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2456 PSA_ERROR_BAD_STATE );
2457 PSA_ASSERT( psa_mac_abort( &operation ) );
2458
2459 /* Call sign finish without calling setup beforehand. */
2460 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2461 &sign_mac_length),
2462 PSA_ERROR_BAD_STATE );
2463 PSA_ASSERT( psa_mac_abort( &operation ) );
2464
2465 /* Call verify finish without calling setup beforehand. */
2466 TEST_EQUAL( psa_mac_verify_finish( &operation,
2467 verify_mac, sizeof( verify_mac ) ),
2468 PSA_ERROR_BAD_STATE );
2469 PSA_ASSERT( psa_mac_abort( &operation ) );
2470
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002471 /* Call setup twice in a row. */
2472 PSA_ASSERT( psa_mac_sign_setup( &operation,
2473 handle, alg ) );
2474 TEST_EQUAL( psa_mac_sign_setup( &operation,
2475 handle, alg ),
2476 PSA_ERROR_BAD_STATE );
2477 PSA_ASSERT( psa_mac_abort( &operation ) );
2478
Jaeden Amero252ef282019-02-15 14:05:35 +00002479 /* Call update after sign finish. */
2480 PSA_ASSERT( psa_mac_sign_setup( &operation,
2481 handle, alg ) );
2482 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2483 PSA_ASSERT( psa_mac_sign_finish( &operation,
2484 sign_mac, sizeof( sign_mac ),
2485 &sign_mac_length ) );
2486 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2487 PSA_ERROR_BAD_STATE );
2488 PSA_ASSERT( psa_mac_abort( &operation ) );
2489
2490 /* Call update after verify finish. */
2491 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002492 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002493 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2494 PSA_ASSERT( psa_mac_verify_finish( &operation,
2495 verify_mac, sizeof( verify_mac ) ) );
2496 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2497 PSA_ERROR_BAD_STATE );
2498 PSA_ASSERT( psa_mac_abort( &operation ) );
2499
2500 /* Call sign finish twice in a row. */
2501 PSA_ASSERT( psa_mac_sign_setup( &operation,
2502 handle, alg ) );
2503 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2504 PSA_ASSERT( psa_mac_sign_finish( &operation,
2505 sign_mac, sizeof( sign_mac ),
2506 &sign_mac_length ) );
2507 TEST_EQUAL( psa_mac_sign_finish( &operation,
2508 sign_mac, sizeof( sign_mac ),
2509 &sign_mac_length ),
2510 PSA_ERROR_BAD_STATE );
2511 PSA_ASSERT( psa_mac_abort( &operation ) );
2512
2513 /* Call verify finish twice in a row. */
2514 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002515 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002516 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2517 PSA_ASSERT( psa_mac_verify_finish( &operation,
2518 verify_mac, sizeof( verify_mac ) ) );
2519 TEST_EQUAL( psa_mac_verify_finish( &operation,
2520 verify_mac, sizeof( verify_mac ) ),
2521 PSA_ERROR_BAD_STATE );
2522 PSA_ASSERT( psa_mac_abort( &operation ) );
2523
2524 /* Setup sign but try verify. */
2525 PSA_ASSERT( psa_mac_sign_setup( &operation,
2526 handle, alg ) );
2527 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2528 TEST_EQUAL( psa_mac_verify_finish( &operation,
2529 verify_mac, sizeof( verify_mac ) ),
2530 PSA_ERROR_BAD_STATE );
2531 PSA_ASSERT( psa_mac_abort( &operation ) );
2532
2533 /* Setup verify but try sign. */
2534 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002535 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002536 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2537 TEST_EQUAL( psa_mac_sign_finish( &operation,
2538 sign_mac, sizeof( sign_mac ),
2539 &sign_mac_length ),
2540 PSA_ERROR_BAD_STATE );
2541 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002542
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002543exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002544 mbedtls_psa_crypto_free( );
2545}
2546/* END_CASE */
2547
2548/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002549void mac_sign( int key_type_arg,
2550 data_t *key,
2551 int alg_arg,
2552 data_t *input,
2553 data_t *expected_mac )
2554{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002555 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002556 psa_key_type_t key_type = key_type_arg;
2557 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002558 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002559 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002560 /* Leave a little extra room in the output buffer. At the end of the
2561 * test, we'll check that the implementation didn't overwrite onto
2562 * this extra room. */
2563 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2564 size_t mac_buffer_size =
2565 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2566 size_t mac_length = 0;
2567
2568 memset( actual_mac, '+', sizeof( actual_mac ) );
2569 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2570 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2571
Gilles Peskine8817f612018-12-18 00:18:46 +01002572 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002573
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002574 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2575 psa_set_key_algorithm( &attributes, alg );
2576 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002577
Gilles Peskine73676cb2019-05-15 20:15:10 +02002578 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002579
2580 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002581 PSA_ASSERT( psa_mac_sign_setup( &operation,
2582 handle, alg ) );
2583 PSA_ASSERT( psa_mac_update( &operation,
2584 input->x, input->len ) );
2585 PSA_ASSERT( psa_mac_sign_finish( &operation,
2586 actual_mac, mac_buffer_size,
2587 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002588
2589 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002590 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2591 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002592
2593 /* Verify that the end of the buffer is untouched. */
2594 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2595 sizeof( actual_mac ) - mac_length ) );
2596
2597exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002598 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002599 mbedtls_psa_crypto_free( );
2600}
2601/* END_CASE */
2602
2603/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002604void mac_verify( int key_type_arg,
2605 data_t *key,
2606 int alg_arg,
2607 data_t *input,
2608 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002609{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002610 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002611 psa_key_type_t key_type = key_type_arg;
2612 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002613 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002614 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002615
Gilles Peskine69c12672018-06-28 00:07:19 +02002616 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2617
Gilles Peskine8817f612018-12-18 00:18:46 +01002618 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002619
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002620 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2621 psa_set_key_algorithm( &attributes, alg );
2622 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002623
Gilles Peskine73676cb2019-05-15 20:15:10 +02002624 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002625
Gilles Peskine8817f612018-12-18 00:18:46 +01002626 PSA_ASSERT( psa_mac_verify_setup( &operation,
2627 handle, alg ) );
2628 PSA_ASSERT( psa_destroy_key( handle ) );
2629 PSA_ASSERT( psa_mac_update( &operation,
2630 input->x, input->len ) );
2631 PSA_ASSERT( psa_mac_verify_finish( &operation,
2632 expected_mac->x,
2633 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002634
2635exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002636 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002637 mbedtls_psa_crypto_free( );
2638}
2639/* END_CASE */
2640
2641/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002642void cipher_operation_init( )
2643{
Jaeden Ameroab439972019-02-15 14:12:05 +00002644 const uint8_t input[1] = { 0 };
2645 unsigned char output[1] = { 0 };
2646 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002647 /* Test each valid way of initializing the object, except for `= {0}`, as
2648 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2649 * though it's OK by the C standard. We could test for this, but we'd need
2650 * to supress the Clang warning for the test. */
2651 psa_cipher_operation_t func = psa_cipher_operation_init( );
2652 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2653 psa_cipher_operation_t zero;
2654
2655 memset( &zero, 0, sizeof( zero ) );
2656
Jaeden Ameroab439972019-02-15 14:12:05 +00002657 /* A freshly-initialized cipher operation should not be usable. */
2658 TEST_EQUAL( psa_cipher_update( &func,
2659 input, sizeof( input ),
2660 output, sizeof( output ),
2661 &output_length ),
2662 PSA_ERROR_BAD_STATE );
2663 TEST_EQUAL( psa_cipher_update( &init,
2664 input, sizeof( input ),
2665 output, sizeof( output ),
2666 &output_length ),
2667 PSA_ERROR_BAD_STATE );
2668 TEST_EQUAL( psa_cipher_update( &zero,
2669 input, sizeof( input ),
2670 output, sizeof( output ),
2671 &output_length ),
2672 PSA_ERROR_BAD_STATE );
2673
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002674 /* A default cipher operation should be abortable without error. */
2675 PSA_ASSERT( psa_cipher_abort( &func ) );
2676 PSA_ASSERT( psa_cipher_abort( &init ) );
2677 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002678}
2679/* END_CASE */
2680
2681/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002682void cipher_setup( int key_type_arg,
2683 data_t *key,
2684 int alg_arg,
2685 int expected_status_arg )
2686{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002687 psa_key_type_t key_type = key_type_arg;
2688 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002689 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002690 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002691 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002692#if defined(KNOWN_SUPPORTED_MAC_ALG)
2693 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2694#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002695
Gilles Peskine8817f612018-12-18 00:18:46 +01002696 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002697
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002698 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2699 &operation, &status ) )
2700 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002701 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002702
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002703 /* The operation object should be reusable. */
2704#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2705 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2706 smoke_test_key_data,
2707 sizeof( smoke_test_key_data ),
2708 KNOWN_SUPPORTED_CIPHER_ALG,
2709 &operation, &status ) )
2710 goto exit;
2711 TEST_EQUAL( status, PSA_SUCCESS );
2712#endif
2713
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002714exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002715 mbedtls_psa_crypto_free( );
2716}
2717/* END_CASE */
2718
2719/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002720void cipher_bad_order( )
2721{
2722 psa_key_handle_t handle = 0;
2723 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2724 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002725 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002726 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2727 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2728 const uint8_t key[] = {
2729 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2730 0xaa, 0xaa, 0xaa, 0xaa };
2731 const uint8_t text[] = {
2732 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2733 0xbb, 0xbb, 0xbb, 0xbb };
2734 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2735 size_t length = 0;
2736
2737 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002738 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2739 psa_set_key_algorithm( &attributes, alg );
2740 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002741 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002742
2743
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002744 /* Call encrypt setup twice in a row. */
2745 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2746 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2747 PSA_ERROR_BAD_STATE );
2748 PSA_ASSERT( psa_cipher_abort( &operation ) );
2749
2750 /* Call decrypt setup twice in a row. */
2751 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2752 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2753 PSA_ERROR_BAD_STATE );
2754 PSA_ASSERT( psa_cipher_abort( &operation ) );
2755
Jaeden Ameroab439972019-02-15 14:12:05 +00002756 /* Generate an IV without calling setup beforehand. */
2757 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2758 buffer, sizeof( buffer ),
2759 &length ),
2760 PSA_ERROR_BAD_STATE );
2761 PSA_ASSERT( psa_cipher_abort( &operation ) );
2762
2763 /* Generate an IV twice in a row. */
2764 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2765 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2766 buffer, sizeof( buffer ),
2767 &length ) );
2768 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2769 buffer, sizeof( buffer ),
2770 &length ),
2771 PSA_ERROR_BAD_STATE );
2772 PSA_ASSERT( psa_cipher_abort( &operation ) );
2773
2774 /* Generate an IV after it's already set. */
2775 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2776 PSA_ASSERT( psa_cipher_set_iv( &operation,
2777 iv, sizeof( iv ) ) );
2778 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2779 buffer, sizeof( buffer ),
2780 &length ),
2781 PSA_ERROR_BAD_STATE );
2782 PSA_ASSERT( psa_cipher_abort( &operation ) );
2783
2784 /* Set an IV without calling setup beforehand. */
2785 TEST_EQUAL( psa_cipher_set_iv( &operation,
2786 iv, sizeof( iv ) ),
2787 PSA_ERROR_BAD_STATE );
2788 PSA_ASSERT( psa_cipher_abort( &operation ) );
2789
2790 /* Set an IV after it's already set. */
2791 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2792 PSA_ASSERT( psa_cipher_set_iv( &operation,
2793 iv, sizeof( iv ) ) );
2794 TEST_EQUAL( psa_cipher_set_iv( &operation,
2795 iv, sizeof( iv ) ),
2796 PSA_ERROR_BAD_STATE );
2797 PSA_ASSERT( psa_cipher_abort( &operation ) );
2798
2799 /* Set an IV after it's already generated. */
2800 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2801 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2802 buffer, sizeof( buffer ),
2803 &length ) );
2804 TEST_EQUAL( psa_cipher_set_iv( &operation,
2805 iv, sizeof( iv ) ),
2806 PSA_ERROR_BAD_STATE );
2807 PSA_ASSERT( psa_cipher_abort( &operation ) );
2808
2809 /* Call update without calling setup beforehand. */
2810 TEST_EQUAL( psa_cipher_update( &operation,
2811 text, sizeof( text ),
2812 buffer, sizeof( buffer ),
2813 &length ),
2814 PSA_ERROR_BAD_STATE );
2815 PSA_ASSERT( psa_cipher_abort( &operation ) );
2816
2817 /* Call update without an IV where an IV is required. */
2818 TEST_EQUAL( psa_cipher_update( &operation,
2819 text, sizeof( text ),
2820 buffer, sizeof( buffer ),
2821 &length ),
2822 PSA_ERROR_BAD_STATE );
2823 PSA_ASSERT( psa_cipher_abort( &operation ) );
2824
2825 /* Call update after finish. */
2826 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2827 PSA_ASSERT( psa_cipher_set_iv( &operation,
2828 iv, sizeof( iv ) ) );
2829 PSA_ASSERT( psa_cipher_finish( &operation,
2830 buffer, sizeof( buffer ), &length ) );
2831 TEST_EQUAL( psa_cipher_update( &operation,
2832 text, sizeof( text ),
2833 buffer, sizeof( buffer ),
2834 &length ),
2835 PSA_ERROR_BAD_STATE );
2836 PSA_ASSERT( psa_cipher_abort( &operation ) );
2837
2838 /* Call finish without calling setup beforehand. */
2839 TEST_EQUAL( psa_cipher_finish( &operation,
2840 buffer, sizeof( buffer ), &length ),
2841 PSA_ERROR_BAD_STATE );
2842 PSA_ASSERT( psa_cipher_abort( &operation ) );
2843
2844 /* Call finish without an IV where an IV is required. */
2845 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2846 /* Not calling update means we are encrypting an empty buffer, which is OK
2847 * for cipher modes with padding. */
2848 TEST_EQUAL( psa_cipher_finish( &operation,
2849 buffer, sizeof( buffer ), &length ),
2850 PSA_ERROR_BAD_STATE );
2851 PSA_ASSERT( psa_cipher_abort( &operation ) );
2852
2853 /* Call finish twice in a row. */
2854 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2855 PSA_ASSERT( psa_cipher_set_iv( &operation,
2856 iv, sizeof( iv ) ) );
2857 PSA_ASSERT( psa_cipher_finish( &operation,
2858 buffer, sizeof( buffer ), &length ) );
2859 TEST_EQUAL( psa_cipher_finish( &operation,
2860 buffer, sizeof( buffer ), &length ),
2861 PSA_ERROR_BAD_STATE );
2862 PSA_ASSERT( psa_cipher_abort( &operation ) );
2863
2864exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002865 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002866}
2867/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002868
Gilles Peskine50e586b2018-06-08 14:28:46 +02002869/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002870void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002871 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002872 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002873 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002874{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002875 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002876 psa_status_t status;
2877 psa_key_type_t key_type = key_type_arg;
2878 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002879 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002880 unsigned char *output = NULL;
2881 size_t output_buffer_size = 0;
2882 size_t function_output_length = 0;
2883 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002884 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002885 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002886
Gilles Peskine8817f612018-12-18 00:18:46 +01002887 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002888
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002889 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2890 psa_set_key_algorithm( &attributes, alg );
2891 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002892
Gilles Peskine73676cb2019-05-15 20:15:10 +02002893 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002894
Gilles Peskine8817f612018-12-18 00:18:46 +01002895 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2896 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002897
Gilles Peskine423005e2019-05-06 15:22:57 +02002898 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002899 output_buffer_size = ( (size_t) input->len +
2900 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002901 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002902
Gilles Peskine8817f612018-12-18 00:18:46 +01002903 PSA_ASSERT( psa_cipher_update( &operation,
2904 input->x, input->len,
2905 output, output_buffer_size,
2906 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002907 total_output_length += function_output_length;
2908 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002909 output + total_output_length,
2910 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002911 &function_output_length );
2912 total_output_length += function_output_length;
2913
Gilles Peskinefe11b722018-12-18 00:24:04 +01002914 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002915 if( expected_status == PSA_SUCCESS )
2916 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002917 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002918 ASSERT_COMPARE( expected_output->x, expected_output->len,
2919 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002920 }
2921
2922exit:
2923 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002924 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002925 mbedtls_psa_crypto_free( );
2926}
2927/* END_CASE */
2928
2929/* BEGIN_CASE */
2930void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002931 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002932 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002933 int first_part_size_arg,
2934 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002935 data_t *expected_output )
2936{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002937 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002938 psa_key_type_t key_type = key_type_arg;
2939 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002940 size_t first_part_size = first_part_size_arg;
2941 size_t output1_length = output1_length_arg;
2942 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002943 unsigned char *output = NULL;
2944 size_t output_buffer_size = 0;
2945 size_t function_output_length = 0;
2946 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002947 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002948 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002949
Gilles Peskine8817f612018-12-18 00:18:46 +01002950 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002951
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002952 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2953 psa_set_key_algorithm( &attributes, alg );
2954 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002955
Gilles Peskine73676cb2019-05-15 20:15:10 +02002956 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002957
Gilles Peskine8817f612018-12-18 00:18:46 +01002958 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2959 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002960
Gilles Peskine423005e2019-05-06 15:22:57 +02002961 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002962 output_buffer_size = ( (size_t) input->len +
2963 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002964 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002965
Gilles Peskinee0866522019-02-19 19:44:00 +01002966 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002967 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2968 output, output_buffer_size,
2969 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002970 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002971 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002972 PSA_ASSERT( psa_cipher_update( &operation,
2973 input->x + first_part_size,
2974 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002975 output + total_output_length,
2976 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002977 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002978 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002979 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002980 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002981 output + total_output_length,
2982 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002983 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002984 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002985 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002986
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002987 ASSERT_COMPARE( expected_output->x, expected_output->len,
2988 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002989
2990exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002991 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002992 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002993 mbedtls_psa_crypto_free( );
2994}
2995/* END_CASE */
2996
2997/* BEGIN_CASE */
2998void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02002999 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003000 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003001 int first_part_size_arg,
3002 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003003 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003004{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003005 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003006
3007 psa_key_type_t key_type = key_type_arg;
3008 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003009 size_t first_part_size = first_part_size_arg;
3010 size_t output1_length = output1_length_arg;
3011 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003012 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003013 size_t output_buffer_size = 0;
3014 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003015 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003016 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003017 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003018
Gilles Peskine8817f612018-12-18 00:18:46 +01003019 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003020
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003021 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3022 psa_set_key_algorithm( &attributes, alg );
3023 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003024
Gilles Peskine73676cb2019-05-15 20:15:10 +02003025 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003026
Gilles Peskine8817f612018-12-18 00:18:46 +01003027 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3028 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003029
Gilles Peskine423005e2019-05-06 15:22:57 +02003030 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003031
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003032 output_buffer_size = ( (size_t) input->len +
3033 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003034 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003035
Gilles Peskinee0866522019-02-19 19:44:00 +01003036 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003037 PSA_ASSERT( psa_cipher_update( &operation,
3038 input->x, first_part_size,
3039 output, output_buffer_size,
3040 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003041 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003042 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003043 PSA_ASSERT( psa_cipher_update( &operation,
3044 input->x + first_part_size,
3045 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003046 output + total_output_length,
3047 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003048 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003049 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003050 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003051 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003052 output + total_output_length,
3053 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003054 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003055 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003056 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003057
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003058 ASSERT_COMPARE( expected_output->x, expected_output->len,
3059 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003060
3061exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003062 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003063 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003064 mbedtls_psa_crypto_free( );
3065}
3066/* END_CASE */
3067
Gilles Peskine50e586b2018-06-08 14:28:46 +02003068/* BEGIN_CASE */
3069void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003070 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003071 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003072 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003073{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003074 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003075 psa_status_t status;
3076 psa_key_type_t key_type = key_type_arg;
3077 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003078 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003079 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003080 size_t output_buffer_size = 0;
3081 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003082 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003083 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003084 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003085
Gilles Peskine8817f612018-12-18 00:18:46 +01003086 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003087
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003088 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3089 psa_set_key_algorithm( &attributes, alg );
3090 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003091
Gilles Peskine73676cb2019-05-15 20:15:10 +02003092 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003093
Gilles Peskine8817f612018-12-18 00:18:46 +01003094 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3095 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003096
Gilles Peskine423005e2019-05-06 15:22:57 +02003097 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003098
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003099 output_buffer_size = ( (size_t) input->len +
3100 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003101 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003102
Gilles Peskine8817f612018-12-18 00:18:46 +01003103 PSA_ASSERT( psa_cipher_update( &operation,
3104 input->x, input->len,
3105 output, output_buffer_size,
3106 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003107 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003108 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003109 output + total_output_length,
3110 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003111 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003112 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003113 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003114
3115 if( expected_status == PSA_SUCCESS )
3116 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003117 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003118 ASSERT_COMPARE( expected_output->x, expected_output->len,
3119 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003120 }
3121
Gilles Peskine50e586b2018-06-08 14:28:46 +02003122exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003123 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003124 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003125 mbedtls_psa_crypto_free( );
3126}
3127/* END_CASE */
3128
Gilles Peskine50e586b2018-06-08 14:28:46 +02003129/* BEGIN_CASE */
3130void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003131 data_t *key,
3132 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003133{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003134 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003135 psa_key_type_t key_type = key_type_arg;
3136 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003137 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003138 size_t iv_size = 16;
3139 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003140 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003141 size_t output1_size = 0;
3142 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003143 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003144 size_t output2_size = 0;
3145 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003146 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003147 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3148 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003149 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003150
Gilles Peskine8817f612018-12-18 00:18:46 +01003151 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003152
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003153 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3154 psa_set_key_algorithm( &attributes, alg );
3155 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003156
Gilles Peskine73676cb2019-05-15 20:15:10 +02003157 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003158
Gilles Peskine8817f612018-12-18 00:18:46 +01003159 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3160 handle, alg ) );
3161 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3162 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003163
Gilles Peskine8817f612018-12-18 00:18:46 +01003164 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3165 iv, iv_size,
3166 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003167 output1_size = ( (size_t) input->len +
3168 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003169 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003170
Gilles Peskine8817f612018-12-18 00:18:46 +01003171 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3172 output1, output1_size,
3173 &output1_length ) );
3174 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003175 output1 + output1_length,
3176 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003177 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003178
Gilles Peskine048b7f02018-06-08 14:20:49 +02003179 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003180
Gilles Peskine8817f612018-12-18 00:18:46 +01003181 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003182
3183 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003184 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003185
Gilles Peskine8817f612018-12-18 00:18:46 +01003186 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3187 iv, iv_length ) );
3188 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3189 output2, output2_size,
3190 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003191 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003192 PSA_ASSERT( psa_cipher_finish( &operation2,
3193 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003194 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003195 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003196
Gilles Peskine048b7f02018-06-08 14:20:49 +02003197 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003198
Gilles Peskine8817f612018-12-18 00:18:46 +01003199 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003200
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003201 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003202
3203exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003204 mbedtls_free( output1 );
3205 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003206 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003207 mbedtls_psa_crypto_free( );
3208}
3209/* END_CASE */
3210
3211/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003212void cipher_verify_output_multipart( int alg_arg,
3213 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003214 data_t *key,
3215 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003216 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003217{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003218 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003219 psa_key_type_t key_type = key_type_arg;
3220 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003221 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003222 unsigned char iv[16] = {0};
3223 size_t iv_size = 16;
3224 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003225 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003226 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003227 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003228 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003229 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003230 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003231 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003232 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3233 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003234 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003235
Gilles Peskine8817f612018-12-18 00:18:46 +01003236 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003237
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003238 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3239 psa_set_key_algorithm( &attributes, alg );
3240 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003241
Gilles Peskine73676cb2019-05-15 20:15:10 +02003242 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003243
Gilles Peskine8817f612018-12-18 00:18:46 +01003244 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3245 handle, alg ) );
3246 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3247 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003248
Gilles Peskine8817f612018-12-18 00:18:46 +01003249 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3250 iv, iv_size,
3251 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003252 output1_buffer_size = ( (size_t) input->len +
3253 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003254 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003255
Gilles Peskinee0866522019-02-19 19:44:00 +01003256 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003257
Gilles Peskine8817f612018-12-18 00:18:46 +01003258 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3259 output1, output1_buffer_size,
3260 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003261 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003262
Gilles Peskine8817f612018-12-18 00:18:46 +01003263 PSA_ASSERT( psa_cipher_update( &operation1,
3264 input->x + first_part_size,
3265 input->len - first_part_size,
3266 output1, output1_buffer_size,
3267 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003268 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003269
Gilles Peskine8817f612018-12-18 00:18:46 +01003270 PSA_ASSERT( psa_cipher_finish( &operation1,
3271 output1 + output1_length,
3272 output1_buffer_size - output1_length,
3273 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003274 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003275
Gilles Peskine8817f612018-12-18 00:18:46 +01003276 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003277
Gilles Peskine048b7f02018-06-08 14:20:49 +02003278 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003279 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003280
Gilles Peskine8817f612018-12-18 00:18:46 +01003281 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3282 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003283
Gilles Peskine8817f612018-12-18 00:18:46 +01003284 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3285 output2, output2_buffer_size,
3286 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003287 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003288
Gilles Peskine8817f612018-12-18 00:18:46 +01003289 PSA_ASSERT( psa_cipher_update( &operation2,
3290 output1 + first_part_size,
3291 output1_length - first_part_size,
3292 output2, output2_buffer_size,
3293 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003294 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003295
Gilles Peskine8817f612018-12-18 00:18:46 +01003296 PSA_ASSERT( psa_cipher_finish( &operation2,
3297 output2 + output2_length,
3298 output2_buffer_size - output2_length,
3299 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003300 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003301
Gilles Peskine8817f612018-12-18 00:18:46 +01003302 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003303
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003304 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003305
3306exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003307 mbedtls_free( output1 );
3308 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003309 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003310 mbedtls_psa_crypto_free( );
3311}
3312/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003313
Gilles Peskine20035e32018-02-03 22:44:14 +01003314/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003315void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003316 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003317 data_t *nonce,
3318 data_t *additional_data,
3319 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003320 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003321{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003322 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003323 psa_key_type_t key_type = key_type_arg;
3324 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003325 unsigned char *output_data = NULL;
3326 size_t output_size = 0;
3327 size_t output_length = 0;
3328 unsigned char *output_data2 = NULL;
3329 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003330 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003331 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003332 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003333
Gilles Peskine4abf7412018-06-18 16:35:34 +02003334 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003335 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3336 * should be exact. */
3337 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3338 TEST_EQUAL( output_size,
3339 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003340 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003341
Gilles Peskine8817f612018-12-18 00:18:46 +01003342 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003343
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003344 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3345 psa_set_key_algorithm( &attributes, alg );
3346 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003347
Gilles Peskine049c7532019-05-15 20:22:09 +02003348 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3349 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003350
Gilles Peskinefe11b722018-12-18 00:24:04 +01003351 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3352 nonce->x, nonce->len,
3353 additional_data->x,
3354 additional_data->len,
3355 input_data->x, input_data->len,
3356 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003357 &output_length ),
3358 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003359
3360 if( PSA_SUCCESS == expected_result )
3361 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003362 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003363
Gilles Peskine003a4a92019-05-14 16:09:40 +02003364 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3365 * should be exact. */
3366 TEST_EQUAL( input_data->len,
3367 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3368
Gilles Peskinefe11b722018-12-18 00:24:04 +01003369 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3370 nonce->x, nonce->len,
3371 additional_data->x,
3372 additional_data->len,
3373 output_data, output_length,
3374 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003375 &output_length2 ),
3376 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003377
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003378 ASSERT_COMPARE( input_data->x, input_data->len,
3379 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003380 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003381
Gilles Peskinea1cac842018-06-11 19:33:02 +02003382exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003383 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003384 mbedtls_free( output_data );
3385 mbedtls_free( output_data2 );
3386 mbedtls_psa_crypto_free( );
3387}
3388/* END_CASE */
3389
3390/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003391void aead_encrypt( int key_type_arg, data_t *key_data,
3392 int alg_arg,
3393 data_t *nonce,
3394 data_t *additional_data,
3395 data_t *input_data,
3396 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003397{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003398 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003399 psa_key_type_t key_type = key_type_arg;
3400 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003401 unsigned char *output_data = NULL;
3402 size_t output_size = 0;
3403 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003404 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003405 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003406
Gilles Peskine4abf7412018-06-18 16:35:34 +02003407 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003408 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3409 * should be exact. */
3410 TEST_EQUAL( output_size,
3411 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003412 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003413
Gilles Peskine8817f612018-12-18 00:18:46 +01003414 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003415
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003416 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3417 psa_set_key_algorithm( &attributes, alg );
3418 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003419
Gilles Peskine049c7532019-05-15 20:22:09 +02003420 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3421 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003422
Gilles Peskine8817f612018-12-18 00:18:46 +01003423 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3424 nonce->x, nonce->len,
3425 additional_data->x, additional_data->len,
3426 input_data->x, input_data->len,
3427 output_data, output_size,
3428 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003429
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003430 ASSERT_COMPARE( expected_result->x, expected_result->len,
3431 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003432
Gilles Peskinea1cac842018-06-11 19:33:02 +02003433exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003434 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003436 mbedtls_psa_crypto_free( );
3437}
3438/* END_CASE */
3439
3440/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003441void aead_decrypt( int key_type_arg, data_t *key_data,
3442 int alg_arg,
3443 data_t *nonce,
3444 data_t *additional_data,
3445 data_t *input_data,
3446 data_t *expected_data,
3447 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003448{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003449 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003450 psa_key_type_t key_type = key_type_arg;
3451 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003452 unsigned char *output_data = NULL;
3453 size_t output_size = 0;
3454 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003455 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003456 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003457 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003458
Gilles Peskine003a4a92019-05-14 16:09:40 +02003459 output_size = input_data->len - tag_length;
3460 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3461 * should be exact. */
3462 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3463 TEST_EQUAL( output_size,
3464 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003465 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003466
Gilles Peskine8817f612018-12-18 00:18:46 +01003467 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003468
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003469 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3470 psa_set_key_algorithm( &attributes, alg );
3471 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003472
Gilles Peskine049c7532019-05-15 20:22:09 +02003473 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3474 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003475
Gilles Peskinefe11b722018-12-18 00:24:04 +01003476 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3477 nonce->x, nonce->len,
3478 additional_data->x,
3479 additional_data->len,
3480 input_data->x, input_data->len,
3481 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003482 &output_length ),
3483 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003484
Gilles Peskine2d277862018-06-18 15:41:12 +02003485 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003486 ASSERT_COMPARE( expected_data->x, expected_data->len,
3487 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488
Gilles Peskinea1cac842018-06-11 19:33:02 +02003489exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003490 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003491 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003492 mbedtls_psa_crypto_free( );
3493}
3494/* END_CASE */
3495
3496/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003497void signature_size( int type_arg,
3498 int bits,
3499 int alg_arg,
3500 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003501{
3502 psa_key_type_t type = type_arg;
3503 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003504 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003505 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003506exit:
3507 ;
3508}
3509/* END_CASE */
3510
3511/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003512void sign_deterministic( int key_type_arg, data_t *key_data,
3513 int alg_arg, data_t *input_data,
3514 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003515{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003516 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003517 psa_key_type_t key_type = key_type_arg;
3518 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003519 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003520 unsigned char *signature = NULL;
3521 size_t signature_size;
3522 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003523 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003524
Gilles Peskine8817f612018-12-18 00:18:46 +01003525 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003526
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003527 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3528 psa_set_key_algorithm( &attributes, alg );
3529 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003530
Gilles Peskine049c7532019-05-15 20:22:09 +02003531 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3532 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003533 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3534 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003535
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003536 /* Allocate a buffer which has the size advertized by the
3537 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003538 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3539 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003540 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003541 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003542 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003543
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003544 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003545 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3546 input_data->x, input_data->len,
3547 signature, signature_size,
3548 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003549 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003550 ASSERT_COMPARE( output_data->x, output_data->len,
3551 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003552
3553exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003554 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003555 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003556 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003557 mbedtls_psa_crypto_free( );
3558}
3559/* END_CASE */
3560
3561/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003562void sign_fail( int key_type_arg, data_t *key_data,
3563 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003564 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003565{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003566 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003567 psa_key_type_t key_type = key_type_arg;
3568 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003569 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003570 psa_status_t actual_status;
3571 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003572 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003573 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003574 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003575
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003576 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003577
Gilles Peskine8817f612018-12-18 00:18:46 +01003578 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003579
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003580 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3581 psa_set_key_algorithm( &attributes, alg );
3582 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003583
Gilles Peskine049c7532019-05-15 20:22:09 +02003584 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3585 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003586
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003587 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003588 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003589 signature, signature_size,
3590 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003591 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003592 /* The value of *signature_length is unspecified on error, but
3593 * whatever it is, it should be less than signature_size, so that
3594 * if the caller tries to read *signature_length bytes without
3595 * checking the error code then they don't overflow a buffer. */
3596 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003597
3598exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003599 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003600 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003601 mbedtls_free( signature );
3602 mbedtls_psa_crypto_free( );
3603}
3604/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003605
3606/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003607void sign_verify( int key_type_arg, data_t *key_data,
3608 int alg_arg, data_t *input_data )
3609{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003610 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003611 psa_key_type_t key_type = key_type_arg;
3612 psa_algorithm_t alg = alg_arg;
3613 size_t key_bits;
3614 unsigned char *signature = NULL;
3615 size_t signature_size;
3616 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003617 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003618
Gilles Peskine8817f612018-12-18 00:18:46 +01003619 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003620
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003621 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3622 psa_set_key_algorithm( &attributes, alg );
3623 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003624
Gilles Peskine049c7532019-05-15 20:22:09 +02003625 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3626 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003627 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3628 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003629
3630 /* Allocate a buffer which has the size advertized by the
3631 * library. */
3632 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3633 key_bits, alg );
3634 TEST_ASSERT( signature_size != 0 );
3635 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003636 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003637
3638 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003639 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3640 input_data->x, input_data->len,
3641 signature, signature_size,
3642 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003643 /* Check that the signature length looks sensible. */
3644 TEST_ASSERT( signature_length <= signature_size );
3645 TEST_ASSERT( signature_length > 0 );
3646
3647 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003648 PSA_ASSERT( psa_asymmetric_verify(
3649 handle, alg,
3650 input_data->x, input_data->len,
3651 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003652
3653 if( input_data->len != 0 )
3654 {
3655 /* Flip a bit in the input and verify that the signature is now
3656 * detected as invalid. Flip a bit at the beginning, not at the end,
3657 * because ECDSA may ignore the last few bits of the input. */
3658 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003659 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3660 input_data->x, input_data->len,
3661 signature, signature_length ),
3662 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003663 }
3664
3665exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003666 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003667 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003668 mbedtls_free( signature );
3669 mbedtls_psa_crypto_free( );
3670}
3671/* END_CASE */
3672
3673/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003674void asymmetric_verify( int key_type_arg, data_t *key_data,
3675 int alg_arg, data_t *hash_data,
3676 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003677{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003678 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003679 psa_key_type_t key_type = key_type_arg;
3680 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003681 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003682
Gilles Peskine69c12672018-06-28 00:07:19 +02003683 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3684
Gilles Peskine8817f612018-12-18 00:18:46 +01003685 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003686
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003687 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3688 psa_set_key_algorithm( &attributes, alg );
3689 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003690
Gilles Peskine049c7532019-05-15 20:22:09 +02003691 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3692 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003693
Gilles Peskine8817f612018-12-18 00:18:46 +01003694 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3695 hash_data->x, hash_data->len,
3696 signature_data->x,
3697 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003698exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003699 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003700 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003701 mbedtls_psa_crypto_free( );
3702}
3703/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003704
3705/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003706void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3707 int alg_arg, data_t *hash_data,
3708 data_t *signature_data,
3709 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003710{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003711 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003712 psa_key_type_t key_type = key_type_arg;
3713 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003714 psa_status_t actual_status;
3715 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003716 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003717
Gilles Peskine8817f612018-12-18 00:18:46 +01003718 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003719
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003720 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3721 psa_set_key_algorithm( &attributes, alg );
3722 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003723
Gilles Peskine049c7532019-05-15 20:22:09 +02003724 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3725 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003726
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003727 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003728 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003729 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003730 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003731
Gilles Peskinefe11b722018-12-18 00:24:04 +01003732 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003733
3734exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003735 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003736 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003737 mbedtls_psa_crypto_free( );
3738}
3739/* END_CASE */
3740
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003741/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003742void asymmetric_encrypt( int key_type_arg,
3743 data_t *key_data,
3744 int alg_arg,
3745 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003746 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003747 int expected_output_length_arg,
3748 int expected_status_arg )
3749{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003750 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003751 psa_key_type_t key_type = key_type_arg;
3752 psa_algorithm_t alg = alg_arg;
3753 size_t expected_output_length = expected_output_length_arg;
3754 size_t key_bits;
3755 unsigned char *output = NULL;
3756 size_t output_size;
3757 size_t output_length = ~0;
3758 psa_status_t actual_status;
3759 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003760 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003761
Gilles Peskine8817f612018-12-18 00:18:46 +01003762 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003763
Gilles Peskine656896e2018-06-29 19:12:28 +02003764 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003765 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3766 psa_set_key_algorithm( &attributes, alg );
3767 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003768 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3769 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003770
3771 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003772 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3773 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003774 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003775 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003776
3777 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003778 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003779 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003780 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003781 output, output_size,
3782 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003783 TEST_EQUAL( actual_status, expected_status );
3784 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003785
Gilles Peskine68428122018-06-30 18:42:41 +02003786 /* If the label is empty, the test framework puts a non-null pointer
3787 * in label->x. Test that a null pointer works as well. */
3788 if( label->len == 0 )
3789 {
3790 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003791 if( output_size != 0 )
3792 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003793 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003794 input_data->x, input_data->len,
3795 NULL, label->len,
3796 output, output_size,
3797 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003798 TEST_EQUAL( actual_status, expected_status );
3799 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003800 }
3801
Gilles Peskine656896e2018-06-29 19:12:28 +02003802exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003803 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003804 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003805 mbedtls_free( output );
3806 mbedtls_psa_crypto_free( );
3807}
3808/* END_CASE */
3809
3810/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003811void asymmetric_encrypt_decrypt( int key_type_arg,
3812 data_t *key_data,
3813 int alg_arg,
3814 data_t *input_data,
3815 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003816{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003817 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003818 psa_key_type_t key_type = key_type_arg;
3819 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003820 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003821 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003822 size_t output_size;
3823 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003824 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003825 size_t output2_size;
3826 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003827 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003828
Gilles Peskine8817f612018-12-18 00:18:46 +01003829 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003830
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003831 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3832 psa_set_key_algorithm( &attributes, alg );
3833 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003834
Gilles Peskine049c7532019-05-15 20:22:09 +02003835 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3836 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003837
3838 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003839 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3840 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003841 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003842 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003843 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003844 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003845
Gilles Peskineeebd7382018-06-08 18:11:54 +02003846 /* We test encryption by checking that encrypt-then-decrypt gives back
3847 * the original plaintext because of the non-optional random
3848 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003849 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3850 input_data->x, input_data->len,
3851 label->x, label->len,
3852 output, output_size,
3853 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003854 /* We don't know what ciphertext length to expect, but check that
3855 * it looks sensible. */
3856 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003857
Gilles Peskine8817f612018-12-18 00:18:46 +01003858 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3859 output, output_length,
3860 label->x, label->len,
3861 output2, output2_size,
3862 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003863 ASSERT_COMPARE( input_data->x, input_data->len,
3864 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003865
3866exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003867 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003868 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003869 mbedtls_free( output );
3870 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003872}
3873/* END_CASE */
3874
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003875/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003876void asymmetric_decrypt( int key_type_arg,
3877 data_t *key_data,
3878 int alg_arg,
3879 data_t *input_data,
3880 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003881 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003882{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003883 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003884 psa_key_type_t key_type = key_type_arg;
3885 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003886 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003887 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003888 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003889 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003890
Jaeden Amero412654a2019-02-06 12:57:46 +00003891 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003892 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003893
Gilles Peskine8817f612018-12-18 00:18:46 +01003894 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003895
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003896 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3897 psa_set_key_algorithm( &attributes, alg );
3898 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003899
Gilles Peskine049c7532019-05-15 20:22:09 +02003900 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3901 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003902
Gilles Peskine8817f612018-12-18 00:18:46 +01003903 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3904 input_data->x, input_data->len,
3905 label->x, label->len,
3906 output,
3907 output_size,
3908 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003909 ASSERT_COMPARE( expected_data->x, expected_data->len,
3910 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003911
Gilles Peskine68428122018-06-30 18:42:41 +02003912 /* If the label is empty, the test framework puts a non-null pointer
3913 * in label->x. Test that a null pointer works as well. */
3914 if( label->len == 0 )
3915 {
3916 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003917 if( output_size != 0 )
3918 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003919 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3920 input_data->x, input_data->len,
3921 NULL, label->len,
3922 output,
3923 output_size,
3924 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003925 ASSERT_COMPARE( expected_data->x, expected_data->len,
3926 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003927 }
3928
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003929exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003930 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003931 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003932 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003933 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003934}
3935/* END_CASE */
3936
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003937/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003938void asymmetric_decrypt_fail( int key_type_arg,
3939 data_t *key_data,
3940 int alg_arg,
3941 data_t *input_data,
3942 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003943 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003944 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003945{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003946 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003947 psa_key_type_t key_type = key_type_arg;
3948 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003949 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003950 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003951 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003952 psa_status_t actual_status;
3953 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003954 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003955
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003956 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003957
Gilles Peskine8817f612018-12-18 00:18:46 +01003958 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003959
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003960 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3961 psa_set_key_algorithm( &attributes, alg );
3962 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003963
Gilles Peskine049c7532019-05-15 20:22:09 +02003964 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3965 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003966
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003967 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003968 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003969 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003970 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003971 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003972 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003973 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003974
Gilles Peskine68428122018-06-30 18:42:41 +02003975 /* If the label is empty, the test framework puts a non-null pointer
3976 * in label->x. Test that a null pointer works as well. */
3977 if( label->len == 0 )
3978 {
3979 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003980 if( output_size != 0 )
3981 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003982 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003983 input_data->x, input_data->len,
3984 NULL, label->len,
3985 output, output_size,
3986 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003987 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003988 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003989 }
3990
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003991exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003992 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003993 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003994 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003995 mbedtls_psa_crypto_free( );
3996}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003997/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003998
3999/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004000void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004001{
4002 /* Test each valid way of initializing the object, except for `= {0}`, as
4003 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4004 * though it's OK by the C standard. We could test for this, but we'd need
4005 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004006 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004007 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4008 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4009 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004010
4011 memset( &zero, 0, sizeof( zero ) );
4012
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004013 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004014 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004015 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004016 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004017 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004018 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004019 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004020
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004021 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004022 PSA_ASSERT( psa_key_derivation_abort(&func) );
4023 PSA_ASSERT( psa_key_derivation_abort(&init) );
4024 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004025}
4026/* END_CASE */
4027
4028/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004029void derive_setup( int key_type_arg,
4030 data_t *key_data,
4031 int alg_arg,
4032 data_t *salt,
4033 data_t *label,
4034 int requested_capacity_arg,
4035 int expected_status_arg )
4036{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004037 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004038 size_t key_type = key_type_arg;
4039 psa_algorithm_t alg = alg_arg;
4040 size_t requested_capacity = requested_capacity_arg;
4041 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004042 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004043 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004044
Gilles Peskine8817f612018-12-18 00:18:46 +01004045 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004046
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004047 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4048 psa_set_key_algorithm( &attributes, alg );
4049 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004050
Gilles Peskine049c7532019-05-15 20:22:09 +02004051 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4052 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004053
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004054 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004055 salt->x, salt->len,
4056 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004057 requested_capacity ),
4058 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004059
4060exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004061 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004062 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004063 mbedtls_psa_crypto_free( );
4064}
4065/* END_CASE */
4066
4067/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004068void test_derive_invalid_key_derivation_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004069{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004070 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004071 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004072 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004073 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004074 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004075 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004076 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4077 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4078 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004079 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004080
Gilles Peskine8817f612018-12-18 00:18:46 +01004081 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004082
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004083 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4084 psa_set_key_algorithm( &attributes, alg );
4085 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004086
Gilles Peskine73676cb2019-05-15 20:15:10 +02004087 PSA_ASSERT( psa_import_key( &attributes,
4088 key_data, sizeof( key_data ),
4089 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004090
4091 /* valid key derivation */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004092 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004093 NULL, 0,
4094 NULL, 0,
4095 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004096
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004097 /* state of operation shouldn't allow additional generation */
4098 TEST_EQUAL( psa_key_derivation( &operation, handle, alg,
Gilles Peskinefe11b722018-12-18 00:24:04 +01004099 NULL, 0,
4100 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004101 capacity ),
4102 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004103
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004104 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004105
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004106 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004107 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004108
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004109exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004110 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004111 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004112 mbedtls_psa_crypto_free( );
4113}
4114/* END_CASE */
4115
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004116/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004117void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004118{
4119 uint8_t output_buffer[16];
4120 size_t buffer_size = 16;
4121 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004122 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004123
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004124 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4125 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004126 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004127
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004128 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004129 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004130
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004131 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004132
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004133 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4134 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004135 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004136
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004137 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004138 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004139
4140exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004141 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004142}
4143/* END_CASE */
4144
4145/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004146void derive_output( int alg_arg,
4147 data_t *key_data,
4148 data_t *salt,
4149 data_t *label,
4150 int requested_capacity_arg,
4151 data_t *expected_output1,
4152 data_t *expected_output2 )
4153{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004154 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004155 psa_algorithm_t alg = alg_arg;
4156 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004157 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004158 uint8_t *expected_outputs[2] =
4159 {expected_output1->x, expected_output2->x};
4160 size_t output_sizes[2] =
4161 {expected_output1->len, expected_output2->len};
4162 size_t output_buffer_size = 0;
4163 uint8_t *output_buffer = NULL;
4164 size_t expected_capacity;
4165 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004166 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004167 psa_status_t status;
4168 unsigned i;
4169
4170 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4171 {
4172 if( output_sizes[i] > output_buffer_size )
4173 output_buffer_size = output_sizes[i];
4174 if( output_sizes[i] == 0 )
4175 expected_outputs[i] = NULL;
4176 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004177 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004178 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004179
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004180 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4181 psa_set_key_algorithm( &attributes, alg );
4182 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004183
Gilles Peskine049c7532019-05-15 20:22:09 +02004184 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4185 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004186
4187 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004188 if( PSA_ALG_IS_HKDF( alg ) )
4189 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004190 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4191 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004192 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004193 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004194 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004195 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004196 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004197 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004198 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004199 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004200 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004201 label->x, label->len ) );
4202 }
4203 else
4204 {
4205 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004206 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004207 salt->x, salt->len,
4208 label->x, label->len,
4209 requested_capacity ) );
4210 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004211 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004212 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004213 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004214 expected_capacity = requested_capacity;
4215
4216 /* Expansion phase. */
4217 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4218 {
4219 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004220 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004221 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004222 if( expected_capacity == 0 && output_sizes[i] == 0 )
4223 {
4224 /* Reading 0 bytes when 0 bytes are available can go either way. */
4225 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004226 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004227 continue;
4228 }
4229 else if( expected_capacity == 0 ||
4230 output_sizes[i] > expected_capacity )
4231 {
4232 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004233 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004234 expected_capacity = 0;
4235 continue;
4236 }
4237 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004238 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004239 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004240 ASSERT_COMPARE( output_buffer, output_sizes[i],
4241 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004242 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004243 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004244 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004245 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004246 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004247 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004248 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004249
4250exit:
4251 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004252 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004253 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004254 mbedtls_psa_crypto_free( );
4255}
4256/* END_CASE */
4257
4258/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004259void derive_full( int alg_arg,
4260 data_t *key_data,
4261 data_t *salt,
4262 data_t *label,
4263 int requested_capacity_arg )
4264{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004265 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004266 psa_algorithm_t alg = alg_arg;
4267 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004268 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004269 unsigned char output_buffer[16];
4270 size_t expected_capacity = requested_capacity;
4271 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004272 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004273
Gilles Peskine8817f612018-12-18 00:18:46 +01004274 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004275
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004276 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4277 psa_set_key_algorithm( &attributes, alg );
4278 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004279
Gilles Peskine049c7532019-05-15 20:22:09 +02004280 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4281 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004282
4283 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004284 if( PSA_ALG_IS_HKDF( alg ) )
4285 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004286 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4287 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004288 requested_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004289 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004290 PSA_KEY_DERIVATION_INPUT_SALT,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004291 salt->x, salt->len ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004292 PSA_ASSERT( psa_key_derivation_input_key( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004293 PSA_KEY_DERIVATION_INPUT_SECRET,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004294 handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004295 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004296 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004297 label->x, label->len ) );
4298 }
4299 else
4300 {
4301 // legacy
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004302 PSA_ASSERT( psa_key_derivation( &operation, handle, alg,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004303 salt->x, salt->len,
4304 label->x, label->len,
4305 requested_capacity ) );
4306 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004307 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004308 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004309 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004310
4311 /* Expansion phase. */
4312 while( current_capacity > 0 )
4313 {
4314 size_t read_size = sizeof( output_buffer );
4315 if( read_size > current_capacity )
4316 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004317 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004318 output_buffer,
4319 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004320 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004321 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004322 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004323 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004324 }
4325
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004326 /* Check that the operation refuses to go over capacity. */
4327 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004328 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004329
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004330 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004331
4332exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004333 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004334 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004335 mbedtls_psa_crypto_free( );
4336}
4337/* END_CASE */
4338
4339/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004340void derive_key_exercise( int alg_arg,
4341 data_t *key_data,
4342 data_t *salt,
4343 data_t *label,
4344 int derived_type_arg,
4345 int derived_bits_arg,
4346 int derived_usage_arg,
4347 int derived_alg_arg )
4348{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004349 psa_key_handle_t base_handle = 0;
4350 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004351 psa_algorithm_t alg = alg_arg;
4352 psa_key_type_t derived_type = derived_type_arg;
4353 size_t derived_bits = derived_bits_arg;
4354 psa_key_usage_t derived_usage = derived_usage_arg;
4355 psa_algorithm_t derived_alg = derived_alg_arg;
4356 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004357 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004358 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004359 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004360
Gilles Peskine8817f612018-12-18 00:18:46 +01004361 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004362
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004363 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4364 psa_set_key_algorithm( &attributes, alg );
4365 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004366 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4367 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004368
4369 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004370 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004371 salt->x, salt->len,
4372 label->x, label->len,
4373 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004374 psa_set_key_usage_flags( &attributes, derived_usage );
4375 psa_set_key_algorithm( &attributes, derived_alg );
4376 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004377 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004378 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004379 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004380
4381 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004382 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4383 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4384 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004385
4386 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004387 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004388 goto exit;
4389
4390exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004391 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004392 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004393 psa_destroy_key( base_handle );
4394 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004395 mbedtls_psa_crypto_free( );
4396}
4397/* END_CASE */
4398
4399/* BEGIN_CASE */
4400void derive_key_export( int alg_arg,
4401 data_t *key_data,
4402 data_t *salt,
4403 data_t *label,
4404 int bytes1_arg,
4405 int bytes2_arg )
4406{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004407 psa_key_handle_t base_handle = 0;
4408 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004409 psa_algorithm_t alg = alg_arg;
4410 size_t bytes1 = bytes1_arg;
4411 size_t bytes2 = bytes2_arg;
4412 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004413 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004414 uint8_t *output_buffer = NULL;
4415 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004416 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4417 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004418 size_t length;
4419
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004420 ASSERT_ALLOC( output_buffer, capacity );
4421 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004422 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004423
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004424 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4425 psa_set_key_algorithm( &base_attributes, alg );
4426 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004427 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4428 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004429
4430 /* Derive some material and output it. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004431 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004432 salt->x, salt->len,
4433 label->x, label->len,
4434 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004435 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004436 output_buffer,
4437 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004438 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004439
4440 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004441 PSA_ASSERT( psa_key_derivation( &operation, base_handle, alg,
Gilles Peskine8817f612018-12-18 00:18:46 +01004442 salt->x, salt->len,
4443 label->x, label->len,
4444 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004445 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4446 psa_set_key_algorithm( &derived_attributes, 0 );
4447 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004448 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004449 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004450 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004451 PSA_ASSERT( psa_export_key( derived_handle,
4452 export_buffer, bytes1,
4453 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004454 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004455 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004456 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004457 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004458 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004459 PSA_ASSERT( psa_export_key( derived_handle,
4460 export_buffer + bytes1, bytes2,
4461 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004462 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004463
4464 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004465 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4466 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004467
4468exit:
4469 mbedtls_free( output_buffer );
4470 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004471 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004472 psa_destroy_key( base_handle );
4473 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004474 mbedtls_psa_crypto_free( );
4475}
4476/* END_CASE */
4477
4478/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004479void key_agreement_setup( int alg_arg,
4480 int our_key_type_arg, data_t *our_key_data,
4481 data_t *peer_key_data,
4482 int expected_status_arg )
4483{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004484 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004485 psa_algorithm_t alg = alg_arg;
4486 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004487 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004488 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004489 psa_status_t expected_status = expected_status_arg;
4490 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004491
Gilles Peskine8817f612018-12-18 00:18:46 +01004492 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004493
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004494 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4495 psa_set_key_algorithm( &attributes, alg );
4496 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004497 PSA_ASSERT( psa_import_key( &attributes,
4498 our_key_data->x, our_key_data->len,
4499 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004500
Gilles Peskine77f40d82019-04-11 21:27:06 +02004501 /* The tests currently include inputs that should fail at either step.
4502 * Test cases that fail at the setup step should be changed to call
4503 * key_derivation_setup instead, and this function should be renamed
4504 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004505 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004506 if( status == PSA_SUCCESS )
4507 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004508 TEST_EQUAL( psa_key_derivation_key_agreement(
4509 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4510 our_key,
4511 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004512 expected_status );
4513 }
4514 else
4515 {
4516 TEST_ASSERT( status == expected_status );
4517 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004518
4519exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004520 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004521 psa_destroy_key( our_key );
4522 mbedtls_psa_crypto_free( );
4523}
4524/* END_CASE */
4525
4526/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004527void raw_key_agreement( int alg_arg,
4528 int our_key_type_arg, data_t *our_key_data,
4529 data_t *peer_key_data,
4530 data_t *expected_output )
4531{
4532 psa_key_handle_t our_key = 0;
4533 psa_algorithm_t alg = alg_arg;
4534 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004535 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004536 unsigned char *output = NULL;
4537 size_t output_length = ~0;
4538
4539 ASSERT_ALLOC( output, expected_output->len );
4540 PSA_ASSERT( psa_crypto_init( ) );
4541
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004542 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4543 psa_set_key_algorithm( &attributes, alg );
4544 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004545 PSA_ASSERT( psa_import_key( &attributes,
4546 our_key_data->x, our_key_data->len,
4547 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004548
Gilles Peskinebe697d82019-05-16 18:00:41 +02004549 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4550 peer_key_data->x, peer_key_data->len,
4551 output, expected_output->len,
4552 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004553 ASSERT_COMPARE( output, output_length,
4554 expected_output->x, expected_output->len );
4555
4556exit:
4557 mbedtls_free( output );
4558 psa_destroy_key( our_key );
4559 mbedtls_psa_crypto_free( );
4560}
4561/* END_CASE */
4562
4563/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004564void key_agreement_capacity( int alg_arg,
4565 int our_key_type_arg, data_t *our_key_data,
4566 data_t *peer_key_data,
4567 int expected_capacity_arg )
4568{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004569 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004570 psa_algorithm_t alg = alg_arg;
4571 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004572 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004573 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004574 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004575 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004576
Gilles Peskine8817f612018-12-18 00:18:46 +01004577 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004578
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004579 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4580 psa_set_key_algorithm( &attributes, alg );
4581 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004582 PSA_ASSERT( psa_import_key( &attributes,
4583 our_key_data->x, our_key_data->len,
4584 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004585
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004586 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004587 PSA_ASSERT( psa_key_derivation_key_agreement(
4588 &operation,
4589 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4590 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004591 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4592 {
4593 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004594 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004595 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004596 NULL, 0 ) );
4597 }
Gilles Peskine59685592018-09-18 12:11:34 +02004598
Gilles Peskinebf491972018-10-25 22:36:12 +02004599 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004600 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004601 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004602 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004603
Gilles Peskinebf491972018-10-25 22:36:12 +02004604 /* Test the actual capacity by reading the output. */
4605 while( actual_capacity > sizeof( output ) )
4606 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004607 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004608 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004609 actual_capacity -= sizeof( output );
4610 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004611 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004612 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004613 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004614 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004615
Gilles Peskine59685592018-09-18 12:11:34 +02004616exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004617 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004618 psa_destroy_key( our_key );
4619 mbedtls_psa_crypto_free( );
4620}
4621/* END_CASE */
4622
4623/* BEGIN_CASE */
4624void key_agreement_output( int alg_arg,
4625 int our_key_type_arg, data_t *our_key_data,
4626 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004627 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004628{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004629 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004630 psa_algorithm_t alg = alg_arg;
4631 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004632 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004633 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004634 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004635
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004636 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4637 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004638
Gilles Peskine8817f612018-12-18 00:18:46 +01004639 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004640
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004641 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4642 psa_set_key_algorithm( &attributes, alg );
4643 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004644 PSA_ASSERT( psa_import_key( &attributes,
4645 our_key_data->x, our_key_data->len,
4646 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004647
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004648 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004649 PSA_ASSERT( psa_key_derivation_key_agreement(
4650 &operation,
4651 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4652 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004653 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4654 {
4655 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004656 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004657 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004658 NULL, 0 ) );
4659 }
Gilles Peskine59685592018-09-18 12:11:34 +02004660
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004661 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004662 actual_output,
4663 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004664 ASSERT_COMPARE( actual_output, expected_output1->len,
4665 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004666 if( expected_output2->len != 0 )
4667 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004668 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004669 actual_output,
4670 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004671 ASSERT_COMPARE( actual_output, expected_output2->len,
4672 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004673 }
Gilles Peskine59685592018-09-18 12:11:34 +02004674
4675exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004676 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004677 psa_destroy_key( our_key );
4678 mbedtls_psa_crypto_free( );
4679 mbedtls_free( actual_output );
4680}
4681/* END_CASE */
4682
4683/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004684void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004685{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004686 size_t bytes = bytes_arg;
4687 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004688 unsigned char *output = NULL;
4689 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004690 size_t i;
4691 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004692
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004693 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4694 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004695 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004696
Gilles Peskine8817f612018-12-18 00:18:46 +01004697 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004698
Gilles Peskinea50d7392018-06-21 10:22:13 +02004699 /* Run several times, to ensure that every output byte will be
4700 * nonzero at least once with overwhelming probability
4701 * (2^(-8*number_of_runs)). */
4702 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004703 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004704 if( bytes != 0 )
4705 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004706 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004707
4708 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004709 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4710 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004711
4712 for( i = 0; i < bytes; i++ )
4713 {
4714 if( output[i] != 0 )
4715 ++changed[i];
4716 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004717 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004718
4719 /* Check that every byte was changed to nonzero at least once. This
4720 * validates that psa_generate_random is overwriting every byte of
4721 * the output buffer. */
4722 for( i = 0; i < bytes; i++ )
4723 {
4724 TEST_ASSERT( changed[i] != 0 );
4725 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004726
4727exit:
4728 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004729 mbedtls_free( output );
4730 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004731}
4732/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004733
4734/* BEGIN_CASE */
4735void generate_key( int type_arg,
4736 int bits_arg,
4737 int usage_arg,
4738 int alg_arg,
4739 int expected_status_arg )
4740{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004741 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004742 psa_key_type_t type = type_arg;
4743 psa_key_usage_t usage = usage_arg;
4744 size_t bits = bits_arg;
4745 psa_algorithm_t alg = alg_arg;
4746 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004747 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004748 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004749
Gilles Peskine8817f612018-12-18 00:18:46 +01004750 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004751
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004752 psa_set_key_usage_flags( &attributes, usage );
4753 psa_set_key_algorithm( &attributes, alg );
4754 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004755 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004756
4757 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004758 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004759 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004760 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004761
4762 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004763 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4764 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4765 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004766
Gilles Peskine818ca122018-06-20 18:16:48 +02004767 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004768 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004769 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004770
4771exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004772 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004773 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004774 mbedtls_psa_crypto_free( );
4775}
4776/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004777
Gilles Peskinee56e8782019-04-26 17:34:02 +02004778/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4779void generate_key_rsa( int bits_arg,
4780 data_t *e_arg,
4781 int expected_status_arg )
4782{
4783 psa_key_handle_t handle = 0;
4784 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEYPAIR;
4785 size_t bits = bits_arg;
4786 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4787 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4788 psa_status_t expected_status = expected_status_arg;
4789 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4790 uint8_t *exported = NULL;
4791 size_t exported_size =
4792 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4793 size_t exported_length = SIZE_MAX;
4794 uint8_t *e_read_buffer = NULL;
4795 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004796 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004797 size_t e_read_length = SIZE_MAX;
4798
4799 if( e_arg->len == 0 ||
4800 ( e_arg->len == 3 &&
4801 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4802 {
4803 is_default_public_exponent = 1;
4804 e_read_size = 0;
4805 }
4806 ASSERT_ALLOC( e_read_buffer, e_read_size );
4807 ASSERT_ALLOC( exported, exported_size );
4808
4809 PSA_ASSERT( psa_crypto_init( ) );
4810
4811 psa_set_key_usage_flags( &attributes, usage );
4812 psa_set_key_algorithm( &attributes, alg );
4813 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4814 e_arg->x, e_arg->len ) );
4815 psa_set_key_bits( &attributes, bits );
4816
4817 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004818 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004819 if( expected_status != PSA_SUCCESS )
4820 goto exit;
4821
4822 /* Test the key information */
4823 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4824 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4825 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4826 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4827 e_read_buffer, e_read_size,
4828 &e_read_length ) );
4829 if( is_default_public_exponent )
4830 TEST_EQUAL( e_read_length, 0 );
4831 else
4832 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4833
4834 /* Do something with the key according to its type and permitted usage. */
4835 if( ! exercise_key( handle, usage, alg ) )
4836 goto exit;
4837
4838 /* Export the key and check the public exponent. */
4839 PSA_ASSERT( psa_export_public_key( handle,
4840 exported, exported_size,
4841 &exported_length ) );
4842 {
4843 uint8_t *p = exported;
4844 uint8_t *end = exported + exported_length;
4845 size_t len;
4846 /* RSAPublicKey ::= SEQUENCE {
4847 * modulus INTEGER, -- n
4848 * publicExponent INTEGER } -- e
4849 */
4850 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004851 MBEDTLS_ASN1_SEQUENCE |
4852 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004853 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4854 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4855 MBEDTLS_ASN1_INTEGER ) );
4856 if( len >= 1 && p[0] == 0 )
4857 {
4858 ++p;
4859 --len;
4860 }
4861 if( e_arg->len == 0 )
4862 {
4863 TEST_EQUAL( len, 3 );
4864 TEST_EQUAL( p[0], 1 );
4865 TEST_EQUAL( p[1], 0 );
4866 TEST_EQUAL( p[2], 1 );
4867 }
4868 else
4869 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4870 }
4871
4872exit:
4873 psa_reset_key_attributes( &attributes );
4874 psa_destroy_key( handle );
4875 mbedtls_psa_crypto_free( );
4876 mbedtls_free( e_read_buffer );
4877 mbedtls_free( exported );
4878}
4879/* END_CASE */
4880
Darryl Greend49a4992018-06-18 17:27:26 +01004881/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004882void persistent_key_load_key_from_storage( data_t *data,
4883 int type_arg, int bits_arg,
4884 int usage_flags_arg, int alg_arg,
4885 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004886{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004887 psa_key_id_t key_id = 1;
4888 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004889 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004890 psa_key_handle_t base_key = 0;
4891 psa_key_type_t type = type_arg;
4892 size_t bits = bits_arg;
4893 psa_key_usage_t usage_flags = usage_flags_arg;
4894 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004895 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004896 unsigned char *first_export = NULL;
4897 unsigned char *second_export = NULL;
4898 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4899 size_t first_exported_length;
4900 size_t second_exported_length;
4901
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004902 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4903 {
4904 ASSERT_ALLOC( first_export, export_size );
4905 ASSERT_ALLOC( second_export, export_size );
4906 }
Darryl Greend49a4992018-06-18 17:27:26 +01004907
Gilles Peskine8817f612018-12-18 00:18:46 +01004908 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004909
Gilles Peskinec87af662019-05-15 16:12:22 +02004910 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004911 psa_set_key_usage_flags( &attributes, usage_flags );
4912 psa_set_key_algorithm( &attributes, alg );
4913 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004914 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004915
Darryl Green0c6575a2018-11-07 16:05:30 +00004916 switch( generation_method )
4917 {
4918 case IMPORT_KEY:
4919 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004920 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4921 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004922 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004923
Darryl Green0c6575a2018-11-07 16:05:30 +00004924 case GENERATE_KEY:
4925 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004926 PSA_ASSERT( psa_generate_random_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004927 break;
4928
4929 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004930 {
4931 /* Create base key */
4932 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4933 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4934 psa_set_key_usage_flags( &base_attributes,
4935 PSA_KEY_USAGE_DERIVE );
4936 psa_set_key_algorithm( &base_attributes, derive_alg );
4937 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004938 PSA_ASSERT( psa_import_key( &base_attributes,
4939 data->x, data->len,
4940 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004941 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004942 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004943 PSA_ASSERT( psa_key_derivation_input_key(
4944 &operation,
4945 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004946 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004947 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004948 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004949 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
4950 &operation,
4951 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004952 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004953 PSA_ASSERT( psa_destroy_key( base_key ) );
4954 base_key = 0;
4955 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004956 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00004957 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004958 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004959
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004960 /* Export the key if permitted by the key policy. */
4961 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4962 {
4963 PSA_ASSERT( psa_export_key( handle,
4964 first_export, export_size,
4965 &first_exported_length ) );
4966 if( generation_method == IMPORT_KEY )
4967 ASSERT_COMPARE( data->x, data->len,
4968 first_export, first_exported_length );
4969 }
Darryl Greend49a4992018-06-18 17:27:26 +01004970
4971 /* Shutdown and restart */
4972 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004973 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004974
Darryl Greend49a4992018-06-18 17:27:26 +01004975 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02004976 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004977 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4978 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4979 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4980 PSA_KEY_LIFETIME_PERSISTENT );
4981 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4982 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4983 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4984 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004985
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004986 /* Export the key again if permitted by the key policy. */
4987 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004988 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004989 PSA_ASSERT( psa_export_key( handle,
4990 second_export, export_size,
4991 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004992 ASSERT_COMPARE( first_export, first_exported_length,
4993 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004994 }
4995
4996 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004997 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004998 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004999
5000exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005001 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005002 mbedtls_free( first_export );
5003 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005004 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005005 psa_destroy_key( base_key );
5006 if( handle == 0 )
5007 {
5008 /* In case there was a test failure after creating the persistent key
5009 * but while it was not open, try to re-open the persistent key
5010 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005011 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005012 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005013 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01005014 mbedtls_psa_crypto_free();
5015}
5016/* END_CASE */