blob: cddcb2e07d040644a97dc3e60f820afe40cfdcbd [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/* BEGIN_HEADER */
itayzafrir3e02b3b2018-06-12 17:06:52 +03002#include <stdint.h>
mohammad160327010052018-07-03 13:16:15 +03003
4#if defined(MBEDTLS_PSA_CRYPTO_SPM)
5#include "spm/psa_defs.h"
6#endif
7
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02008#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02009#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +020010#include "mbedtls/oid.h"
11
Gilles Peskinee59236f2018-01-27 23:32:46 +010012#include "psa/crypto.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +030013
Jaeden Amerof24c7f82018-06-27 17:20:43 +010014/** An invalid export length that will never be set by psa_export_key(). */
15static const size_t INVALID_EXPORT_LENGTH = ~0U;
16
Gilles Peskinef426e0f2019-02-25 17:42:03 +010017/* A hash algorithm that is known to be supported.
18 *
19 * This is used in some smoke tests.
20 */
21#if defined(MBEDTLS_MD2_C)
22#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
23#elif defined(MBEDTLS_MD4_C)
24#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
25#elif defined(MBEDTLS_MD5_C)
26#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
27/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
28 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
29 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
30 * implausible anyway. */
31#elif defined(MBEDTLS_SHA1_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
33#elif defined(MBEDTLS_SHA256_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
35#elif defined(MBEDTLS_SHA512_C)
36#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
37#elif defined(MBEDTLS_SHA3_C)
38#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
39#else
40#undef KNOWN_SUPPORTED_HASH_ALG
41#endif
42
43/* A block cipher that is known to be supported.
44 *
45 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
46 */
47#if defined(MBEDTLS_AES_C)
48#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
49#elif defined(MBEDTLS_ARIA_C)
50#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
51#elif defined(MBEDTLS_CAMELLIA_C)
52#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
53#undef KNOWN_SUPPORTED_BLOCK_CIPHER
54#endif
55
56/* A MAC mode that is known to be supported.
57 *
58 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
59 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
60 *
61 * This is used in some smoke tests.
62 */
63#if defined(KNOWN_SUPPORTED_HASH_ALG)
64#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
65#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
66#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
67#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
68#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
69#else
70#undef KNOWN_SUPPORTED_MAC_ALG
71#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
72#endif
73
74/* A cipher algorithm and key type that are known to be supported.
75 *
76 * This is used in some smoke tests.
77 */
78#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
79#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
80#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
81#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
82#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
83#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
84#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
85#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
86#else
87#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
88#endif
89#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
90#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
91#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
92#elif defined(MBEDTLS_RC4_C)
93#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
94#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
95#else
96#undef KNOWN_SUPPORTED_CIPHER_ALG
97#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
98#endif
99
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200100/** Test if a buffer contains a constant byte value.
101 *
102 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200103 *
104 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200105 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 * \param size Size of the buffer in bytes.
107 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200108 * \return 1 if the buffer is all-bits-zero.
109 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200110 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200111static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200112{
113 size_t i;
114 for( i = 0; i < size; i++ )
115 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200116 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200117 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200118 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200119 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200120}
Gilles Peskine818ca122018-06-20 18:16:48 +0200121
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200122/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
123static int asn1_write_10x( unsigned char **p,
124 unsigned char *start,
125 size_t bits,
126 unsigned char x )
127{
128 int ret;
129 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200130 if( bits == 0 )
131 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
132 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200133 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300134 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200135 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
136 *p -= len;
137 ( *p )[len-1] = x;
138 if( bits % 8 == 0 )
139 ( *p )[1] |= 1;
140 else
141 ( *p )[0] |= 1 << ( bits % 8 );
142 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
143 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
144 MBEDTLS_ASN1_INTEGER ) );
145 return( len );
146}
147
148static int construct_fake_rsa_key( unsigned char *buffer,
149 size_t buffer_size,
150 unsigned char **p,
151 size_t bits,
152 int keypair )
153{
154 size_t half_bits = ( bits + 1 ) / 2;
155 int ret;
156 int len = 0;
157 /* Construct something that looks like a DER encoding of
158 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
159 * RSAPrivateKey ::= SEQUENCE {
160 * version Version,
161 * modulus INTEGER, -- n
162 * publicExponent INTEGER, -- e
163 * privateExponent INTEGER, -- d
164 * prime1 INTEGER, -- p
165 * prime2 INTEGER, -- q
166 * exponent1 INTEGER, -- d mod (p-1)
167 * exponent2 INTEGER, -- d mod (q-1)
168 * coefficient INTEGER, -- (inverse of q) mod p
169 * otherPrimeInfos OtherPrimeInfos OPTIONAL
170 * }
171 * Or, for a public key, the same structure with only
172 * version, modulus and publicExponent.
173 */
174 *p = buffer + buffer_size;
175 if( keypair )
176 {
177 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
178 asn1_write_10x( p, buffer, half_bits, 1 ) );
179 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
180 asn1_write_10x( p, buffer, half_bits, 1 ) );
181 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
182 asn1_write_10x( p, buffer, half_bits, 1 ) );
183 MBEDTLS_ASN1_CHK_ADD( len, /* q */
184 asn1_write_10x( p, buffer, half_bits, 1 ) );
185 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
186 asn1_write_10x( p, buffer, half_bits, 3 ) );
187 MBEDTLS_ASN1_CHK_ADD( len, /* d */
188 asn1_write_10x( p, buffer, bits, 1 ) );
189 }
190 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
191 asn1_write_10x( p, buffer, 17, 1 ) );
192 MBEDTLS_ASN1_CHK_ADD( len, /* n */
193 asn1_write_10x( p, buffer, bits, 1 ) );
194 if( keypair )
195 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
196 mbedtls_asn1_write_int( p, buffer, 0 ) );
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
198 {
199 const unsigned char tag =
200 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
201 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
202 }
203 return( len );
204}
205
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100206int exercise_mac_setup( psa_key_type_t key_type,
207 const unsigned char *key_bytes,
208 size_t key_length,
209 psa_algorithm_t alg,
210 psa_mac_operation_t *operation,
211 psa_status_t *status )
212{
213 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100215
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200216 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
217 psa_set_key_algorithm( &attributes, alg );
218 psa_set_key_type( &attributes, key_type );
219 PSA_ASSERT( psa_import_key( &attributes, &handle, key_bytes, key_length ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100220
221 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100222 /* Whether setup succeeded or failed, abort must succeed. */
223 PSA_ASSERT( psa_mac_abort( operation ) );
224 /* If setup failed, reproduce the failure, so that the caller can
225 * test the resulting state of the operation object. */
226 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100227 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100228 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
229 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100230 }
231
232 psa_destroy_key( handle );
233 return( 1 );
234
235exit:
236 psa_destroy_key( handle );
237 return( 0 );
238}
239
240int exercise_cipher_setup( psa_key_type_t key_type,
241 const unsigned char *key_bytes,
242 size_t key_length,
243 psa_algorithm_t alg,
244 psa_cipher_operation_t *operation,
245 psa_status_t *status )
246{
247 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200248 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100249
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200250 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
251 psa_set_key_algorithm( &attributes, alg );
252 psa_set_key_type( &attributes, key_type );
253 PSA_ASSERT( psa_import_key( &attributes, &handle, key_bytes, key_length ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100254
255 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100256 /* Whether setup succeeded or failed, abort must succeed. */
257 PSA_ASSERT( psa_cipher_abort( operation ) );
258 /* If setup failed, reproduce the failure, so that the caller can
259 * test the resulting state of the operation object. */
260 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100261 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100262 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
263 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100264 }
265
266 psa_destroy_key( handle );
267 return( 1 );
268
269exit:
270 psa_destroy_key( handle );
271 return( 0 );
272}
273
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100274static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200275 psa_key_usage_t usage,
276 psa_algorithm_t alg )
277{
Jaeden Amero769ce272019-01-04 11:48:03 +0000278 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200279 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200280 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200281 size_t mac_length = sizeof( mac );
282
283 if( usage & PSA_KEY_USAGE_SIGN )
284 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100285 PSA_ASSERT( psa_mac_sign_setup( &operation,
286 handle, alg ) );
287 PSA_ASSERT( psa_mac_update( &operation,
288 input, sizeof( input ) ) );
289 PSA_ASSERT( psa_mac_sign_finish( &operation,
290 mac, sizeof( mac ),
291 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200292 }
293
294 if( usage & PSA_KEY_USAGE_VERIFY )
295 {
296 psa_status_t verify_status =
297 ( usage & PSA_KEY_USAGE_SIGN ?
298 PSA_SUCCESS :
299 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100300 PSA_ASSERT( psa_mac_verify_setup( &operation,
301 handle, alg ) );
302 PSA_ASSERT( psa_mac_update( &operation,
303 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100304 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
305 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200306 }
307
308 return( 1 );
309
310exit:
311 psa_mac_abort( &operation );
312 return( 0 );
313}
314
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100315static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200316 psa_key_usage_t usage,
317 psa_algorithm_t alg )
318{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000319 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200320 unsigned char iv[16] = {0};
321 size_t iv_length = sizeof( iv );
322 const unsigned char plaintext[16] = "Hello, world...";
323 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
324 size_t ciphertext_length = sizeof( ciphertext );
325 unsigned char decrypted[sizeof( ciphertext )];
326 size_t part_length;
327
328 if( usage & PSA_KEY_USAGE_ENCRYPT )
329 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100330 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
331 handle, alg ) );
332 PSA_ASSERT( psa_cipher_generate_iv( &operation,
333 iv, sizeof( iv ),
334 &iv_length ) );
335 PSA_ASSERT( psa_cipher_update( &operation,
336 plaintext, sizeof( plaintext ),
337 ciphertext, sizeof( ciphertext ),
338 &ciphertext_length ) );
339 PSA_ASSERT( psa_cipher_finish( &operation,
340 ciphertext + ciphertext_length,
341 sizeof( ciphertext ) - ciphertext_length,
342 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200343 ciphertext_length += part_length;
344 }
345
346 if( usage & PSA_KEY_USAGE_DECRYPT )
347 {
348 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200349 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200350 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
351 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200352 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
353 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
354 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
355 * have this macro yet. */
356 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
357 psa_get_key_type( &attributes ) );
358 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200359 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100360 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
361 handle, alg ) );
362 PSA_ASSERT( psa_cipher_set_iv( &operation,
363 iv, iv_length ) );
364 PSA_ASSERT( psa_cipher_update( &operation,
365 ciphertext, ciphertext_length,
366 decrypted, sizeof( decrypted ),
367 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200368 status = psa_cipher_finish( &operation,
369 decrypted + part_length,
370 sizeof( decrypted ) - part_length,
371 &part_length );
372 /* For a stream cipher, all inputs are valid. For a block cipher,
373 * if the input is some aribtrary data rather than an actual
374 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200375 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200376 TEST_ASSERT( status == PSA_SUCCESS ||
377 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200378 else
379 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200380 }
381
382 return( 1 );
383
384exit:
385 psa_cipher_abort( &operation );
386 return( 0 );
387}
388
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100389static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200390 psa_key_usage_t usage,
391 psa_algorithm_t alg )
392{
393 unsigned char nonce[16] = {0};
394 size_t nonce_length = sizeof( nonce );
395 unsigned char plaintext[16] = "Hello, world...";
396 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
397 size_t ciphertext_length = sizeof( ciphertext );
398 size_t plaintext_length = sizeof( ciphertext );
399
400 if( usage & PSA_KEY_USAGE_ENCRYPT )
401 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100402 PSA_ASSERT( psa_aead_encrypt( handle, alg,
403 nonce, nonce_length,
404 NULL, 0,
405 plaintext, sizeof( plaintext ),
406 ciphertext, sizeof( ciphertext ),
407 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200408 }
409
410 if( usage & PSA_KEY_USAGE_DECRYPT )
411 {
412 psa_status_t verify_status =
413 ( usage & PSA_KEY_USAGE_ENCRYPT ?
414 PSA_SUCCESS :
415 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100416 TEST_EQUAL( psa_aead_decrypt( handle, alg,
417 nonce, nonce_length,
418 NULL, 0,
419 ciphertext, ciphertext_length,
420 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100421 &plaintext_length ),
422 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200423 }
424
425 return( 1 );
426
427exit:
428 return( 0 );
429}
430
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100431static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200432 psa_key_usage_t usage,
433 psa_algorithm_t alg )
434{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200435 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
436 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200437 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200438 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100439 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
440
441 /* If the policy allows signing with any hash, just pick one. */
442 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
443 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100444#if defined(KNOWN_SUPPORTED_HASH_ALG)
445 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
446 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100447#else
448 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100449 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100450#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100451 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200452
453 if( usage & PSA_KEY_USAGE_SIGN )
454 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200455 /* Some algorithms require the payload to have the size of
456 * the hash encoded in the algorithm. Use this input size
457 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200458 if( hash_alg != 0 )
459 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100460 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
461 payload, payload_length,
462 signature, sizeof( signature ),
463 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200464 }
465
466 if( usage & PSA_KEY_USAGE_VERIFY )
467 {
468 psa_status_t verify_status =
469 ( usage & PSA_KEY_USAGE_SIGN ?
470 PSA_SUCCESS :
471 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100472 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
473 payload, payload_length,
474 signature, signature_length ),
475 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200476 }
477
478 return( 1 );
479
480exit:
481 return( 0 );
482}
483
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100484static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200485 psa_key_usage_t usage,
486 psa_algorithm_t alg )
487{
488 unsigned char plaintext[256] = "Hello, world...";
489 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
490 size_t ciphertext_length = sizeof( ciphertext );
491 size_t plaintext_length = 16;
492
493 if( usage & PSA_KEY_USAGE_ENCRYPT )
494 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100495 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
496 plaintext, plaintext_length,
497 NULL, 0,
498 ciphertext, sizeof( ciphertext ),
499 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200500 }
501
502 if( usage & PSA_KEY_USAGE_DECRYPT )
503 {
504 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100505 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200506 ciphertext, ciphertext_length,
507 NULL, 0,
508 plaintext, sizeof( plaintext ),
509 &plaintext_length );
510 TEST_ASSERT( status == PSA_SUCCESS ||
511 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
512 ( status == PSA_ERROR_INVALID_ARGUMENT ||
513 status == PSA_ERROR_INVALID_PADDING ) ) );
514 }
515
516 return( 1 );
517
518exit:
519 return( 0 );
520}
Gilles Peskine02b75072018-07-01 22:31:34 +0200521
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100522static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200523 psa_key_usage_t usage,
524 psa_algorithm_t alg )
525{
526 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
527 unsigned char label[16] = "This is a label.";
528 size_t label_length = sizeof( label );
529 unsigned char seed[16] = "abcdefghijklmnop";
530 size_t seed_length = sizeof( seed );
531 unsigned char output[1];
532
533 if( usage & PSA_KEY_USAGE_DERIVE )
534 {
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100535 if( PSA_ALG_IS_HKDF( alg ) )
536 {
537 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
538 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
539 PSA_KDF_STEP_SALT,
540 label,
541 label_length ) );
542 PSA_ASSERT( psa_key_derivation_input_key( &generator,
543 PSA_KDF_STEP_SECRET,
544 handle ) );
545 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
546 PSA_KDF_STEP_INFO,
547 seed,
548 seed_length ) );
549 }
550 else
551 {
552 // legacy
553 PSA_ASSERT( psa_key_derivation( &generator,
554 handle, alg,
555 label, label_length,
556 seed, seed_length,
557 sizeof( output ) ) );
558 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100559 PSA_ASSERT( psa_generator_read( &generator,
560 output,
561 sizeof( output ) ) );
562 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200563 }
564
565 return( 1 );
566
567exit:
568 return( 0 );
569}
570
Gilles Peskinec7998b72018-11-07 18:45:02 +0100571/* We need two keys to exercise key agreement. Exercise the
572 * private key against its own public key. */
573static psa_status_t key_agreement_with_self( psa_crypto_generator_t *generator,
Gilles Peskine969c5d62019-01-16 15:53:06 +0100574 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100575{
576 psa_key_type_t private_key_type;
577 psa_key_type_t public_key_type;
578 size_t key_bits;
579 uint8_t *public_key = NULL;
580 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200581 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinec7998b72018-11-07 18:45:02 +0100582 * psa_key_agreement fails. This isn't fully satisfactory, but it's
583 * good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200584 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200585 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100586
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200587 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
588 private_key_type = psa_get_key_type( &attributes );
589 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100590 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
591 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
592 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100593 PSA_ASSERT( psa_export_public_key( handle,
594 public_key, public_key_length,
595 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100596
Gilles Peskine969c5d62019-01-16 15:53:06 +0100597 status = psa_key_agreement( generator, PSA_KDF_STEP_SECRET, handle,
598 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100599exit:
600 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200601 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100602 return( status );
603}
604
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200605/* We need two keys to exercise key agreement. Exercise the
606 * private key against its own public key. */
607static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
608 psa_key_handle_t handle )
609{
610 psa_key_type_t private_key_type;
611 psa_key_type_t public_key_type;
612 size_t key_bits;
613 uint8_t *public_key = NULL;
614 size_t public_key_length;
615 uint8_t output[1024];
616 size_t output_length;
617 /* Return GENERIC_ERROR if something other than the final call to
618 * psa_key_agreement fails. This isn't fully satisfactory, but it's
619 * good enough: callers will report it as a failed test anyway. */
620 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200621 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200622
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200623 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
624 private_key_type = psa_get_key_type( &attributes );
625 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200626 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
627 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
628 ASSERT_ALLOC( public_key, public_key_length );
629 PSA_ASSERT( psa_export_public_key( handle,
630 public_key, public_key_length,
631 &public_key_length ) );
632
633 status = psa_key_agreement_raw_shared_secret(
634 alg, handle,
635 public_key, public_key_length,
636 output, sizeof( output ), &output_length );
637exit:
638 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200639 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200640 return( status );
641}
642
643static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
644 psa_key_usage_t usage,
645 psa_algorithm_t alg )
646{
647 int ok = 0;
648
649 if( usage & PSA_KEY_USAGE_DERIVE )
650 {
651 /* We need two keys to exercise key agreement. Exercise the
652 * private key against its own public key. */
653 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
654 }
655 ok = 1;
656
657exit:
658 return( ok );
659}
660
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100661static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200662 psa_key_usage_t usage,
663 psa_algorithm_t alg )
664{
665 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200666 unsigned char output[1];
667 int ok = 0;
668
669 if( usage & PSA_KEY_USAGE_DERIVE )
670 {
671 /* We need two keys to exercise key agreement. Exercise the
672 * private key against its own public key. */
Gilles Peskine969c5d62019-01-16 15:53:06 +0100673 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
674 PSA_ASSERT( key_agreement_with_self( &generator, handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +0100675 PSA_ASSERT( psa_generator_read( &generator,
676 output,
677 sizeof( output ) ) );
678 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200679 }
680 ok = 1;
681
682exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200683 return( ok );
684}
685
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200686static int is_oid_of_key_type( psa_key_type_t type,
687 const uint8_t *oid, size_t oid_length )
688{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200689 const uint8_t *expected_oid = NULL;
690 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200691#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200692 if( PSA_KEY_TYPE_IS_RSA( type ) )
693 {
694 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
695 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
696 }
697 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200698#endif /* MBEDTLS_RSA_C */
699#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200700 if( PSA_KEY_TYPE_IS_ECC( type ) )
701 {
702 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
703 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
704 }
705 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200706#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200707 {
708 char message[40];
709 mbedtls_snprintf( message, sizeof( message ),
710 "OID not known for key type=0x%08lx",
711 (unsigned long) type );
712 test_fail( message, __LINE__, __FILE__ );
713 return( 0 );
714 }
715
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200716 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200717 return( 1 );
718
719exit:
720 return( 0 );
721}
722
723static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
724 size_t min_bits, size_t max_bits,
725 int must_be_odd )
726{
727 size_t len;
728 size_t actual_bits;
729 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100730 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100731 MBEDTLS_ASN1_INTEGER ),
732 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200733 /* Tolerate a slight departure from DER encoding:
734 * - 0 may be represented by an empty string or a 1-byte string.
735 * - The sign bit may be used as a value bit. */
736 if( ( len == 1 && ( *p )[0] == 0 ) ||
737 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
738 {
739 ++( *p );
740 --len;
741 }
742 if( min_bits == 0 && len == 0 )
743 return( 1 );
744 msb = ( *p )[0];
745 TEST_ASSERT( msb != 0 );
746 actual_bits = 8 * ( len - 1 );
747 while( msb != 0 )
748 {
749 msb >>= 1;
750 ++actual_bits;
751 }
752 TEST_ASSERT( actual_bits >= min_bits );
753 TEST_ASSERT( actual_bits <= max_bits );
754 if( must_be_odd )
755 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
756 *p += len;
757 return( 1 );
758exit:
759 return( 0 );
760}
761
762static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
763 size_t *len,
764 unsigned char n, unsigned char tag )
765{
766 int ret;
767 ret = mbedtls_asn1_get_tag( p, end, len,
768 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
769 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
770 if( ret != 0 )
771 return( ret );
772 end = *p + *len;
773 ret = mbedtls_asn1_get_tag( p, end, len, tag );
774 if( ret != 0 )
775 return( ret );
776 if( *p + *len != end )
777 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
778 return( 0 );
779}
780
781static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
782 uint8_t *exported, size_t exported_length )
783{
784 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100785 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200786 else
787 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200788
789#if defined(MBEDTLS_DES_C)
790 if( type == PSA_KEY_TYPE_DES )
791 {
792 /* Check the parity bits. */
793 unsigned i;
794 for( i = 0; i < bits / 8; i++ )
795 {
796 unsigned bit_count = 0;
797 unsigned m;
798 for( m = 1; m <= 0x100; m <<= 1 )
799 {
800 if( exported[i] & m )
801 ++bit_count;
802 }
803 TEST_ASSERT( bit_count % 2 != 0 );
804 }
805 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200806 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200807#endif
808
809#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
810 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
811 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200812 uint8_t *p = exported;
813 uint8_t *end = exported + exported_length;
814 size_t len;
815 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200816 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200817 * modulus INTEGER, -- n
818 * publicExponent INTEGER, -- e
819 * privateExponent INTEGER, -- d
820 * prime1 INTEGER, -- p
821 * prime2 INTEGER, -- q
822 * exponent1 INTEGER, -- d mod (p-1)
823 * exponent2 INTEGER, -- d mod (q-1)
824 * coefficient INTEGER, -- (inverse of q) mod p
825 * }
826 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100827 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
828 MBEDTLS_ASN1_SEQUENCE |
829 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
830 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200831 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
832 goto exit;
833 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
834 goto exit;
835 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
836 goto exit;
837 /* Require d to be at least half the size of n. */
838 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
839 goto exit;
840 /* Require p and q to be at most half the size of n, rounded up. */
841 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
842 goto exit;
843 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
844 goto exit;
845 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
846 goto exit;
847 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
848 goto exit;
849 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
850 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100851 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100852 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200853 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200854#endif /* MBEDTLS_RSA_C */
855
856#if defined(MBEDTLS_ECP_C)
857 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
858 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100859 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100860 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100861 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200862 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200863#endif /* MBEDTLS_ECP_C */
864
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200865 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
866 {
867 uint8_t *p = exported;
868 uint8_t *end = exported + exported_length;
869 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200870#if defined(MBEDTLS_RSA_C)
871 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
872 {
873 /* RSAPublicKey ::= SEQUENCE {
874 * modulus INTEGER, -- n
875 * publicExponent INTEGER } -- e
876 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100877 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
878 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100879 MBEDTLS_ASN1_CONSTRUCTED ),
880 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100881 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200882 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
883 goto exit;
884 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
885 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100886 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200887 }
888 else
889#endif /* MBEDTLS_RSA_C */
890#if defined(MBEDTLS_ECP_C)
891 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
892 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000893 /* The representation of an ECC public key is:
894 * - The byte 0x04;
895 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
896 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
897 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000898 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100899 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
900 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200901 }
902 else
903#endif /* MBEDTLS_ECP_C */
904 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100905 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200906 mbedtls_snprintf( message, sizeof( message ),
907 "No sanity check for public key type=0x%08lx",
908 (unsigned long) type );
909 test_fail( message, __LINE__, __FILE__ );
910 return( 0 );
911 }
912 }
913 else
914
915 {
916 /* No sanity checks for other types */
917 }
918
919 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200920
921exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200922 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200923}
924
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100925static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200926 psa_key_usage_t usage )
927{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200928 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200929 uint8_t *exported = NULL;
930 size_t exported_size = 0;
931 size_t exported_length = 0;
932 int ok = 0;
933
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200934 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200935
936 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200937 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200938 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100939 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
940 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200941 ok = 1;
942 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200943 }
944
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200945 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
946 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200947 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200948
Gilles Peskine8817f612018-12-18 00:18:46 +0100949 PSA_ASSERT( psa_export_key( handle,
950 exported, exported_size,
951 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200952 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
953 psa_get_key_bits( &attributes ),
954 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200955
956exit:
957 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200958 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200959 return( ok );
960}
961
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100962static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200963{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200964 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200965 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200966 uint8_t *exported = NULL;
967 size_t exported_size = 0;
968 size_t exported_length = 0;
969 int ok = 0;
970
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200971 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
972 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200973 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100974 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100975 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200976 return( 1 );
977 }
978
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200979 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
980 psa_get_key_type( &attributes ) );
981 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
982 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200983 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200984
Gilles Peskine8817f612018-12-18 00:18:46 +0100985 PSA_ASSERT( psa_export_public_key( handle,
986 exported, exported_size,
987 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200988 ok = exported_key_sanity_check( public_type,
989 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200990 exported, exported_length );
991
992exit:
993 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200994 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200995 return( ok );
996}
997
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100998/** Do smoke tests on a key.
999 *
1000 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1001 * sign/verify, or derivation) that is permitted according to \p usage.
1002 * \p usage and \p alg should correspond to the expected policy on the
1003 * key.
1004 *
1005 * Export the key if permitted by \p usage, and check that the output
1006 * looks sensible. If \p usage forbids export, check that
1007 * \p psa_export_key correctly rejects the attempt. If the key is
1008 * asymmetric, also check \p psa_export_public_key.
1009 *
1010 * If the key fails the tests, this function calls the test framework's
1011 * `test_fail` function and returns false. Otherwise this function returns
1012 * true. Therefore it should be used as follows:
1013 * ```
1014 * if( ! exercise_key( ... ) ) goto exit;
1015 * ```
1016 *
1017 * \param handle The key to exercise. It should be capable of performing
1018 * \p alg.
1019 * \param usage The usage flags to assume.
1020 * \param alg The algorithm to exercise.
1021 *
1022 * \retval 0 The key failed the smoke tests.
1023 * \retval 1 The key passed the smoke tests.
1024 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001025static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001026 psa_key_usage_t usage,
1027 psa_algorithm_t alg )
1028{
1029 int ok;
1030 if( alg == 0 )
1031 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1032 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001033 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001034 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001035 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001036 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001037 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001038 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001039 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001040 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001041 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001042 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001043 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001044 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1045 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001046 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001047 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001048 else
1049 {
1050 char message[40];
1051 mbedtls_snprintf( message, sizeof( message ),
1052 "No code to exercise alg=0x%08lx",
1053 (unsigned long) alg );
1054 test_fail( message, __LINE__, __FILE__ );
1055 ok = 0;
1056 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001057
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001058 ok = ok && exercise_export_key( handle, usage );
1059 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001060
Gilles Peskine02b75072018-07-01 22:31:34 +02001061 return( ok );
1062}
1063
Gilles Peskine10df3412018-10-25 22:35:43 +02001064static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1065 psa_algorithm_t alg )
1066{
1067 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1068 {
1069 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1070 PSA_KEY_USAGE_VERIFY :
1071 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1072 }
1073 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1074 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1075 {
1076 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1077 PSA_KEY_USAGE_ENCRYPT :
1078 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1079 }
1080 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1081 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1082 {
1083 return( PSA_KEY_USAGE_DERIVE );
1084 }
1085 else
1086 {
1087 return( 0 );
1088 }
1089
1090}
Darryl Green0c6575a2018-11-07 16:05:30 +00001091
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001092static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1093{
1094 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1095 uint8_t buffer[1];
1096 size_t length;
1097 int ok = 0;
1098
1099 psa_make_key_persistent( &attributes, 0x6964, PSA_KEY_LIFETIME_PERSISTENT );
1100 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1101 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1102 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1103 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1104 PSA_ERROR_INVALID_HANDLE );
1105 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001106 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001107 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1108 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1109 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1110 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1111
1112 TEST_EQUAL( psa_export_key( handle,
1113 buffer, sizeof( buffer ), &length ),
1114 PSA_ERROR_INVALID_HANDLE );
1115 TEST_EQUAL( psa_export_public_key( handle,
1116 buffer, sizeof( buffer ), &length ),
1117 PSA_ERROR_INVALID_HANDLE );
1118
1119 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1120 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1121
1122 ok = 1;
1123
1124exit:
1125 psa_reset_key_attributes( &attributes );
1126 return( ok );
1127}
1128
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001129/* An overapproximation of the amount of storage needed for a key of the
1130 * given type and with the given content. The API doesn't make it easy
1131 * to find a good value for the size. The current implementation doesn't
1132 * care about the value anyway. */
1133#define KEY_BITS_FROM_DATA( type, data ) \
1134 ( data )->len
1135
Darryl Green0c6575a2018-11-07 16:05:30 +00001136typedef enum {
1137 IMPORT_KEY = 0,
1138 GENERATE_KEY = 1,
1139 DERIVE_KEY = 2
1140} generate_method;
1141
Gilles Peskinee59236f2018-01-27 23:32:46 +01001142/* END_HEADER */
1143
1144/* BEGIN_DEPENDENCIES
1145 * depends_on:MBEDTLS_PSA_CRYPTO_C
1146 * END_DEPENDENCIES
1147 */
1148
1149/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001150void static_checks( )
1151{
1152 size_t max_truncated_mac_size =
1153 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1154
1155 /* Check that the length for a truncated MAC always fits in the algorithm
1156 * encoding. The shifted mask is the maximum truncated value. The
1157 * untruncated algorithm may be one byte larger. */
1158 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1159}
1160/* END_CASE */
1161
1162/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001163void attributes_set_get( int id_arg, int lifetime_arg,
1164 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001165 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001166{
Gilles Peskine4747d192019-04-17 15:05:45 +02001167 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001168 psa_key_id_t id = id_arg;
1169 psa_key_lifetime_t lifetime = lifetime_arg;
1170 psa_key_usage_t usage_flags = usage_flags_arg;
1171 psa_algorithm_t alg = alg_arg;
1172 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001173 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001174
1175 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1176 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1177 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1178 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1179 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001180 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001181
1182 psa_make_key_persistent( &attributes, id, lifetime );
1183 psa_set_key_usage_flags( &attributes, usage_flags );
1184 psa_set_key_algorithm( &attributes, alg );
1185 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001186 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001187
1188 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1189 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1190 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1191 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1192 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001193 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001194
1195 psa_reset_key_attributes( &attributes );
1196
1197 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1198 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1199 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1200 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1201 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001202 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001203}
1204/* END_CASE */
1205
1206/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001207void import( data_t *data, int type_arg,
1208 int attr_bits_arg,
1209 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001210{
1211 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1212 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001213 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001214 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001215 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001216 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001217 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001218
Gilles Peskine8817f612018-12-18 00:18:46 +01001219 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001220
Gilles Peskine4747d192019-04-17 15:05:45 +02001221 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001222 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine4747d192019-04-17 15:05:45 +02001223 status = psa_import_key( &attributes, &handle, data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001224 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001225 if( status != PSA_SUCCESS )
1226 goto exit;
1227
1228 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1229 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001230 if( attr_bits != 0 )
1231 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001232
1233 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001234 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001235
1236exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001237 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001238 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001239 mbedtls_psa_crypto_free( );
1240}
1241/* END_CASE */
1242
1243/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001244void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1245{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001246 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001247 size_t bits = bits_arg;
1248 psa_status_t expected_status = expected_status_arg;
1249 psa_status_t status;
1250 psa_key_type_t type =
1251 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1252 size_t buffer_size = /* Slight overapproximations */
1253 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001254 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001255 unsigned char *p;
1256 int ret;
1257 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001258 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001259
Gilles Peskine8817f612018-12-18 00:18:46 +01001260 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001261 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001262
1263 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1264 bits, keypair ) ) >= 0 );
1265 length = ret;
1266
1267 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001268 psa_set_key_type( &attributes, type );
1269 status = psa_import_key( &attributes, &handle, p, length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001270 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001271 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001272 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001273
1274exit:
1275 mbedtls_free( buffer );
1276 mbedtls_psa_crypto_free( );
1277}
1278/* END_CASE */
1279
1280/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001281void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001282 int type_arg,
1283 int alg_arg,
1284 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001285 int expected_bits,
1286 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001287 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001288 int canonical_input )
1289{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001290 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001291 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001292 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001293 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001294 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001295 unsigned char *exported = NULL;
1296 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001297 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001298 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001299 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001300 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001301 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001302
Moran Pekercb088e72018-07-17 17:36:59 +03001303 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001304 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001305 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001306 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001307 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001308
Gilles Peskine4747d192019-04-17 15:05:45 +02001309 psa_set_key_usage_flags( &attributes, usage_arg );
1310 psa_set_key_algorithm( &attributes, alg );
1311 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001312
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001313 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001314 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001315
1316 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001317 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1318 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1319 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001320
1321 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001322 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001323 exported, export_size,
1324 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001325 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001326
1327 /* The exported length must be set by psa_export_key() to a value between 0
1328 * and export_size. On errors, the exported length must be 0. */
1329 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1330 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1331 TEST_ASSERT( exported_length <= export_size );
1332
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001333 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001334 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001335 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001336 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001337 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001338 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001339 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001340
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001341 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001342 goto exit;
1343
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001344 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001345 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001346 else
1347 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001348 psa_key_handle_t handle2;
Gilles Peskine4747d192019-04-17 15:05:45 +02001349 PSA_ASSERT( psa_import_key( &attributes, &handle2,
1350 exported, exported_length ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001351 PSA_ASSERT( psa_export_key( handle2,
1352 reexported,
1353 export_size,
1354 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001355 ASSERT_COMPARE( exported, exported_length,
1356 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001357 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001358 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001359 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001360
1361destroy:
1362 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001363 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001364 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001365
1366exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001367 mbedtls_free( exported );
1368 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001369 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001370 mbedtls_psa_crypto_free( );
1371}
1372/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001373
Moran Pekerf709f4a2018-06-06 17:26:04 +03001374/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001375void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001376{
Gilles Peskine8817f612018-12-18 00:18:46 +01001377 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001378 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001379
1380exit:
1381 mbedtls_psa_crypto_free( );
1382}
1383/* END_CASE */
1384
1385/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001386void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001387 int type_arg,
1388 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001389 int export_size_delta,
1390 int expected_export_status_arg,
1391 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001392{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001393 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001394 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001395 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001396 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001397 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001398 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001399 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001400 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001401 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001402
Gilles Peskine8817f612018-12-18 00:18:46 +01001403 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001404
Gilles Peskine4747d192019-04-17 15:05:45 +02001405 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1406 psa_set_key_algorithm( &attributes, alg );
1407 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001408
1409 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001410 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001411
Gilles Peskine49c25912018-10-29 15:15:31 +01001412 /* Export the public key */
1413 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001414 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001415 exported, export_size,
1416 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001417 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001418 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001419 {
1420 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1421 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001422 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1423 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001424 TEST_ASSERT( expected_public_key->len <=
1425 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001426 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1427 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001428 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001429
1430exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001431 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001432 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001433 psa_reset_key_attributes( &attributes );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001434 mbedtls_psa_crypto_free( );
1435}
1436/* END_CASE */
1437
Gilles Peskine20035e32018-02-03 22:44:14 +01001438/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001439void import_and_exercise_key( data_t *data,
1440 int type_arg,
1441 int bits_arg,
1442 int alg_arg )
1443{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001444 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001445 psa_key_type_t type = type_arg;
1446 size_t bits = bits_arg;
1447 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001448 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001449 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001450 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001451
Gilles Peskine8817f612018-12-18 00:18:46 +01001452 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001453
Gilles Peskine4747d192019-04-17 15:05:45 +02001454 psa_set_key_usage_flags( &attributes, usage );
1455 psa_set_key_algorithm( &attributes, alg );
1456 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001457
1458 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001459 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001460
1461 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001462 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1463 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1464 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001465
1466 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001467 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001468 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001469
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001470 PSA_ASSERT( psa_destroy_key( handle ) );
1471 test_operations_on_invalid_handle( handle );
1472
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001473exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001474 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001475 psa_reset_key_attributes( &got_attributes );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001476 mbedtls_psa_crypto_free( );
1477}
1478/* END_CASE */
1479
1480/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001481void key_policy( int usage_arg, int alg_arg )
1482{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001483 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001484 psa_algorithm_t alg = alg_arg;
1485 psa_key_usage_t usage = usage_arg;
1486 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1487 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001488 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001489
1490 memset( key, 0x2a, sizeof( key ) );
1491
Gilles Peskine8817f612018-12-18 00:18:46 +01001492 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001493
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001494 psa_set_key_usage_flags( &attributes, usage );
1495 psa_set_key_algorithm( &attributes, alg );
1496 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001497
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001498 PSA_ASSERT( psa_import_key( &attributes, &handle, key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001499
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001500 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1501 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1502 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1503 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001504
1505exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001506 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001507 psa_reset_key_attributes( &attributes );
Gilles Peskined5b33222018-06-18 22:20:03 +02001508 mbedtls_psa_crypto_free( );
1509}
1510/* END_CASE */
1511
1512/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001513void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001514{
1515 /* Test each valid way of initializing the object, except for `= {0}`, as
1516 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1517 * though it's OK by the C standard. We could test for this, but we'd need
1518 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001519 psa_key_attributes_t func = psa_key_attributes_init( );
1520 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1521 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001522
1523 memset( &zero, 0, sizeof( zero ) );
1524
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001525 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1526 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1527 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001528
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001529 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1530 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1531 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1532
1533 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1534 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1535 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1536
1537 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1538 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1539 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1540
1541 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1542 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1543 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001544}
1545/* END_CASE */
1546
1547/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001548void mac_key_policy( int policy_usage,
1549 int policy_alg,
1550 int key_type,
1551 data_t *key_data,
1552 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001553{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001554 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001555 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001556 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001557 psa_status_t status;
1558 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001559
Gilles Peskine8817f612018-12-18 00:18:46 +01001560 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001561
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001562 psa_set_key_usage_flags( &attributes, policy_usage );
1563 psa_set_key_algorithm( &attributes, policy_alg );
1564 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001565
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001566 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001567 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001568
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001569 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001570 if( policy_alg == exercise_alg &&
1571 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001572 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001573 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001574 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001575 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001576
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001577 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001578 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001579 if( policy_alg == exercise_alg &&
1580 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001581 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001582 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001583 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001584
1585exit:
1586 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001587 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001588 mbedtls_psa_crypto_free( );
1589}
1590/* END_CASE */
1591
1592/* BEGIN_CASE */
1593void cipher_key_policy( int policy_usage,
1594 int policy_alg,
1595 int key_type,
1596 data_t *key_data,
1597 int exercise_alg )
1598{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001599 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001600 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001601 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001602 psa_status_t status;
1603
Gilles Peskine8817f612018-12-18 00:18:46 +01001604 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001605
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001606 psa_set_key_usage_flags( &attributes, policy_usage );
1607 psa_set_key_algorithm( &attributes, policy_alg );
1608 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001609
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001610 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001611 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001612
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001613 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001614 if( policy_alg == exercise_alg &&
1615 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001616 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001617 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001618 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001619 psa_cipher_abort( &operation );
1620
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001621 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001622 if( policy_alg == exercise_alg &&
1623 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001624 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001625 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001626 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001627
1628exit:
1629 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001630 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001631 mbedtls_psa_crypto_free( );
1632}
1633/* END_CASE */
1634
1635/* BEGIN_CASE */
1636void aead_key_policy( int policy_usage,
1637 int policy_alg,
1638 int key_type,
1639 data_t *key_data,
1640 int nonce_length_arg,
1641 int tag_length_arg,
1642 int exercise_alg )
1643{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001644 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001645 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001646 psa_status_t status;
1647 unsigned char nonce[16] = {0};
1648 size_t nonce_length = nonce_length_arg;
1649 unsigned char tag[16];
1650 size_t tag_length = tag_length_arg;
1651 size_t output_length;
1652
1653 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1654 TEST_ASSERT( tag_length <= sizeof( tag ) );
1655
Gilles Peskine8817f612018-12-18 00:18:46 +01001656 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001657
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001658 psa_set_key_usage_flags( &attributes, policy_usage );
1659 psa_set_key_algorithm( &attributes, policy_alg );
1660 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001661
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001662 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001663 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001664
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001665 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001666 nonce, nonce_length,
1667 NULL, 0,
1668 NULL, 0,
1669 tag, tag_length,
1670 &output_length );
1671 if( policy_alg == exercise_alg &&
1672 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001673 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001674 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001675 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001676
1677 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001678 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001679 nonce, nonce_length,
1680 NULL, 0,
1681 tag, tag_length,
1682 NULL, 0,
1683 &output_length );
1684 if( policy_alg == exercise_alg &&
1685 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001686 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001687 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001688 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001689
1690exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001691 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692 mbedtls_psa_crypto_free( );
1693}
1694/* END_CASE */
1695
1696/* BEGIN_CASE */
1697void asymmetric_encryption_key_policy( int policy_usage,
1698 int policy_alg,
1699 int key_type,
1700 data_t *key_data,
1701 int exercise_alg )
1702{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001703 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001704 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705 psa_status_t status;
1706 size_t key_bits;
1707 size_t buffer_length;
1708 unsigned char *buffer = NULL;
1709 size_t output_length;
1710
Gilles Peskine8817f612018-12-18 00:18:46 +01001711 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001712
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001713 psa_set_key_usage_flags( &attributes, policy_usage );
1714 psa_set_key_algorithm( &attributes, policy_alg );
1715 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001717 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001718 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001719
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001720 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1721 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001722 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1723 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001724 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001725
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001726 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001727 NULL, 0,
1728 NULL, 0,
1729 buffer, buffer_length,
1730 &output_length );
1731 if( policy_alg == exercise_alg &&
1732 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001733 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001734 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001735 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001736
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001737 if( buffer_length != 0 )
1738 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001739 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001740 buffer, buffer_length,
1741 NULL, 0,
1742 buffer, buffer_length,
1743 &output_length );
1744 if( policy_alg == exercise_alg &&
1745 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001746 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001747 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001748 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001749
1750exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001751 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001752 psa_reset_key_attributes( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001753 mbedtls_psa_crypto_free( );
1754 mbedtls_free( buffer );
1755}
1756/* END_CASE */
1757
1758/* BEGIN_CASE */
1759void asymmetric_signature_key_policy( int policy_usage,
1760 int policy_alg,
1761 int key_type,
1762 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001763 int exercise_alg,
1764 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001765{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001766 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001767 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001768 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001769 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1770 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1771 * compatible with the policy and `payload_length_arg` is supposed to be
1772 * a valid input length to sign. If `payload_length_arg <= 0`,
1773 * `exercise_alg` is supposed to be forbidden by the policy. */
1774 int compatible_alg = payload_length_arg > 0;
1775 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001776 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1777 size_t signature_length;
1778
Gilles Peskine8817f612018-12-18 00:18:46 +01001779 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001780
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001781 psa_set_key_usage_flags( &attributes, policy_usage );
1782 psa_set_key_algorithm( &attributes, policy_alg );
1783 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001784
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001785 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001786 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001787
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001788 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001789 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001790 signature, sizeof( signature ),
1791 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001792 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001793 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001794 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001795 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796
1797 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001798 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001799 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001800 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001801 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001802 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001803 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001804 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001805
1806exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001807 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001808 mbedtls_psa_crypto_free( );
1809}
1810/* END_CASE */
1811
1812/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001813void derive_key_policy( int policy_usage,
1814 int policy_alg,
1815 int key_type,
1816 data_t *key_data,
1817 int exercise_alg )
1818{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001819 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001820 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001821 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1822 psa_status_t status;
1823
Gilles Peskine8817f612018-12-18 00:18:46 +01001824 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001825
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001826 psa_set_key_usage_flags( &attributes, policy_usage );
1827 psa_set_key_algorithm( &attributes, policy_alg );
1828 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001829
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001830 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001831 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001832
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001833 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001834 exercise_alg,
1835 NULL, 0,
1836 NULL, 0,
1837 1 );
1838 if( policy_alg == exercise_alg &&
1839 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001840 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001841 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001842 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001843
1844exit:
1845 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001846 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001847 mbedtls_psa_crypto_free( );
1848}
1849/* END_CASE */
1850
1851/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001852void agreement_key_policy( int policy_usage,
1853 int policy_alg,
1854 int key_type_arg,
1855 data_t *key_data,
1856 int exercise_alg )
1857{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001858 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001859 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001860 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001861 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1862 psa_status_t status;
1863
Gilles Peskine8817f612018-12-18 00:18:46 +01001864 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001865
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001866 psa_set_key_usage_flags( &attributes, policy_usage );
1867 psa_set_key_algorithm( &attributes, policy_alg );
1868 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001869
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001870 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01001871 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001872
Gilles Peskine969c5d62019-01-16 15:53:06 +01001873 PSA_ASSERT( psa_key_derivation_setup( &generator, exercise_alg ) );
1874 status = key_agreement_with_self( &generator, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001875
Gilles Peskine01d718c2018-09-18 12:01:02 +02001876 if( policy_alg == exercise_alg &&
1877 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001878 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001879 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001880 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001881
1882exit:
1883 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001884 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001885 mbedtls_psa_crypto_free( );
1886}
1887/* END_CASE */
1888
1889/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001890void raw_agreement_key_policy( int policy_usage,
1891 int policy_alg,
1892 int key_type_arg,
1893 data_t *key_data,
1894 int exercise_alg )
1895{
1896 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001897 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001898 psa_key_type_t key_type = key_type_arg;
1899 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1900 psa_status_t status;
1901
1902 PSA_ASSERT( psa_crypto_init( ) );
1903
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001904 psa_set_key_usage_flags( &attributes, policy_usage );
1905 psa_set_key_algorithm( &attributes, policy_alg );
1906 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001907
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001908 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001909 key_data->x, key_data->len ) );
1910
1911 status = raw_key_agreement_with_self( exercise_alg, handle );
1912
1913 if( policy_alg == exercise_alg &&
1914 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1915 PSA_ASSERT( status );
1916 else
1917 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1918
1919exit:
1920 psa_generator_abort( &generator );
1921 psa_destroy_key( handle );
1922 mbedtls_psa_crypto_free( );
1923}
1924/* END_CASE */
1925
1926/* BEGIN_CASE */
Gilles Peskineca25db92019-04-19 11:43:08 +02001927void copy_key( int source_usage_arg, int source_alg_arg,
1928 int type_arg, data_t *material,
1929 int copy_attributes,
1930 int target_usage_arg, int target_alg_arg,
1931 int expected_status_arg,
1932 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001933{
Gilles Peskineca25db92019-04-19 11:43:08 +02001934 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1935 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001936 psa_key_usage_t expected_usage = expected_usage_arg;
1937 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001938 psa_key_handle_t source_handle = 0;
1939 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001940 uint8_t *export_buffer = NULL;
1941
Gilles Peskine57ab7212019-01-28 13:03:09 +01001942 PSA_ASSERT( psa_crypto_init( ) );
1943
Gilles Peskineca25db92019-04-19 11:43:08 +02001944 /* Prepare the source key. */
1945 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1946 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1947 psa_set_key_type( &source_attributes, type_arg );
1948 PSA_ASSERT( psa_import_key( &source_attributes, &source_handle,
Gilles Peskine57ab7212019-01-28 13:03:09 +01001949 material->x, material->len ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001950 /* Retrieve the key size. */
1951 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001952
Gilles Peskineca25db92019-04-19 11:43:08 +02001953 /* Prepare the target attributes. */
1954 if( copy_attributes )
1955 target_attributes = source_attributes;
1956 if( target_usage_arg != -1 )
1957 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1958 if( target_alg_arg != -1 )
1959 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001960
1961 /* Copy the key. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001962 TEST_EQUAL( psa_copy_key( source_handle,
1963 &target_attributes, &target_handle ),
1964 expected_status_arg );
1965 if( expected_status_arg != PSA_SUCCESS )
1966 {
1967 TEST_EQUAL( target_handle, 0 );
1968 goto exit;
1969 }
Gilles Peskine57ab7212019-01-28 13:03:09 +01001970
1971 /* Destroy the source to ensure that this doesn't affect the target. */
1972 PSA_ASSERT( psa_destroy_key( source_handle ) );
1973
1974 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001975 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1976 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1977 psa_get_key_type( &target_attributes ) );
1978 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1979 psa_get_key_bits( &target_attributes ) );
1980 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
1981 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001982 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1983 {
1984 size_t length;
1985 ASSERT_ALLOC( export_buffer, material->len );
1986 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1987 material->len, &length ) );
1988 ASSERT_COMPARE( material->x, material->len,
1989 export_buffer, length );
1990 }
1991 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1992 goto exit;
1993
1994 PSA_ASSERT( psa_close_key( target_handle ) );
1995
1996exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001997 psa_reset_key_attributes( &source_attributes );
1998 psa_reset_key_attributes( &target_attributes );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001999 mbedtls_psa_crypto_free( );
2000 mbedtls_free( export_buffer );
2001}
2002/* END_CASE */
2003
2004/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002005void hash_operation_init( )
2006{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002007 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002008 /* Test each valid way of initializing the object, except for `= {0}`, as
2009 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2010 * though it's OK by the C standard. We could test for this, but we'd need
2011 * to supress the Clang warning for the test. */
2012 psa_hash_operation_t func = psa_hash_operation_init( );
2013 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2014 psa_hash_operation_t zero;
2015
2016 memset( &zero, 0, sizeof( zero ) );
2017
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002018 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002019 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2020 PSA_ERROR_BAD_STATE );
2021 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2022 PSA_ERROR_BAD_STATE );
2023 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2024 PSA_ERROR_BAD_STATE );
2025
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002026 /* A default hash operation should be abortable without error. */
2027 PSA_ASSERT( psa_hash_abort( &func ) );
2028 PSA_ASSERT( psa_hash_abort( &init ) );
2029 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002030}
2031/* END_CASE */
2032
2033/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002034void hash_setup( int alg_arg,
2035 int expected_status_arg )
2036{
2037 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002038 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002039 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002040 psa_status_t status;
2041
Gilles Peskine8817f612018-12-18 00:18:46 +01002042 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002043
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002044 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002045 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002046
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002047 /* Whether setup succeeded or failed, abort must succeed. */
2048 PSA_ASSERT( psa_hash_abort( &operation ) );
2049
2050 /* If setup failed, reproduce the failure, so as to
2051 * test the resulting state of the operation object. */
2052 if( status != PSA_SUCCESS )
2053 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2054
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002055 /* Now the operation object should be reusable. */
2056#if defined(KNOWN_SUPPORTED_HASH_ALG)
2057 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2058 PSA_ASSERT( psa_hash_abort( &operation ) );
2059#endif
2060
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002061exit:
2062 mbedtls_psa_crypto_free( );
2063}
2064/* END_CASE */
2065
2066/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002067void hash_bad_order( )
2068{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002069 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002070 unsigned char input[] = "";
2071 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002072 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002073 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2074 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2075 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002076 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002077 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002078 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002079
Gilles Peskine8817f612018-12-18 00:18:46 +01002080 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002081
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002082 /* Call setup twice in a row. */
2083 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2084 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2085 PSA_ERROR_BAD_STATE );
2086 PSA_ASSERT( psa_hash_abort( &operation ) );
2087
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002088 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002089 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002090 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002091 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002092
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002093 /* Call update after finish. */
2094 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2095 PSA_ASSERT( psa_hash_finish( &operation,
2096 hash, sizeof( hash ), &hash_len ) );
2097 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002098 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002099 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002100
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002101 /* Call verify without calling setup beforehand. */
2102 TEST_EQUAL( psa_hash_verify( &operation,
2103 valid_hash, sizeof( valid_hash ) ),
2104 PSA_ERROR_BAD_STATE );
2105 PSA_ASSERT( psa_hash_abort( &operation ) );
2106
2107 /* Call verify after finish. */
2108 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2109 PSA_ASSERT( psa_hash_finish( &operation,
2110 hash, sizeof( hash ), &hash_len ) );
2111 TEST_EQUAL( psa_hash_verify( &operation,
2112 valid_hash, sizeof( valid_hash ) ),
2113 PSA_ERROR_BAD_STATE );
2114 PSA_ASSERT( psa_hash_abort( &operation ) );
2115
2116 /* Call verify twice in a row. */
2117 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2118 PSA_ASSERT( psa_hash_verify( &operation,
2119 valid_hash, sizeof( valid_hash ) ) );
2120 TEST_EQUAL( psa_hash_verify( &operation,
2121 valid_hash, sizeof( valid_hash ) ),
2122 PSA_ERROR_BAD_STATE );
2123 PSA_ASSERT( psa_hash_abort( &operation ) );
2124
2125 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002126 TEST_EQUAL( psa_hash_finish( &operation,
2127 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002128 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002129 PSA_ASSERT( psa_hash_abort( &operation ) );
2130
2131 /* Call finish twice in a row. */
2132 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2133 PSA_ASSERT( psa_hash_finish( &operation,
2134 hash, sizeof( hash ), &hash_len ) );
2135 TEST_EQUAL( psa_hash_finish( &operation,
2136 hash, sizeof( hash ), &hash_len ),
2137 PSA_ERROR_BAD_STATE );
2138 PSA_ASSERT( psa_hash_abort( &operation ) );
2139
2140 /* Call finish after calling verify. */
2141 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2142 PSA_ASSERT( psa_hash_verify( &operation,
2143 valid_hash, sizeof( valid_hash ) ) );
2144 TEST_EQUAL( psa_hash_finish( &operation,
2145 hash, sizeof( hash ), &hash_len ),
2146 PSA_ERROR_BAD_STATE );
2147 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002148
2149exit:
2150 mbedtls_psa_crypto_free( );
2151}
2152/* END_CASE */
2153
itayzafrir27e69452018-11-01 14:26:34 +02002154/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2155void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002156{
2157 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002158 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2159 * appended to it */
2160 unsigned char hash[] = {
2161 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2162 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2163 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002164 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002165 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002166
Gilles Peskine8817f612018-12-18 00:18:46 +01002167 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002168
itayzafrir27e69452018-11-01 14:26:34 +02002169 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002170 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002171 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002172 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002173
itayzafrir27e69452018-11-01 14:26:34 +02002174 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002175 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002176 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002177 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002178
itayzafrir27e69452018-11-01 14:26:34 +02002179 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002180 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002181 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002182 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002183
itayzafrirec93d302018-10-18 18:01:10 +03002184exit:
2185 mbedtls_psa_crypto_free( );
2186}
2187/* END_CASE */
2188
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002189/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2190void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002191{
2192 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002193 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002194 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002195 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002196 size_t hash_len;
2197
Gilles Peskine8817f612018-12-18 00:18:46 +01002198 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002199
itayzafrir58028322018-10-25 10:22:01 +03002200 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002201 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002202 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002203 hash, expected_size - 1, &hash_len ),
2204 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002205
2206exit:
2207 mbedtls_psa_crypto_free( );
2208}
2209/* END_CASE */
2210
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002211/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2212void hash_clone_source_state( )
2213{
2214 psa_algorithm_t alg = PSA_ALG_SHA_256;
2215 unsigned char hash[PSA_HASH_MAX_SIZE];
2216 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2217 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2218 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2219 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2220 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2221 size_t hash_len;
2222
2223 PSA_ASSERT( psa_crypto_init( ) );
2224 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2225
2226 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2227 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2228 PSA_ASSERT( psa_hash_finish( &op_finished,
2229 hash, sizeof( hash ), &hash_len ) );
2230 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2231 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2232
2233 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2234 PSA_ERROR_BAD_STATE );
2235
2236 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2237 PSA_ASSERT( psa_hash_finish( &op_init,
2238 hash, sizeof( hash ), &hash_len ) );
2239 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2240 PSA_ASSERT( psa_hash_finish( &op_finished,
2241 hash, sizeof( hash ), &hash_len ) );
2242 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2243 PSA_ASSERT( psa_hash_finish( &op_aborted,
2244 hash, sizeof( hash ), &hash_len ) );
2245
2246exit:
2247 psa_hash_abort( &op_source );
2248 psa_hash_abort( &op_init );
2249 psa_hash_abort( &op_setup );
2250 psa_hash_abort( &op_finished );
2251 psa_hash_abort( &op_aborted );
2252 mbedtls_psa_crypto_free( );
2253}
2254/* END_CASE */
2255
2256/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2257void hash_clone_target_state( )
2258{
2259 psa_algorithm_t alg = PSA_ALG_SHA_256;
2260 unsigned char hash[PSA_HASH_MAX_SIZE];
2261 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2262 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2263 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2264 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2265 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2266 size_t hash_len;
2267
2268 PSA_ASSERT( psa_crypto_init( ) );
2269
2270 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2271 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2272 PSA_ASSERT( psa_hash_finish( &op_finished,
2273 hash, sizeof( hash ), &hash_len ) );
2274 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2275 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2276
2277 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2278 PSA_ASSERT( psa_hash_finish( &op_target,
2279 hash, sizeof( hash ), &hash_len ) );
2280
2281 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2282 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2283 PSA_ERROR_BAD_STATE );
2284 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2285 PSA_ERROR_BAD_STATE );
2286
2287exit:
2288 psa_hash_abort( &op_target );
2289 psa_hash_abort( &op_init );
2290 psa_hash_abort( &op_setup );
2291 psa_hash_abort( &op_finished );
2292 psa_hash_abort( &op_aborted );
2293 mbedtls_psa_crypto_free( );
2294}
2295/* END_CASE */
2296
itayzafrir58028322018-10-25 10:22:01 +03002297/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002298void mac_operation_init( )
2299{
Jaeden Amero252ef282019-02-15 14:05:35 +00002300 const uint8_t input[1] = { 0 };
2301
Jaeden Amero769ce272019-01-04 11:48:03 +00002302 /* Test each valid way of initializing the object, except for `= {0}`, as
2303 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2304 * though it's OK by the C standard. We could test for this, but we'd need
2305 * to supress the Clang warning for the test. */
2306 psa_mac_operation_t func = psa_mac_operation_init( );
2307 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2308 psa_mac_operation_t zero;
2309
2310 memset( &zero, 0, sizeof( zero ) );
2311
Jaeden Amero252ef282019-02-15 14:05:35 +00002312 /* A freshly-initialized MAC operation should not be usable. */
2313 TEST_EQUAL( psa_mac_update( &func,
2314 input, sizeof( input ) ),
2315 PSA_ERROR_BAD_STATE );
2316 TEST_EQUAL( psa_mac_update( &init,
2317 input, sizeof( input ) ),
2318 PSA_ERROR_BAD_STATE );
2319 TEST_EQUAL( psa_mac_update( &zero,
2320 input, sizeof( input ) ),
2321 PSA_ERROR_BAD_STATE );
2322
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002323 /* A default MAC operation should be abortable without error. */
2324 PSA_ASSERT( psa_mac_abort( &func ) );
2325 PSA_ASSERT( psa_mac_abort( &init ) );
2326 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002327}
2328/* END_CASE */
2329
2330/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002331void mac_setup( int key_type_arg,
2332 data_t *key,
2333 int alg_arg,
2334 int expected_status_arg )
2335{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002336 psa_key_type_t key_type = key_type_arg;
2337 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002338 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002339 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002340 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2341#if defined(KNOWN_SUPPORTED_MAC_ALG)
2342 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2343#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002344
Gilles Peskine8817f612018-12-18 00:18:46 +01002345 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002346
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002347 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2348 &operation, &status ) )
2349 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002350 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002351
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002352 /* The operation object should be reusable. */
2353#if defined(KNOWN_SUPPORTED_MAC_ALG)
2354 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2355 smoke_test_key_data,
2356 sizeof( smoke_test_key_data ),
2357 KNOWN_SUPPORTED_MAC_ALG,
2358 &operation, &status ) )
2359 goto exit;
2360 TEST_EQUAL( status, PSA_SUCCESS );
2361#endif
2362
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002363exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002364 mbedtls_psa_crypto_free( );
2365}
2366/* END_CASE */
2367
2368/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002369void mac_bad_order( )
2370{
2371 psa_key_handle_t handle = 0;
2372 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2373 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2374 const uint8_t key[] = {
2375 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2376 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2377 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002378 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002379 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2380 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2381 size_t sign_mac_length = 0;
2382 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2383 const uint8_t verify_mac[] = {
2384 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2385 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2386 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2387
2388 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002389 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2390 psa_set_key_algorithm( &attributes, alg );
2391 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002392
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002393 PSA_ASSERT( psa_import_key( &attributes, &handle,
Jaeden Amero252ef282019-02-15 14:05:35 +00002394 key, sizeof(key) ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002395
Jaeden Amero252ef282019-02-15 14:05:35 +00002396 /* Call update without calling setup beforehand. */
2397 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2398 PSA_ERROR_BAD_STATE );
2399 PSA_ASSERT( psa_mac_abort( &operation ) );
2400
2401 /* Call sign finish without calling setup beforehand. */
2402 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2403 &sign_mac_length),
2404 PSA_ERROR_BAD_STATE );
2405 PSA_ASSERT( psa_mac_abort( &operation ) );
2406
2407 /* Call verify finish without calling setup beforehand. */
2408 TEST_EQUAL( psa_mac_verify_finish( &operation,
2409 verify_mac, sizeof( verify_mac ) ),
2410 PSA_ERROR_BAD_STATE );
2411 PSA_ASSERT( psa_mac_abort( &operation ) );
2412
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002413 /* Call setup twice in a row. */
2414 PSA_ASSERT( psa_mac_sign_setup( &operation,
2415 handle, alg ) );
2416 TEST_EQUAL( psa_mac_sign_setup( &operation,
2417 handle, alg ),
2418 PSA_ERROR_BAD_STATE );
2419 PSA_ASSERT( psa_mac_abort( &operation ) );
2420
Jaeden Amero252ef282019-02-15 14:05:35 +00002421 /* Call update after sign finish. */
2422 PSA_ASSERT( psa_mac_sign_setup( &operation,
2423 handle, alg ) );
2424 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2425 PSA_ASSERT( psa_mac_sign_finish( &operation,
2426 sign_mac, sizeof( sign_mac ),
2427 &sign_mac_length ) );
2428 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2429 PSA_ERROR_BAD_STATE );
2430 PSA_ASSERT( psa_mac_abort( &operation ) );
2431
2432 /* Call update after verify finish. */
2433 PSA_ASSERT( psa_mac_verify_setup( &operation,
2434 handle, alg ) );
2435 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2436 PSA_ASSERT( psa_mac_verify_finish( &operation,
2437 verify_mac, sizeof( verify_mac ) ) );
2438 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2439 PSA_ERROR_BAD_STATE );
2440 PSA_ASSERT( psa_mac_abort( &operation ) );
2441
2442 /* Call sign finish twice in a row. */
2443 PSA_ASSERT( psa_mac_sign_setup( &operation,
2444 handle, alg ) );
2445 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2446 PSA_ASSERT( psa_mac_sign_finish( &operation,
2447 sign_mac, sizeof( sign_mac ),
2448 &sign_mac_length ) );
2449 TEST_EQUAL( psa_mac_sign_finish( &operation,
2450 sign_mac, sizeof( sign_mac ),
2451 &sign_mac_length ),
2452 PSA_ERROR_BAD_STATE );
2453 PSA_ASSERT( psa_mac_abort( &operation ) );
2454
2455 /* Call verify finish twice in a row. */
2456 PSA_ASSERT( psa_mac_verify_setup( &operation,
2457 handle, alg ) );
2458 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2459 PSA_ASSERT( psa_mac_verify_finish( &operation,
2460 verify_mac, sizeof( verify_mac ) ) );
2461 TEST_EQUAL( psa_mac_verify_finish( &operation,
2462 verify_mac, sizeof( verify_mac ) ),
2463 PSA_ERROR_BAD_STATE );
2464 PSA_ASSERT( psa_mac_abort( &operation ) );
2465
2466 /* Setup sign but try verify. */
2467 PSA_ASSERT( psa_mac_sign_setup( &operation,
2468 handle, alg ) );
2469 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2470 TEST_EQUAL( psa_mac_verify_finish( &operation,
2471 verify_mac, sizeof( verify_mac ) ),
2472 PSA_ERROR_BAD_STATE );
2473 PSA_ASSERT( psa_mac_abort( &operation ) );
2474
2475 /* Setup verify but try sign. */
2476 PSA_ASSERT( psa_mac_verify_setup( &operation,
2477 handle, alg ) );
2478 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2479 TEST_EQUAL( psa_mac_sign_finish( &operation,
2480 sign_mac, sizeof( sign_mac ),
2481 &sign_mac_length ),
2482 PSA_ERROR_BAD_STATE );
2483 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002484
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002485exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002486 mbedtls_psa_crypto_free( );
2487}
2488/* END_CASE */
2489
2490/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002491void mac_sign( int key_type_arg,
2492 data_t *key,
2493 int alg_arg,
2494 data_t *input,
2495 data_t *expected_mac )
2496{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002497 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002498 psa_key_type_t key_type = key_type_arg;
2499 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002500 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002501 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002502 /* Leave a little extra room in the output buffer. At the end of the
2503 * test, we'll check that the implementation didn't overwrite onto
2504 * this extra room. */
2505 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2506 size_t mac_buffer_size =
2507 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2508 size_t mac_length = 0;
2509
2510 memset( actual_mac, '+', sizeof( actual_mac ) );
2511 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2512 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2513
Gilles Peskine8817f612018-12-18 00:18:46 +01002514 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002515
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002516 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2517 psa_set_key_algorithm( &attributes, alg );
2518 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002519
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002520 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002521 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002522
2523 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002524 PSA_ASSERT( psa_mac_sign_setup( &operation,
2525 handle, alg ) );
2526 PSA_ASSERT( psa_mac_update( &operation,
2527 input->x, input->len ) );
2528 PSA_ASSERT( psa_mac_sign_finish( &operation,
2529 actual_mac, mac_buffer_size,
2530 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002531
2532 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002533 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2534 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002535
2536 /* Verify that the end of the buffer is untouched. */
2537 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2538 sizeof( actual_mac ) - mac_length ) );
2539
2540exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002541 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002542 mbedtls_psa_crypto_free( );
2543}
2544/* END_CASE */
2545
2546/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002547void mac_verify( int key_type_arg,
2548 data_t *key,
2549 int alg_arg,
2550 data_t *input,
2551 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002552{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002553 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002554 psa_key_type_t key_type = key_type_arg;
2555 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002556 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002557 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002558
Gilles Peskine69c12672018-06-28 00:07:19 +02002559 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2560
Gilles Peskine8817f612018-12-18 00:18:46 +01002561 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002562
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002563 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2564 psa_set_key_algorithm( &attributes, alg );
2565 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002566
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002567 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002568 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002569
Gilles Peskine8817f612018-12-18 00:18:46 +01002570 PSA_ASSERT( psa_mac_verify_setup( &operation,
2571 handle, alg ) );
2572 PSA_ASSERT( psa_destroy_key( handle ) );
2573 PSA_ASSERT( psa_mac_update( &operation,
2574 input->x, input->len ) );
2575 PSA_ASSERT( psa_mac_verify_finish( &operation,
2576 expected_mac->x,
2577 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002578
2579exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002580 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002581 mbedtls_psa_crypto_free( );
2582}
2583/* END_CASE */
2584
2585/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002586void cipher_operation_init( )
2587{
Jaeden Ameroab439972019-02-15 14:12:05 +00002588 const uint8_t input[1] = { 0 };
2589 unsigned char output[1] = { 0 };
2590 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002591 /* Test each valid way of initializing the object, except for `= {0}`, as
2592 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2593 * though it's OK by the C standard. We could test for this, but we'd need
2594 * to supress the Clang warning for the test. */
2595 psa_cipher_operation_t func = psa_cipher_operation_init( );
2596 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2597 psa_cipher_operation_t zero;
2598
2599 memset( &zero, 0, sizeof( zero ) );
2600
Jaeden Ameroab439972019-02-15 14:12:05 +00002601 /* A freshly-initialized cipher operation should not be usable. */
2602 TEST_EQUAL( psa_cipher_update( &func,
2603 input, sizeof( input ),
2604 output, sizeof( output ),
2605 &output_length ),
2606 PSA_ERROR_BAD_STATE );
2607 TEST_EQUAL( psa_cipher_update( &init,
2608 input, sizeof( input ),
2609 output, sizeof( output ),
2610 &output_length ),
2611 PSA_ERROR_BAD_STATE );
2612 TEST_EQUAL( psa_cipher_update( &zero,
2613 input, sizeof( input ),
2614 output, sizeof( output ),
2615 &output_length ),
2616 PSA_ERROR_BAD_STATE );
2617
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002618 /* A default cipher operation should be abortable without error. */
2619 PSA_ASSERT( psa_cipher_abort( &func ) );
2620 PSA_ASSERT( psa_cipher_abort( &init ) );
2621 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002622}
2623/* END_CASE */
2624
2625/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002626void cipher_setup( int key_type_arg,
2627 data_t *key,
2628 int alg_arg,
2629 int expected_status_arg )
2630{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002631 psa_key_type_t key_type = key_type_arg;
2632 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002633 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002634 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002635 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002636#if defined(KNOWN_SUPPORTED_MAC_ALG)
2637 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2638#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002639
Gilles Peskine8817f612018-12-18 00:18:46 +01002640 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002641
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002642 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2643 &operation, &status ) )
2644 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002645 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002646
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002647 /* The operation object should be reusable. */
2648#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2649 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2650 smoke_test_key_data,
2651 sizeof( smoke_test_key_data ),
2652 KNOWN_SUPPORTED_CIPHER_ALG,
2653 &operation, &status ) )
2654 goto exit;
2655 TEST_EQUAL( status, PSA_SUCCESS );
2656#endif
2657
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002658exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002659 mbedtls_psa_crypto_free( );
2660}
2661/* END_CASE */
2662
2663/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002664void cipher_bad_order( )
2665{
2666 psa_key_handle_t handle = 0;
2667 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2668 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002669 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002670 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2671 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2672 const uint8_t key[] = {
2673 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2674 0xaa, 0xaa, 0xaa, 0xaa };
2675 const uint8_t text[] = {
2676 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2677 0xbb, 0xbb, 0xbb, 0xbb };
2678 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2679 size_t length = 0;
2680
2681 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002682 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2683 psa_set_key_algorithm( &attributes, alg );
2684 psa_set_key_type( &attributes, key_type );
2685 PSA_ASSERT( psa_import_key( &attributes, &handle,
Jaeden Ameroab439972019-02-15 14:12:05 +00002686 key, sizeof(key) ) );
2687
2688
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002689 /* Call encrypt setup twice in a row. */
2690 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2691 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2692 PSA_ERROR_BAD_STATE );
2693 PSA_ASSERT( psa_cipher_abort( &operation ) );
2694
2695 /* Call decrypt setup twice in a row. */
2696 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2697 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2698 PSA_ERROR_BAD_STATE );
2699 PSA_ASSERT( psa_cipher_abort( &operation ) );
2700
Jaeden Ameroab439972019-02-15 14:12:05 +00002701 /* Generate an IV without calling setup beforehand. */
2702 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2703 buffer, sizeof( buffer ),
2704 &length ),
2705 PSA_ERROR_BAD_STATE );
2706 PSA_ASSERT( psa_cipher_abort( &operation ) );
2707
2708 /* Generate an IV twice in a row. */
2709 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2710 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2711 buffer, sizeof( buffer ),
2712 &length ) );
2713 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2714 buffer, sizeof( buffer ),
2715 &length ),
2716 PSA_ERROR_BAD_STATE );
2717 PSA_ASSERT( psa_cipher_abort( &operation ) );
2718
2719 /* Generate an IV after it's already set. */
2720 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2721 PSA_ASSERT( psa_cipher_set_iv( &operation,
2722 iv, sizeof( iv ) ) );
2723 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2724 buffer, sizeof( buffer ),
2725 &length ),
2726 PSA_ERROR_BAD_STATE );
2727 PSA_ASSERT( psa_cipher_abort( &operation ) );
2728
2729 /* Set an IV without calling setup beforehand. */
2730 TEST_EQUAL( psa_cipher_set_iv( &operation,
2731 iv, sizeof( iv ) ),
2732 PSA_ERROR_BAD_STATE );
2733 PSA_ASSERT( psa_cipher_abort( &operation ) );
2734
2735 /* Set an IV after it's already set. */
2736 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2737 PSA_ASSERT( psa_cipher_set_iv( &operation,
2738 iv, sizeof( iv ) ) );
2739 TEST_EQUAL( psa_cipher_set_iv( &operation,
2740 iv, sizeof( iv ) ),
2741 PSA_ERROR_BAD_STATE );
2742 PSA_ASSERT( psa_cipher_abort( &operation ) );
2743
2744 /* Set an IV after it's already generated. */
2745 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2746 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2747 buffer, sizeof( buffer ),
2748 &length ) );
2749 TEST_EQUAL( psa_cipher_set_iv( &operation,
2750 iv, sizeof( iv ) ),
2751 PSA_ERROR_BAD_STATE );
2752 PSA_ASSERT( psa_cipher_abort( &operation ) );
2753
2754 /* Call update without calling setup beforehand. */
2755 TEST_EQUAL( psa_cipher_update( &operation,
2756 text, sizeof( text ),
2757 buffer, sizeof( buffer ),
2758 &length ),
2759 PSA_ERROR_BAD_STATE );
2760 PSA_ASSERT( psa_cipher_abort( &operation ) );
2761
2762 /* Call update without an IV where an IV is required. */
2763 TEST_EQUAL( psa_cipher_update( &operation,
2764 text, sizeof( text ),
2765 buffer, sizeof( buffer ),
2766 &length ),
2767 PSA_ERROR_BAD_STATE );
2768 PSA_ASSERT( psa_cipher_abort( &operation ) );
2769
2770 /* Call update after finish. */
2771 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2772 PSA_ASSERT( psa_cipher_set_iv( &operation,
2773 iv, sizeof( iv ) ) );
2774 PSA_ASSERT( psa_cipher_finish( &operation,
2775 buffer, sizeof( buffer ), &length ) );
2776 TEST_EQUAL( psa_cipher_update( &operation,
2777 text, sizeof( text ),
2778 buffer, sizeof( buffer ),
2779 &length ),
2780 PSA_ERROR_BAD_STATE );
2781 PSA_ASSERT( psa_cipher_abort( &operation ) );
2782
2783 /* Call finish without calling setup beforehand. */
2784 TEST_EQUAL( psa_cipher_finish( &operation,
2785 buffer, sizeof( buffer ), &length ),
2786 PSA_ERROR_BAD_STATE );
2787 PSA_ASSERT( psa_cipher_abort( &operation ) );
2788
2789 /* Call finish without an IV where an IV is required. */
2790 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2791 /* Not calling update means we are encrypting an empty buffer, which is OK
2792 * for cipher modes with padding. */
2793 TEST_EQUAL( psa_cipher_finish( &operation,
2794 buffer, sizeof( buffer ), &length ),
2795 PSA_ERROR_BAD_STATE );
2796 PSA_ASSERT( psa_cipher_abort( &operation ) );
2797
2798 /* Call finish twice in a row. */
2799 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2800 PSA_ASSERT( psa_cipher_set_iv( &operation,
2801 iv, sizeof( iv ) ) );
2802 PSA_ASSERT( psa_cipher_finish( &operation,
2803 buffer, sizeof( buffer ), &length ) );
2804 TEST_EQUAL( psa_cipher_finish( &operation,
2805 buffer, sizeof( buffer ), &length ),
2806 PSA_ERROR_BAD_STATE );
2807 PSA_ASSERT( psa_cipher_abort( &operation ) );
2808
2809exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002810 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002811}
2812/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002813
Gilles Peskine50e586b2018-06-08 14:28:46 +02002814/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002815void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002816 data_t *key,
2817 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002818 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002819{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002820 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002821 psa_status_t status;
2822 psa_key_type_t key_type = key_type_arg;
2823 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002824 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002825 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002826 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002827 unsigned char *output = NULL;
2828 size_t output_buffer_size = 0;
2829 size_t function_output_length = 0;
2830 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002831 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002832 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002833
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002834 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2835 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002836
Gilles Peskine8817f612018-12-18 00:18:46 +01002837 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002838
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002839 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2840 psa_set_key_algorithm( &attributes, alg );
2841 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002842
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002843 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002844 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002845
Gilles Peskine8817f612018-12-18 00:18:46 +01002846 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2847 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002848
Gilles Peskine8817f612018-12-18 00:18:46 +01002849 PSA_ASSERT( psa_cipher_set_iv( &operation,
2850 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002851 output_buffer_size = ( (size_t) input->len +
2852 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002853 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002854
Gilles Peskine8817f612018-12-18 00:18:46 +01002855 PSA_ASSERT( psa_cipher_update( &operation,
2856 input->x, input->len,
2857 output, output_buffer_size,
2858 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002859 total_output_length += function_output_length;
2860 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002861 output + total_output_length,
2862 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002863 &function_output_length );
2864 total_output_length += function_output_length;
2865
Gilles Peskinefe11b722018-12-18 00:24:04 +01002866 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002867 if( expected_status == PSA_SUCCESS )
2868 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002869 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002870 ASSERT_COMPARE( expected_output->x, expected_output->len,
2871 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002872 }
2873
2874exit:
2875 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002876 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002877 mbedtls_psa_crypto_free( );
2878}
2879/* END_CASE */
2880
2881/* BEGIN_CASE */
2882void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
2883 data_t *key,
2884 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002885 int first_part_size_arg,
2886 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002887 data_t *expected_output )
2888{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002889 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002890 psa_key_type_t key_type = key_type_arg;
2891 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002892 size_t first_part_size = first_part_size_arg;
2893 size_t output1_length = output1_length_arg;
2894 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002895 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002896 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002897 unsigned char *output = NULL;
2898 size_t output_buffer_size = 0;
2899 size_t function_output_length = 0;
2900 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002901 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002902 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002903
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002904 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2905 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002906
Gilles Peskine8817f612018-12-18 00:18:46 +01002907 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002908
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002909 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2910 psa_set_key_algorithm( &attributes, alg );
2911 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002912
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002913 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002914 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002915
Gilles Peskine8817f612018-12-18 00:18:46 +01002916 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2917 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002918
Gilles Peskine8817f612018-12-18 00:18:46 +01002919 PSA_ASSERT( psa_cipher_set_iv( &operation,
2920 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002921 output_buffer_size = ( (size_t) input->len +
2922 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002923 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924
Gilles Peskinee0866522019-02-19 19:44:00 +01002925 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002926 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2927 output, output_buffer_size,
2928 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002929 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002930 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002931 PSA_ASSERT( psa_cipher_update( &operation,
2932 input->x + first_part_size,
2933 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002934 output + total_output_length,
2935 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002936 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002937 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002938 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002939 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002940 output + total_output_length,
2941 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002942 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002943 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002944 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002945
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002946 ASSERT_COMPARE( expected_output->x, expected_output->len,
2947 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002948
2949exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002950 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002951 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952 mbedtls_psa_crypto_free( );
2953}
2954/* END_CASE */
2955
2956/* BEGIN_CASE */
2957void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002958 data_t *key,
2959 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002960 int first_part_size_arg,
2961 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002962 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002963{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002964 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002965
2966 psa_key_type_t key_type = key_type_arg;
2967 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002968 size_t first_part_size = first_part_size_arg;
2969 size_t output1_length = output1_length_arg;
2970 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002971 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002972 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002973 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002974 size_t output_buffer_size = 0;
2975 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002976 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002977 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002978 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002979
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002980 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2981 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002982
Gilles Peskine8817f612018-12-18 00:18:46 +01002983 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002984
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002985 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
2986 psa_set_key_algorithm( &attributes, alg );
2987 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002988
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002989 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01002990 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002991
Gilles Peskine8817f612018-12-18 00:18:46 +01002992 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
2993 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002994
Gilles Peskine8817f612018-12-18 00:18:46 +01002995 PSA_ASSERT( psa_cipher_set_iv( &operation,
2996 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002997
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002998 output_buffer_size = ( (size_t) input->len +
2999 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003000 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003001
Gilles Peskinee0866522019-02-19 19:44:00 +01003002 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003003 PSA_ASSERT( psa_cipher_update( &operation,
3004 input->x, first_part_size,
3005 output, output_buffer_size,
3006 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003007 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003008 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003009 PSA_ASSERT( psa_cipher_update( &operation,
3010 input->x + first_part_size,
3011 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003012 output + total_output_length,
3013 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003014 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003015 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003016 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003017 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003018 output + total_output_length,
3019 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003020 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003021 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003022 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003023
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003024 ASSERT_COMPARE( expected_output->x, expected_output->len,
3025 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003026
3027exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003028 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003029 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003030 mbedtls_psa_crypto_free( );
3031}
3032/* END_CASE */
3033
Gilles Peskine50e586b2018-06-08 14:28:46 +02003034/* BEGIN_CASE */
3035void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003036 data_t *key,
3037 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003038 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003039{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003040 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041 psa_status_t status;
3042 psa_key_type_t key_type = key_type_arg;
3043 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003044 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003045 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003046 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003047 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003048 size_t output_buffer_size = 0;
3049 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003050 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003051 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003052 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003053
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003054 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3055 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003056
Gilles Peskine8817f612018-12-18 00:18:46 +01003057 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003058
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003059 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3060 psa_set_key_algorithm( &attributes, alg );
3061 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003062
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003063 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003064 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003065
Gilles Peskine8817f612018-12-18 00:18:46 +01003066 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3067 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003068
Gilles Peskine8817f612018-12-18 00:18:46 +01003069 PSA_ASSERT( psa_cipher_set_iv( &operation,
3070 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003071
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003072 output_buffer_size = ( (size_t) input->len +
3073 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003074 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003075
Gilles Peskine8817f612018-12-18 00:18:46 +01003076 PSA_ASSERT( psa_cipher_update( &operation,
3077 input->x, input->len,
3078 output, output_buffer_size,
3079 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003080 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003081 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003082 output + total_output_length,
3083 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003084 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003085 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003086 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003087
3088 if( expected_status == PSA_SUCCESS )
3089 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003090 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003091 ASSERT_COMPARE( expected_output->x, expected_output->len,
3092 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003093 }
3094
Gilles Peskine50e586b2018-06-08 14:28:46 +02003095exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003096 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003097 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003098 mbedtls_psa_crypto_free( );
3099}
3100/* END_CASE */
3101
Gilles Peskine50e586b2018-06-08 14:28:46 +02003102/* BEGIN_CASE */
3103void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003104 data_t *key,
3105 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003106{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003107 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003108 psa_key_type_t key_type = key_type_arg;
3109 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003110 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003111 size_t iv_size = 16;
3112 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003113 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003114 size_t output1_size = 0;
3115 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003116 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003117 size_t output2_size = 0;
3118 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003119 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003120 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3121 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003122 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003123
Gilles Peskine8817f612018-12-18 00:18:46 +01003124 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003125
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003126 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3127 psa_set_key_algorithm( &attributes, alg );
3128 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003129
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003130 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003131 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003132
Gilles Peskine8817f612018-12-18 00:18:46 +01003133 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3134 handle, alg ) );
3135 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3136 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003137
Gilles Peskine8817f612018-12-18 00:18:46 +01003138 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3139 iv, iv_size,
3140 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003141 output1_size = ( (size_t) input->len +
3142 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003143 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003144
Gilles Peskine8817f612018-12-18 00:18:46 +01003145 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3146 output1, output1_size,
3147 &output1_length ) );
3148 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003149 output1 + output1_length,
3150 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003151 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003152
Gilles Peskine048b7f02018-06-08 14:20:49 +02003153 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003154
Gilles Peskine8817f612018-12-18 00:18:46 +01003155 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003156
3157 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003158 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003159
Gilles Peskine8817f612018-12-18 00:18:46 +01003160 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3161 iv, iv_length ) );
3162 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3163 output2, output2_size,
3164 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003165 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003166 PSA_ASSERT( psa_cipher_finish( &operation2,
3167 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003168 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003169 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003170
Gilles Peskine048b7f02018-06-08 14:20:49 +02003171 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003172
Gilles Peskine8817f612018-12-18 00:18:46 +01003173 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003174
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003175 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003176
3177exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003178 mbedtls_free( output1 );
3179 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003180 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003181 mbedtls_psa_crypto_free( );
3182}
3183/* END_CASE */
3184
3185/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003186void cipher_verify_output_multipart( int alg_arg,
3187 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003188 data_t *key,
3189 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003190 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003191{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003192 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003193 psa_key_type_t key_type = key_type_arg;
3194 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003195 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003196 unsigned char iv[16] = {0};
3197 size_t iv_size = 16;
3198 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003199 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003200 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003201 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003202 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003203 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003204 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003205 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003206 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3207 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003208 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003209
Gilles Peskine8817f612018-12-18 00:18:46 +01003210 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003211
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003212 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3213 psa_set_key_algorithm( &attributes, alg );
3214 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003215
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003216 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003217 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003218
Gilles Peskine8817f612018-12-18 00:18:46 +01003219 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3220 handle, alg ) );
3221 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3222 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003223
Gilles Peskine8817f612018-12-18 00:18:46 +01003224 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3225 iv, iv_size,
3226 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003227 output1_buffer_size = ( (size_t) input->len +
3228 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003229 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003230
Gilles Peskinee0866522019-02-19 19:44:00 +01003231 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003232
Gilles Peskine8817f612018-12-18 00:18:46 +01003233 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3234 output1, output1_buffer_size,
3235 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003236 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003237
Gilles Peskine8817f612018-12-18 00:18:46 +01003238 PSA_ASSERT( psa_cipher_update( &operation1,
3239 input->x + first_part_size,
3240 input->len - first_part_size,
3241 output1, output1_buffer_size,
3242 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003243 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003244
Gilles Peskine8817f612018-12-18 00:18:46 +01003245 PSA_ASSERT( psa_cipher_finish( &operation1,
3246 output1 + output1_length,
3247 output1_buffer_size - output1_length,
3248 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003249 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003250
Gilles Peskine8817f612018-12-18 00:18:46 +01003251 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003252
Gilles Peskine048b7f02018-06-08 14:20:49 +02003253 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003254 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003255
Gilles Peskine8817f612018-12-18 00:18:46 +01003256 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3257 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003258
Gilles Peskine8817f612018-12-18 00:18:46 +01003259 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3260 output2, output2_buffer_size,
3261 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003262 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003263
Gilles Peskine8817f612018-12-18 00:18:46 +01003264 PSA_ASSERT( psa_cipher_update( &operation2,
3265 output1 + first_part_size,
3266 output1_length - first_part_size,
3267 output2, output2_buffer_size,
3268 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003269 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003270
Gilles Peskine8817f612018-12-18 00:18:46 +01003271 PSA_ASSERT( psa_cipher_finish( &operation2,
3272 output2 + output2_length,
3273 output2_buffer_size - output2_length,
3274 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003275 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003276
Gilles Peskine8817f612018-12-18 00:18:46 +01003277 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003278
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003279 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003280
3281exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003282 mbedtls_free( output1 );
3283 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003284 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003285 mbedtls_psa_crypto_free( );
3286}
3287/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003288
Gilles Peskine20035e32018-02-03 22:44:14 +01003289/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003290void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003291 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003292 data_t *nonce,
3293 data_t *additional_data,
3294 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003295 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003296{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003297 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003298 psa_key_type_t key_type = key_type_arg;
3299 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003300 unsigned char *output_data = NULL;
3301 size_t output_size = 0;
3302 size_t output_length = 0;
3303 unsigned char *output_data2 = NULL;
3304 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003305 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003306 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003307 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003308
Gilles Peskine4abf7412018-06-18 16:35:34 +02003309 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003310 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003311
Gilles Peskine8817f612018-12-18 00:18:46 +01003312 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003313
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003314 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3315 psa_set_key_algorithm( &attributes, alg );
3316 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003317
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003318 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01003319 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003320
Gilles Peskinefe11b722018-12-18 00:24:04 +01003321 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3322 nonce->x, nonce->len,
3323 additional_data->x,
3324 additional_data->len,
3325 input_data->x, input_data->len,
3326 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003327 &output_length ),
3328 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003329
3330 if( PSA_SUCCESS == expected_result )
3331 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003332 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003333
Gilles Peskinefe11b722018-12-18 00:24:04 +01003334 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3335 nonce->x, nonce->len,
3336 additional_data->x,
3337 additional_data->len,
3338 output_data, output_length,
3339 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003340 &output_length2 ),
3341 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003342
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003343 ASSERT_COMPARE( input_data->x, input_data->len,
3344 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003345 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003346
Gilles Peskinea1cac842018-06-11 19:33:02 +02003347exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003348 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003349 mbedtls_free( output_data );
3350 mbedtls_free( output_data2 );
3351 mbedtls_psa_crypto_free( );
3352}
3353/* END_CASE */
3354
3355/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003356void aead_encrypt( int key_type_arg, data_t *key_data,
3357 int alg_arg,
3358 data_t *nonce,
3359 data_t *additional_data,
3360 data_t *input_data,
3361 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003362{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003363 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003364 psa_key_type_t key_type = key_type_arg;
3365 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003366 unsigned char *output_data = NULL;
3367 size_t output_size = 0;
3368 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003369 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003370 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003371
Gilles Peskine4abf7412018-06-18 16:35:34 +02003372 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003373 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003374
Gilles Peskine8817f612018-12-18 00:18:46 +01003375 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003376
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003377 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3378 psa_set_key_algorithm( &attributes, alg );
3379 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003380
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003381 PSA_ASSERT( psa_import_key( &attributes, &handle,
3382 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003383
Gilles Peskine8817f612018-12-18 00:18:46 +01003384 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3385 nonce->x, nonce->len,
3386 additional_data->x, additional_data->len,
3387 input_data->x, input_data->len,
3388 output_data, output_size,
3389 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003390
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003391 ASSERT_COMPARE( expected_result->x, expected_result->len,
3392 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003393
Gilles Peskinea1cac842018-06-11 19:33:02 +02003394exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003395 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003396 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003397 mbedtls_psa_crypto_free( );
3398}
3399/* END_CASE */
3400
3401/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003402void aead_decrypt( int key_type_arg, data_t *key_data,
3403 int alg_arg,
3404 data_t *nonce,
3405 data_t *additional_data,
3406 data_t *input_data,
3407 data_t *expected_data,
3408 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003409{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003410 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003411 psa_key_type_t key_type = key_type_arg;
3412 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003413 unsigned char *output_data = NULL;
3414 size_t output_size = 0;
3415 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003416 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003417 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003418 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003419
Gilles Peskine4abf7412018-06-18 16:35:34 +02003420 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003421 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003422
Gilles Peskine8817f612018-12-18 00:18:46 +01003423 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003424
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003425 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3426 psa_set_key_algorithm( &attributes, alg );
3427 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003428
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003429 PSA_ASSERT( psa_import_key( &attributes, &handle,
3430 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003431
Gilles Peskinefe11b722018-12-18 00:24:04 +01003432 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3433 nonce->x, nonce->len,
3434 additional_data->x,
3435 additional_data->len,
3436 input_data->x, input_data->len,
3437 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003438 &output_length ),
3439 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003440
Gilles Peskine2d277862018-06-18 15:41:12 +02003441 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003442 ASSERT_COMPARE( expected_data->x, expected_data->len,
3443 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003444
Gilles Peskinea1cac842018-06-11 19:33:02 +02003445exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003446 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003447 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003448 mbedtls_psa_crypto_free( );
3449}
3450/* END_CASE */
3451
3452/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003453void signature_size( int type_arg,
3454 int bits,
3455 int alg_arg,
3456 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003457{
3458 psa_key_type_t type = type_arg;
3459 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003460 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003461 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003462exit:
3463 ;
3464}
3465/* END_CASE */
3466
3467/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003468void sign_deterministic( int key_type_arg, data_t *key_data,
3469 int alg_arg, data_t *input_data,
3470 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003471{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003472 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003473 psa_key_type_t key_type = key_type_arg;
3474 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003475 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003476 unsigned char *signature = NULL;
3477 size_t signature_size;
3478 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003479 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003480
Gilles Peskine8817f612018-12-18 00:18:46 +01003481 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003482
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003483 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3484 psa_set_key_algorithm( &attributes, alg );
3485 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003486
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003487 PSA_ASSERT( psa_import_key( &attributes, &handle,
3488 key_data->x, key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003489 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3490 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003491
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003492 /* Allocate a buffer which has the size advertized by the
3493 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003494 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3495 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003496 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003497 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003498 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003499
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003500 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003501 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3502 input_data->x, input_data->len,
3503 signature, signature_size,
3504 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003505 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003506 ASSERT_COMPARE( output_data->x, output_data->len,
3507 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003508
3509exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003510 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003511 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003512 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003513 mbedtls_psa_crypto_free( );
3514}
3515/* END_CASE */
3516
3517/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003518void sign_fail( int key_type_arg, data_t *key_data,
3519 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003520 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003521{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003522 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003523 psa_key_type_t key_type = key_type_arg;
3524 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003525 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003526 psa_status_t actual_status;
3527 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003528 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003529 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003530 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003531
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003532 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003533
Gilles Peskine8817f612018-12-18 00:18:46 +01003534 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003535
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003536 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3537 psa_set_key_algorithm( &attributes, alg );
3538 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003539
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003540 PSA_ASSERT( psa_import_key( &attributes, &handle,
3541 key_data->x, key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003542
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003543 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003544 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003545 signature, signature_size,
3546 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003547 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003548 /* The value of *signature_length is unspecified on error, but
3549 * whatever it is, it should be less than signature_size, so that
3550 * if the caller tries to read *signature_length bytes without
3551 * checking the error code then they don't overflow a buffer. */
3552 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003553
3554exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003555 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003556 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003557 mbedtls_free( signature );
3558 mbedtls_psa_crypto_free( );
3559}
3560/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003561
3562/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003563void sign_verify( int key_type_arg, data_t *key_data,
3564 int alg_arg, data_t *input_data )
3565{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003566 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003567 psa_key_type_t key_type = key_type_arg;
3568 psa_algorithm_t alg = alg_arg;
3569 size_t key_bits;
3570 unsigned char *signature = NULL;
3571 size_t signature_size;
3572 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003573 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003574
Gilles Peskine8817f612018-12-18 00:18:46 +01003575 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003576
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003577 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3578 psa_set_key_algorithm( &attributes, alg );
3579 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003580
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003581 PSA_ASSERT( psa_import_key( &attributes, &handle,
3582 key_data->x, key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003583 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3584 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003585
3586 /* Allocate a buffer which has the size advertized by the
3587 * library. */
3588 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3589 key_bits, alg );
3590 TEST_ASSERT( signature_size != 0 );
3591 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003592 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003593
3594 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003595 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3596 input_data->x, input_data->len,
3597 signature, signature_size,
3598 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003599 /* Check that the signature length looks sensible. */
3600 TEST_ASSERT( signature_length <= signature_size );
3601 TEST_ASSERT( signature_length > 0 );
3602
3603 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003604 PSA_ASSERT( psa_asymmetric_verify(
3605 handle, alg,
3606 input_data->x, input_data->len,
3607 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003608
3609 if( input_data->len != 0 )
3610 {
3611 /* Flip a bit in the input and verify that the signature is now
3612 * detected as invalid. Flip a bit at the beginning, not at the end,
3613 * because ECDSA may ignore the last few bits of the input. */
3614 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003615 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3616 input_data->x, input_data->len,
3617 signature, signature_length ),
3618 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003619 }
3620
3621exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003622 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003623 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003624 mbedtls_free( signature );
3625 mbedtls_psa_crypto_free( );
3626}
3627/* END_CASE */
3628
3629/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003630void asymmetric_verify( int key_type_arg, data_t *key_data,
3631 int alg_arg, data_t *hash_data,
3632 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003633{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003634 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003635 psa_key_type_t key_type = key_type_arg;
3636 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003637 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003638
Gilles Peskine69c12672018-06-28 00:07:19 +02003639 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3640
Gilles Peskine8817f612018-12-18 00:18:46 +01003641 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003642
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003643 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3644 psa_set_key_algorithm( &attributes, alg );
3645 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003646
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003647 PSA_ASSERT( psa_import_key( &attributes, &handle,
3648 key_data->x, key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003649
Gilles Peskine8817f612018-12-18 00:18:46 +01003650 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3651 hash_data->x, hash_data->len,
3652 signature_data->x,
3653 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003654exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003655 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003656 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003657 mbedtls_psa_crypto_free( );
3658}
3659/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003660
3661/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003662void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3663 int alg_arg, data_t *hash_data,
3664 data_t *signature_data,
3665 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003666{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003667 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003668 psa_key_type_t key_type = key_type_arg;
3669 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003670 psa_status_t actual_status;
3671 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003672 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003673
Gilles Peskine8817f612018-12-18 00:18:46 +01003674 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003675
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003676 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3677 psa_set_key_algorithm( &attributes, alg );
3678 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003679
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003680 PSA_ASSERT( psa_import_key( &attributes, &handle,
3681 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003682
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003683 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003684 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003685 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003686 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003687
Gilles Peskinefe11b722018-12-18 00:24:04 +01003688 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003689
3690exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003691 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003692 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003693 mbedtls_psa_crypto_free( );
3694}
3695/* END_CASE */
3696
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003697/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003698void asymmetric_encrypt( int key_type_arg,
3699 data_t *key_data,
3700 int alg_arg,
3701 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003702 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003703 int expected_output_length_arg,
3704 int expected_status_arg )
3705{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003706 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003707 psa_key_type_t key_type = key_type_arg;
3708 psa_algorithm_t alg = alg_arg;
3709 size_t expected_output_length = expected_output_length_arg;
3710 size_t key_bits;
3711 unsigned char *output = NULL;
3712 size_t output_size;
3713 size_t output_length = ~0;
3714 psa_status_t actual_status;
3715 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003716 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003717
Gilles Peskine8817f612018-12-18 00:18:46 +01003718 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003719
Gilles Peskine656896e2018-06-29 19:12:28 +02003720 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003721 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3722 psa_set_key_algorithm( &attributes, alg );
3723 psa_set_key_type( &attributes, key_type );
3724 PSA_ASSERT( psa_import_key( &attributes, &handle,
3725 key_data->x, key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003726
3727 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003728 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3729 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003730 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003731 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003732
3733 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003734 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003735 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003736 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003737 output, output_size,
3738 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003739 TEST_EQUAL( actual_status, expected_status );
3740 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003741
Gilles Peskine68428122018-06-30 18:42:41 +02003742 /* If the label is empty, the test framework puts a non-null pointer
3743 * in label->x. Test that a null pointer works as well. */
3744 if( label->len == 0 )
3745 {
3746 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003747 if( output_size != 0 )
3748 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003749 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003750 input_data->x, input_data->len,
3751 NULL, label->len,
3752 output, output_size,
3753 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003754 TEST_EQUAL( actual_status, expected_status );
3755 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003756 }
3757
Gilles Peskine656896e2018-06-29 19:12:28 +02003758exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003759 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003760 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003761 mbedtls_free( output );
3762 mbedtls_psa_crypto_free( );
3763}
3764/* END_CASE */
3765
3766/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003767void asymmetric_encrypt_decrypt( int key_type_arg,
3768 data_t *key_data,
3769 int alg_arg,
3770 data_t *input_data,
3771 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003772{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003773 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003774 psa_key_type_t key_type = key_type_arg;
3775 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003776 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003777 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003778 size_t output_size;
3779 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003780 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003781 size_t output2_size;
3782 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003783 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003784
Gilles Peskine8817f612018-12-18 00:18:46 +01003785 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003786
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003787 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3788 psa_set_key_algorithm( &attributes, alg );
3789 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003790
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003791 PSA_ASSERT( psa_import_key( &attributes, &handle,
3792 key_data->x, key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003793
3794 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003795 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3796 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003797 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003798 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003799 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003800 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003801
Gilles Peskineeebd7382018-06-08 18:11:54 +02003802 /* We test encryption by checking that encrypt-then-decrypt gives back
3803 * the original plaintext because of the non-optional random
3804 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003805 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3806 input_data->x, input_data->len,
3807 label->x, label->len,
3808 output, output_size,
3809 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003810 /* We don't know what ciphertext length to expect, but check that
3811 * it looks sensible. */
3812 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003813
Gilles Peskine8817f612018-12-18 00:18:46 +01003814 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3815 output, output_length,
3816 label->x, label->len,
3817 output2, output2_size,
3818 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003819 ASSERT_COMPARE( input_data->x, input_data->len,
3820 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003821
3822exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003823 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003824 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003825 mbedtls_free( output );
3826 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003827 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003828}
3829/* END_CASE */
3830
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003831/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003832void asymmetric_decrypt( int key_type_arg,
3833 data_t *key_data,
3834 int alg_arg,
3835 data_t *input_data,
3836 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003837 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003838{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003839 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003840 psa_key_type_t key_type = key_type_arg;
3841 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003842 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003843 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003844 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003845 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003846
Jaeden Amero412654a2019-02-06 12:57:46 +00003847 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003848 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003849
Gilles Peskine8817f612018-12-18 00:18:46 +01003850 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003851
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003852 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3853 psa_set_key_algorithm( &attributes, alg );
3854 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003855
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003856 PSA_ASSERT( psa_import_key( &attributes, &handle,
3857 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003858
Gilles Peskine8817f612018-12-18 00:18:46 +01003859 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3860 input_data->x, input_data->len,
3861 label->x, label->len,
3862 output,
3863 output_size,
3864 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003865 ASSERT_COMPARE( expected_data->x, expected_data->len,
3866 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003867
Gilles Peskine68428122018-06-30 18:42:41 +02003868 /* If the label is empty, the test framework puts a non-null pointer
3869 * in label->x. Test that a null pointer works as well. */
3870 if( label->len == 0 )
3871 {
3872 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003873 if( output_size != 0 )
3874 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003875 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3876 input_data->x, input_data->len,
3877 NULL, label->len,
3878 output,
3879 output_size,
3880 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003881 ASSERT_COMPARE( expected_data->x, expected_data->len,
3882 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003883 }
3884
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003885exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003886 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003887 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003888 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003889 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003890}
3891/* END_CASE */
3892
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003893/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003894void asymmetric_decrypt_fail( int key_type_arg,
3895 data_t *key_data,
3896 int alg_arg,
3897 data_t *input_data,
3898 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003899 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003900 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003901{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003902 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003903 psa_key_type_t key_type = key_type_arg;
3904 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003905 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003906 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003907 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003908 psa_status_t actual_status;
3909 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003910 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003911
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003912 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003913
Gilles Peskine8817f612018-12-18 00:18:46 +01003914 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003915
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003916 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3917 psa_set_key_algorithm( &attributes, alg );
3918 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003919
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003920 PSA_ASSERT( psa_import_key( &attributes, &handle,
3921 key_data->x, key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003922
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003923 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003924 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003925 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003926 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003927 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003928 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003929 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003930
Gilles Peskine68428122018-06-30 18:42:41 +02003931 /* If the label is empty, the test framework puts a non-null pointer
3932 * in label->x. Test that a null pointer works as well. */
3933 if( label->len == 0 )
3934 {
3935 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003936 if( output_size != 0 )
3937 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003938 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003939 input_data->x, input_data->len,
3940 NULL, label->len,
3941 output, output_size,
3942 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003943 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003944 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003945 }
3946
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003947exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003948 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003949 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003950 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003951 mbedtls_psa_crypto_free( );
3952}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003953/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003954
3955/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00003956void crypto_generator_init( )
3957{
3958 /* Test each valid way of initializing the object, except for `= {0}`, as
3959 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
3960 * though it's OK by the C standard. We could test for this, but we'd need
3961 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003962 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00003963 psa_crypto_generator_t func = psa_crypto_generator_init( );
3964 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
3965 psa_crypto_generator_t zero;
3966
3967 memset( &zero, 0, sizeof( zero ) );
3968
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003969 /* A default generator should not be able to report its capacity. */
3970 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
3971 PSA_ERROR_BAD_STATE );
3972 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
3973 PSA_ERROR_BAD_STATE );
3974 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
3975 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003976
3977 /* A default generator should be abortable without error. */
3978 PSA_ASSERT( psa_generator_abort(&func) );
3979 PSA_ASSERT( psa_generator_abort(&init) );
3980 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00003981}
3982/* END_CASE */
3983
3984/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02003985void derive_setup( int key_type_arg,
3986 data_t *key_data,
3987 int alg_arg,
3988 data_t *salt,
3989 data_t *label,
3990 int requested_capacity_arg,
3991 int expected_status_arg )
3992{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003993 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003994 size_t key_type = key_type_arg;
3995 psa_algorithm_t alg = alg_arg;
3996 size_t requested_capacity = requested_capacity_arg;
3997 psa_status_t expected_status = expected_status_arg;
3998 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003999 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004000
Gilles Peskine8817f612018-12-18 00:18:46 +01004001 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004002
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004003 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4004 psa_set_key_algorithm( &attributes, alg );
4005 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004006
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004007 PSA_ASSERT( psa_import_key( &attributes, &handle,
4008 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004009
Gilles Peskinefe11b722018-12-18 00:24:04 +01004010 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4011 salt->x, salt->len,
4012 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004013 requested_capacity ),
4014 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004015
4016exit:
4017 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004018 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004019 mbedtls_psa_crypto_free( );
4020}
4021/* END_CASE */
4022
4023/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004024void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004025{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004026 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004027 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004028 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004029 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004030 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004031 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004032 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4033 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4034 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004035 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004036
Gilles Peskine8817f612018-12-18 00:18:46 +01004037 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004038
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004039 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4040 psa_set_key_algorithm( &attributes, alg );
4041 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004042
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004043 PSA_ASSERT( psa_import_key( &attributes, &handle,
4044 key_data, sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004045
4046 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004047 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4048 NULL, 0,
4049 NULL, 0,
4050 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004051
4052 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004053 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4054 NULL, 0,
4055 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004056 capacity ),
4057 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004058
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004059 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004060
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004061 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004062 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004063
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004064exit:
4065 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004066 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004067 mbedtls_psa_crypto_free( );
4068}
4069/* END_CASE */
4070
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004071/* BEGIN_CASE */
4072void test_derive_invalid_generator_tests( )
4073{
4074 uint8_t output_buffer[16];
4075 size_t buffer_size = 16;
4076 size_t capacity = 0;
4077 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4078
Nir Sonnenschein50789302018-10-31 12:16:38 +02004079 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004080 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004081
4082 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004083 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004084
Gilles Peskine8817f612018-12-18 00:18:46 +01004085 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004086
Nir Sonnenschein50789302018-10-31 12:16:38 +02004087 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004088 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004089
Nir Sonnenschein50789302018-10-31 12:16:38 +02004090 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004091 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004092
4093exit:
4094 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004095}
4096/* END_CASE */
4097
4098/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004099void derive_output( int alg_arg,
4100 data_t *key_data,
4101 data_t *salt,
4102 data_t *label,
4103 int requested_capacity_arg,
4104 data_t *expected_output1,
4105 data_t *expected_output2 )
4106{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004107 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004108 psa_algorithm_t alg = alg_arg;
4109 size_t requested_capacity = requested_capacity_arg;
4110 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4111 uint8_t *expected_outputs[2] =
4112 {expected_output1->x, expected_output2->x};
4113 size_t output_sizes[2] =
4114 {expected_output1->len, expected_output2->len};
4115 size_t output_buffer_size = 0;
4116 uint8_t *output_buffer = NULL;
4117 size_t expected_capacity;
4118 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004119 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004120 psa_status_t status;
4121 unsigned i;
4122
4123 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4124 {
4125 if( output_sizes[i] > output_buffer_size )
4126 output_buffer_size = output_sizes[i];
4127 if( output_sizes[i] == 0 )
4128 expected_outputs[i] = NULL;
4129 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004130 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004131 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004132
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004133 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4134 psa_set_key_algorithm( &attributes, alg );
4135 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004136
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004137 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004138 key_data->x, key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004139
4140 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004141 if( PSA_ALG_IS_HKDF( alg ) )
4142 {
4143 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4144 PSA_ASSERT( psa_set_generator_capacity( &generator,
4145 requested_capacity ) );
4146 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4147 PSA_KDF_STEP_SALT,
4148 salt->x, salt->len ) );
4149 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4150 PSA_KDF_STEP_SECRET,
4151 handle ) );
4152 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4153 PSA_KDF_STEP_INFO,
4154 label->x, label->len ) );
4155 }
4156 else
4157 {
4158 // legacy
4159 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4160 salt->x, salt->len,
4161 label->x, label->len,
4162 requested_capacity ) );
4163 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004164 PSA_ASSERT( psa_get_generator_capacity( &generator,
4165 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004166 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004167 expected_capacity = requested_capacity;
4168
4169 /* Expansion phase. */
4170 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4171 {
4172 /* Read some bytes. */
4173 status = psa_generator_read( &generator,
4174 output_buffer, output_sizes[i] );
4175 if( expected_capacity == 0 && output_sizes[i] == 0 )
4176 {
4177 /* Reading 0 bytes when 0 bytes are available can go either way. */
4178 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004179 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004180 continue;
4181 }
4182 else if( expected_capacity == 0 ||
4183 output_sizes[i] > expected_capacity )
4184 {
4185 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004186 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004187 expected_capacity = 0;
4188 continue;
4189 }
4190 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004191 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004192 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004193 ASSERT_COMPARE( output_buffer, output_sizes[i],
4194 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004195 /* Check the generator status. */
4196 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004197 PSA_ASSERT( psa_get_generator_capacity( &generator,
4198 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004199 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004200 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004201 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004202
4203exit:
4204 mbedtls_free( output_buffer );
4205 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004206 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004207 mbedtls_psa_crypto_free( );
4208}
4209/* END_CASE */
4210
4211/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004212void derive_full( int alg_arg,
4213 data_t *key_data,
4214 data_t *salt,
4215 data_t *label,
4216 int requested_capacity_arg )
4217{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004218 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004219 psa_algorithm_t alg = alg_arg;
4220 size_t requested_capacity = requested_capacity_arg;
4221 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4222 unsigned char output_buffer[16];
4223 size_t expected_capacity = requested_capacity;
4224 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004225 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004226
Gilles Peskine8817f612018-12-18 00:18:46 +01004227 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004228
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004229 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4230 psa_set_key_algorithm( &attributes, alg );
4231 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004232
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004233 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004234 key_data->x, key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004235
4236 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004237 if( PSA_ALG_IS_HKDF( alg ) )
4238 {
4239 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4240 PSA_ASSERT( psa_set_generator_capacity( &generator,
4241 requested_capacity ) );
4242 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4243 PSA_KDF_STEP_SALT,
4244 salt->x, salt->len ) );
4245 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4246 PSA_KDF_STEP_SECRET,
4247 handle ) );
4248 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4249 PSA_KDF_STEP_INFO,
4250 label->x, label->len ) );
4251 }
4252 else
4253 {
4254 // legacy
4255 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4256 salt->x, salt->len,
4257 label->x, label->len,
4258 requested_capacity ) );
4259 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004260 PSA_ASSERT( psa_get_generator_capacity( &generator,
4261 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004262 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004263
4264 /* Expansion phase. */
4265 while( current_capacity > 0 )
4266 {
4267 size_t read_size = sizeof( output_buffer );
4268 if( read_size > current_capacity )
4269 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004270 PSA_ASSERT( psa_generator_read( &generator,
4271 output_buffer,
4272 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004273 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004274 PSA_ASSERT( psa_get_generator_capacity( &generator,
4275 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004276 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004277 }
4278
4279 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004280 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004281 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004282
Gilles Peskine8817f612018-12-18 00:18:46 +01004283 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004284
4285exit:
4286 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004287 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004288 mbedtls_psa_crypto_free( );
4289}
4290/* END_CASE */
4291
4292/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004293void derive_key_exercise( int alg_arg,
4294 data_t *key_data,
4295 data_t *salt,
4296 data_t *label,
4297 int derived_type_arg,
4298 int derived_bits_arg,
4299 int derived_usage_arg,
4300 int derived_alg_arg )
4301{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004302 psa_key_handle_t base_handle = 0;
4303 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004304 psa_algorithm_t alg = alg_arg;
4305 psa_key_type_t derived_type = derived_type_arg;
4306 size_t derived_bits = derived_bits_arg;
4307 psa_key_usage_t derived_usage = derived_usage_arg;
4308 psa_algorithm_t derived_alg = derived_alg_arg;
4309 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4310 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004311 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004312 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004313
Gilles Peskine8817f612018-12-18 00:18:46 +01004314 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004315
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004316 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4317 psa_set_key_algorithm( &attributes, alg );
4318 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
4319 PSA_ASSERT( psa_import_key( &attributes, &base_handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004320 key_data->x, key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004321
4322 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004323 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4324 salt->x, salt->len,
4325 label->x, label->len,
4326 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004327 psa_set_key_usage_flags( &attributes, derived_usage );
4328 psa_set_key_algorithm( &attributes, derived_alg );
4329 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004330 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004331 PSA_ASSERT( psa_generator_import_key( &attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004332 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004333
4334 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004335 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4336 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4337 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004338
4339 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004340 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004341 goto exit;
4342
4343exit:
4344 psa_generator_abort( &generator );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004345 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004346 psa_destroy_key( base_handle );
4347 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004348 mbedtls_psa_crypto_free( );
4349}
4350/* END_CASE */
4351
4352/* BEGIN_CASE */
4353void derive_key_export( int alg_arg,
4354 data_t *key_data,
4355 data_t *salt,
4356 data_t *label,
4357 int bytes1_arg,
4358 int bytes2_arg )
4359{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004360 psa_key_handle_t base_handle = 0;
4361 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004362 psa_algorithm_t alg = alg_arg;
4363 size_t bytes1 = bytes1_arg;
4364 size_t bytes2 = bytes2_arg;
4365 size_t capacity = bytes1 + bytes2;
4366 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004367 uint8_t *output_buffer = NULL;
4368 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004369 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4370 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004371 size_t length;
4372
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004373 ASSERT_ALLOC( output_buffer, capacity );
4374 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004375 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004376
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004377 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4378 psa_set_key_algorithm( &base_attributes, alg );
4379 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4380 PSA_ASSERT( psa_import_key( &base_attributes, &base_handle,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004381 key_data->x, key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004382
4383 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004384 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4385 salt->x, salt->len,
4386 label->x, label->len,
4387 capacity ) );
4388 PSA_ASSERT( psa_generator_read( &generator,
4389 output_buffer,
4390 capacity ) );
4391 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004392
4393 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004394 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4395 salt->x, salt->len,
4396 label->x, label->len,
4397 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004398 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4399 psa_set_key_algorithm( &derived_attributes, 0 );
4400 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004401 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004402 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004403 &generator ) );
4404 PSA_ASSERT( psa_export_key( derived_handle,
4405 export_buffer, bytes1,
4406 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004407 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004408 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004409 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004410 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004411 &generator ) );
4412 PSA_ASSERT( psa_export_key( derived_handle,
4413 export_buffer + bytes1, bytes2,
4414 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004415 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004416
4417 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004418 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4419 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004420
4421exit:
4422 mbedtls_free( output_buffer );
4423 mbedtls_free( export_buffer );
4424 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004425 psa_destroy_key( base_handle );
4426 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004427 mbedtls_psa_crypto_free( );
4428}
4429/* END_CASE */
4430
4431/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004432void key_agreement_setup( int alg_arg,
4433 int our_key_type_arg, data_t *our_key_data,
4434 data_t *peer_key_data,
4435 int expected_status_arg )
4436{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004437 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004438 psa_algorithm_t alg = alg_arg;
4439 psa_key_type_t our_key_type = our_key_type_arg;
4440 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004441 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004442 psa_status_t expected_status = expected_status_arg;
4443 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004444
Gilles Peskine8817f612018-12-18 00:18:46 +01004445 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004446
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004447 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4448 psa_set_key_algorithm( &attributes, alg );
4449 psa_set_key_type( &attributes, our_key_type );
4450 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004451 our_key_data->x, our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004452
Gilles Peskine77f40d82019-04-11 21:27:06 +02004453 /* The tests currently include inputs that should fail at either step.
4454 * Test cases that fail at the setup step should be changed to call
4455 * key_derivation_setup instead, and this function should be renamed
4456 * to key_agreement_fail. */
4457 status = psa_key_derivation_setup( &generator, alg );
4458 if( status == PSA_SUCCESS )
4459 {
4460 TEST_EQUAL( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
4461 our_key,
4462 peer_key_data->x, peer_key_data->len ),
4463 expected_status );
4464 }
4465 else
4466 {
4467 TEST_ASSERT( status == expected_status );
4468 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004469
4470exit:
4471 psa_generator_abort( &generator );
4472 psa_destroy_key( our_key );
4473 mbedtls_psa_crypto_free( );
4474}
4475/* END_CASE */
4476
4477/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004478void raw_key_agreement( int alg_arg,
4479 int our_key_type_arg, data_t *our_key_data,
4480 data_t *peer_key_data,
4481 data_t *expected_output )
4482{
4483 psa_key_handle_t our_key = 0;
4484 psa_algorithm_t alg = alg_arg;
4485 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004486 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004487 unsigned char *output = NULL;
4488 size_t output_length = ~0;
4489
4490 ASSERT_ALLOC( output, expected_output->len );
4491 PSA_ASSERT( psa_crypto_init( ) );
4492
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004493 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4494 psa_set_key_algorithm( &attributes, alg );
4495 psa_set_key_type( &attributes, our_key_type );
4496 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004497 our_key_data->x, our_key_data->len ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004498
4499 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4500 alg, our_key,
4501 peer_key_data->x, peer_key_data->len,
4502 output, expected_output->len, &output_length ) );
4503 ASSERT_COMPARE( output, output_length,
4504 expected_output->x, expected_output->len );
4505
4506exit:
4507 mbedtls_free( output );
4508 psa_destroy_key( our_key );
4509 mbedtls_psa_crypto_free( );
4510}
4511/* END_CASE */
4512
4513/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004514void key_agreement_capacity( int alg_arg,
4515 int our_key_type_arg, data_t *our_key_data,
4516 data_t *peer_key_data,
4517 int expected_capacity_arg )
4518{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004519 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004520 psa_algorithm_t alg = alg_arg;
4521 psa_key_type_t our_key_type = our_key_type_arg;
4522 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004523 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004524 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004525 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004526
Gilles Peskine8817f612018-12-18 00:18:46 +01004527 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004528
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004529 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4530 psa_set_key_algorithm( &attributes, alg );
4531 psa_set_key_type( &attributes, our_key_type );
4532 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004533 our_key_data->x, our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004534
Gilles Peskine969c5d62019-01-16 15:53:06 +01004535 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4536 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004537 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004538 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004539 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4540 {
4541 /* The test data is for info="" */
4542 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4543 PSA_KDF_STEP_INFO,
4544 NULL, 0 ) );
4545 }
Gilles Peskine59685592018-09-18 12:11:34 +02004546
Gilles Peskinebf491972018-10-25 22:36:12 +02004547 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004548 PSA_ASSERT( psa_get_generator_capacity(
4549 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004550 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004551
Gilles Peskinebf491972018-10-25 22:36:12 +02004552 /* Test the actual capacity by reading the output. */
4553 while( actual_capacity > sizeof( output ) )
4554 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004555 PSA_ASSERT( psa_generator_read( &generator,
4556 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004557 actual_capacity -= sizeof( output );
4558 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004559 PSA_ASSERT( psa_generator_read( &generator,
4560 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004561 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004562 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004563
Gilles Peskine59685592018-09-18 12:11:34 +02004564exit:
4565 psa_generator_abort( &generator );
4566 psa_destroy_key( our_key );
4567 mbedtls_psa_crypto_free( );
4568}
4569/* END_CASE */
4570
4571/* BEGIN_CASE */
4572void key_agreement_output( int alg_arg,
4573 int our_key_type_arg, data_t *our_key_data,
4574 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004575 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004576{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004577 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004578 psa_algorithm_t alg = alg_arg;
4579 psa_key_type_t our_key_type = our_key_type_arg;
4580 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004581 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004582 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004583
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004584 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4585 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004586
Gilles Peskine8817f612018-12-18 00:18:46 +01004587 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004588
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004589 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4590 psa_set_key_algorithm( &attributes, alg );
4591 psa_set_key_type( &attributes, our_key_type );
4592 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004593 our_key_data->x, our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004594
Gilles Peskine969c5d62019-01-16 15:53:06 +01004595 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4596 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004597 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004598 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004599 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4600 {
4601 /* The test data is for info="" */
4602 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4603 PSA_KDF_STEP_INFO,
4604 NULL, 0 ) );
4605 }
Gilles Peskine59685592018-09-18 12:11:34 +02004606
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004607 PSA_ASSERT( psa_generator_read( &generator,
4608 actual_output,
4609 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004610 ASSERT_COMPARE( actual_output, expected_output1->len,
4611 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004612 if( expected_output2->len != 0 )
4613 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004614 PSA_ASSERT( psa_generator_read( &generator,
4615 actual_output,
4616 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004617 ASSERT_COMPARE( actual_output, expected_output2->len,
4618 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004619 }
Gilles Peskine59685592018-09-18 12:11:34 +02004620
4621exit:
4622 psa_generator_abort( &generator );
4623 psa_destroy_key( our_key );
4624 mbedtls_psa_crypto_free( );
4625 mbedtls_free( actual_output );
4626}
4627/* END_CASE */
4628
4629/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004630void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004631{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004632 size_t bytes = bytes_arg;
4633 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004634 unsigned char *output = NULL;
4635 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004636 size_t i;
4637 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004638
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004639 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4640 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004641 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004642
Gilles Peskine8817f612018-12-18 00:18:46 +01004643 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004644
Gilles Peskinea50d7392018-06-21 10:22:13 +02004645 /* Run several times, to ensure that every output byte will be
4646 * nonzero at least once with overwhelming probability
4647 * (2^(-8*number_of_runs)). */
4648 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004649 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004650 if( bytes != 0 )
4651 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004652 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004653
4654 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004655 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4656 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004657
4658 for( i = 0; i < bytes; i++ )
4659 {
4660 if( output[i] != 0 )
4661 ++changed[i];
4662 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004663 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004664
4665 /* Check that every byte was changed to nonzero at least once. This
4666 * validates that psa_generate_random is overwriting every byte of
4667 * the output buffer. */
4668 for( i = 0; i < bytes; i++ )
4669 {
4670 TEST_ASSERT( changed[i] != 0 );
4671 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004672
4673exit:
4674 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004675 mbedtls_free( output );
4676 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004677}
4678/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004679
4680/* BEGIN_CASE */
4681void generate_key( int type_arg,
4682 int bits_arg,
4683 int usage_arg,
4684 int alg_arg,
4685 int expected_status_arg )
4686{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004687 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004688 psa_key_type_t type = type_arg;
4689 psa_key_usage_t usage = usage_arg;
4690 size_t bits = bits_arg;
4691 psa_algorithm_t alg = alg_arg;
4692 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004693 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004694 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004695
Gilles Peskine8817f612018-12-18 00:18:46 +01004696 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004697
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004698 psa_set_key_usage_flags( &attributes, usage );
4699 psa_set_key_algorithm( &attributes, alg );
4700 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004701 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004702
4703 /* Generate a key */
Gilles Peskinee56e8782019-04-26 17:34:02 +02004704 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
4705 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004706 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004707
4708 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004709 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4710 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4711 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004712
Gilles Peskine818ca122018-06-20 18:16:48 +02004713 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004714 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004715 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004716
4717exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004718 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004719 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004720 mbedtls_psa_crypto_free( );
4721}
4722/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004723
Gilles Peskinee56e8782019-04-26 17:34:02 +02004724/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4725void generate_key_rsa( int bits_arg,
4726 data_t *e_arg,
4727 int expected_status_arg )
4728{
4729 psa_key_handle_t handle = 0;
4730 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEYPAIR;
4731 size_t bits = bits_arg;
4732 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4733 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4734 psa_status_t expected_status = expected_status_arg;
4735 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4736 uint8_t *exported = NULL;
4737 size_t exported_size =
4738 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4739 size_t exported_length = SIZE_MAX;
4740 uint8_t *e_read_buffer = NULL;
4741 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004742 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004743 size_t e_read_length = SIZE_MAX;
4744
4745 if( e_arg->len == 0 ||
4746 ( e_arg->len == 3 &&
4747 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4748 {
4749 is_default_public_exponent = 1;
4750 e_read_size = 0;
4751 }
4752 ASSERT_ALLOC( e_read_buffer, e_read_size );
4753 ASSERT_ALLOC( exported, exported_size );
4754
4755 PSA_ASSERT( psa_crypto_init( ) );
4756
4757 psa_set_key_usage_flags( &attributes, usage );
4758 psa_set_key_algorithm( &attributes, alg );
4759 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4760 e_arg->x, e_arg->len ) );
4761 psa_set_key_bits( &attributes, bits );
4762
4763 /* Generate a key */
4764 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
4765 if( expected_status != PSA_SUCCESS )
4766 goto exit;
4767
4768 /* Test the key information */
4769 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4770 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4771 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4772 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4773 e_read_buffer, e_read_size,
4774 &e_read_length ) );
4775 if( is_default_public_exponent )
4776 TEST_EQUAL( e_read_length, 0 );
4777 else
4778 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4779
4780 /* Do something with the key according to its type and permitted usage. */
4781 if( ! exercise_key( handle, usage, alg ) )
4782 goto exit;
4783
4784 /* Export the key and check the public exponent. */
4785 PSA_ASSERT( psa_export_public_key( handle,
4786 exported, exported_size,
4787 &exported_length ) );
4788 {
4789 uint8_t *p = exported;
4790 uint8_t *end = exported + exported_length;
4791 size_t len;
4792 /* RSAPublicKey ::= SEQUENCE {
4793 * modulus INTEGER, -- n
4794 * publicExponent INTEGER } -- e
4795 */
4796 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4797 MBEDTLS_ASN1_SEQUENCE |
4798 MBEDTLS_ASN1_CONSTRUCTED ) );
4799 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4800 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4801 MBEDTLS_ASN1_INTEGER ) );
4802 if( len >= 1 && p[0] == 0 )
4803 {
4804 ++p;
4805 --len;
4806 }
4807 if( e_arg->len == 0 )
4808 {
4809 TEST_EQUAL( len, 3 );
4810 TEST_EQUAL( p[0], 1 );
4811 TEST_EQUAL( p[1], 0 );
4812 TEST_EQUAL( p[2], 1 );
4813 }
4814 else
4815 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4816 }
4817
4818exit:
4819 psa_reset_key_attributes( &attributes );
4820 psa_destroy_key( handle );
4821 mbedtls_psa_crypto_free( );
4822 mbedtls_free( e_read_buffer );
4823 mbedtls_free( exported );
4824}
4825/* END_CASE */
4826
Darryl Greend49a4992018-06-18 17:27:26 +01004827/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004828void persistent_key_load_key_from_storage( data_t *data,
4829 int type_arg, int bits_arg,
4830 int usage_flags_arg, int alg_arg,
4831 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004832{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004833 psa_key_id_t key_id = 1;
4834 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004835 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004836 psa_key_handle_t base_key = 0;
4837 psa_key_type_t type = type_arg;
4838 size_t bits = bits_arg;
4839 psa_key_usage_t usage_flags = usage_flags_arg;
4840 psa_algorithm_t alg = alg_arg;
Darryl Green0c6575a2018-11-07 16:05:30 +00004841 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004842 unsigned char *first_export = NULL;
4843 unsigned char *second_export = NULL;
4844 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4845 size_t first_exported_length;
4846 size_t second_exported_length;
4847
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004848 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4849 {
4850 ASSERT_ALLOC( first_export, export_size );
4851 ASSERT_ALLOC( second_export, export_size );
4852 }
Darryl Greend49a4992018-06-18 17:27:26 +01004853
Gilles Peskine8817f612018-12-18 00:18:46 +01004854 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004855
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004856 psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT );
4857 psa_set_key_usage_flags( &attributes, usage_flags );
4858 psa_set_key_algorithm( &attributes, alg );
4859 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004860 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004861
Darryl Green0c6575a2018-11-07 16:05:30 +00004862 switch( generation_method )
4863 {
4864 case IMPORT_KEY:
4865 /* Import the key */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004866 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004867 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004868 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004869
Darryl Green0c6575a2018-11-07 16:05:30 +00004870 case GENERATE_KEY:
4871 /* Generate a key */
Gilles Peskinee56e8782019-04-26 17:34:02 +02004872 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004873 break;
4874
4875 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004876 {
4877 /* Create base key */
4878 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4879 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4880 psa_set_key_usage_flags( &base_attributes,
4881 PSA_KEY_USAGE_DERIVE );
4882 psa_set_key_algorithm( &base_attributes, derive_alg );
4883 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4884 PSA_ASSERT( psa_import_key( &base_attributes, &base_key,
4885 data->x, data->len ) );
4886 /* Derive a key. */
4887 PSA_ASSERT( psa_key_derivation_setup( &generator, derive_alg ) );
4888 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4889 PSA_KDF_STEP_SECRET,
4890 base_key ) );
4891 PSA_ASSERT( psa_key_derivation_input_bytes(
4892 &generator, PSA_KDF_STEP_INFO,
4893 NULL, 0 ) );
4894 PSA_ASSERT( psa_generator_import_key( &attributes, &handle,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004895 &generator ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004896 PSA_ASSERT( psa_generator_abort( &generator ) );
4897 PSA_ASSERT( psa_destroy_key( base_key ) );
4898 base_key = 0;
4899 }
Darryl Green0c6575a2018-11-07 16:05:30 +00004900 break;
4901 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004902 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004903
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004904 /* Export the key if permitted by the key policy. */
4905 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4906 {
4907 PSA_ASSERT( psa_export_key( handle,
4908 first_export, export_size,
4909 &first_exported_length ) );
4910 if( generation_method == IMPORT_KEY )
4911 ASSERT_COMPARE( data->x, data->len,
4912 first_export, first_exported_length );
4913 }
Darryl Greend49a4992018-06-18 17:27:26 +01004914
4915 /* Shutdown and restart */
4916 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004917 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004918
Darryl Greend49a4992018-06-18 17:27:26 +01004919 /* Check key slot still contains key data */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004920 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
Gilles Peskine8817f612018-12-18 00:18:46 +01004921 &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004922 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4923 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4924 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4925 PSA_KEY_LIFETIME_PERSISTENT );
4926 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4927 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4928 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4929 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004930
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004931 /* Export the key again if permitted by the key policy. */
4932 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004933 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004934 PSA_ASSERT( psa_export_key( handle,
4935 second_export, export_size,
4936 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004937 ASSERT_COMPARE( first_export, first_exported_length,
4938 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004939 }
4940
4941 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004942 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004943 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004944
4945exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004946 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004947 mbedtls_free( first_export );
4948 mbedtls_free( second_export );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004949 psa_generator_abort( &generator );
4950 psa_destroy_key( base_key );
4951 if( handle == 0 )
4952 {
4953 /* In case there was a test failure after creating the persistent key
4954 * but while it was not open, try to re-open the persistent key
4955 * to delete it. */
4956 psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle );
4957 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004958 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004959 mbedtls_psa_crypto_free();
4960}
4961/* END_CASE */