blob: c6a0f592f28f872f5539526e583c25b13efd58e7 [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;
214 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
215
216 PSA_ASSERT( psa_allocate_key( &handle ) );
217 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
218 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +0200219 PSA_ASSERT( psa_import_key_to_handle( handle, key_type, 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;
248 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
249
250 PSA_ASSERT( psa_allocate_key( &handle ) );
251 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
252 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +0200253 PSA_ASSERT( psa_import_key_to_handle( handle, key_type, 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 );
601 return( status );
602}
603
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200604/* We need two keys to exercise key agreement. Exercise the
605 * private key against its own public key. */
606static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
607 psa_key_handle_t handle )
608{
609 psa_key_type_t private_key_type;
610 psa_key_type_t public_key_type;
611 size_t key_bits;
612 uint8_t *public_key = NULL;
613 size_t public_key_length;
614 uint8_t output[1024];
615 size_t output_length;
616 /* Return GENERIC_ERROR if something other than the final call to
617 * psa_key_agreement fails. This isn't fully satisfactory, but it's
618 * good enough: callers will report it as a failed test anyway. */
619 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200620 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200621
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200622 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
623 private_key_type = psa_get_key_type( &attributes );
624 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200625 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
626 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
627 ASSERT_ALLOC( public_key, public_key_length );
628 PSA_ASSERT( psa_export_public_key( handle,
629 public_key, public_key_length,
630 &public_key_length ) );
631
632 status = psa_key_agreement_raw_shared_secret(
633 alg, handle,
634 public_key, public_key_length,
635 output, sizeof( output ), &output_length );
636exit:
637 mbedtls_free( public_key );
638 return( status );
639}
640
641static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
642 psa_key_usage_t usage,
643 psa_algorithm_t alg )
644{
645 int ok = 0;
646
647 if( usage & PSA_KEY_USAGE_DERIVE )
648 {
649 /* We need two keys to exercise key agreement. Exercise the
650 * private key against its own public key. */
651 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
652 }
653 ok = 1;
654
655exit:
656 return( ok );
657}
658
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100659static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200660 psa_key_usage_t usage,
661 psa_algorithm_t alg )
662{
663 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200664 unsigned char output[1];
665 int ok = 0;
666
667 if( usage & PSA_KEY_USAGE_DERIVE )
668 {
669 /* We need two keys to exercise key agreement. Exercise the
670 * private key against its own public key. */
Gilles Peskine969c5d62019-01-16 15:53:06 +0100671 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
672 PSA_ASSERT( key_agreement_with_self( &generator, handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +0100673 PSA_ASSERT( psa_generator_read( &generator,
674 output,
675 sizeof( output ) ) );
676 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200677 }
678 ok = 1;
679
680exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200681 return( ok );
682}
683
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200684static int is_oid_of_key_type( psa_key_type_t type,
685 const uint8_t *oid, size_t oid_length )
686{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200687 const uint8_t *expected_oid = NULL;
688 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200689#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200690 if( PSA_KEY_TYPE_IS_RSA( type ) )
691 {
692 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
693 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
694 }
695 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200696#endif /* MBEDTLS_RSA_C */
697#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200698 if( PSA_KEY_TYPE_IS_ECC( type ) )
699 {
700 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
701 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
702 }
703 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200704#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200705 {
706 char message[40];
707 mbedtls_snprintf( message, sizeof( message ),
708 "OID not known for key type=0x%08lx",
709 (unsigned long) type );
710 test_fail( message, __LINE__, __FILE__ );
711 return( 0 );
712 }
713
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200714 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200715 return( 1 );
716
717exit:
718 return( 0 );
719}
720
721static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
722 size_t min_bits, size_t max_bits,
723 int must_be_odd )
724{
725 size_t len;
726 size_t actual_bits;
727 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100728 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100729 MBEDTLS_ASN1_INTEGER ),
730 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200731 /* Tolerate a slight departure from DER encoding:
732 * - 0 may be represented by an empty string or a 1-byte string.
733 * - The sign bit may be used as a value bit. */
734 if( ( len == 1 && ( *p )[0] == 0 ) ||
735 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
736 {
737 ++( *p );
738 --len;
739 }
740 if( min_bits == 0 && len == 0 )
741 return( 1 );
742 msb = ( *p )[0];
743 TEST_ASSERT( msb != 0 );
744 actual_bits = 8 * ( len - 1 );
745 while( msb != 0 )
746 {
747 msb >>= 1;
748 ++actual_bits;
749 }
750 TEST_ASSERT( actual_bits >= min_bits );
751 TEST_ASSERT( actual_bits <= max_bits );
752 if( must_be_odd )
753 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
754 *p += len;
755 return( 1 );
756exit:
757 return( 0 );
758}
759
760static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
761 size_t *len,
762 unsigned char n, unsigned char tag )
763{
764 int ret;
765 ret = mbedtls_asn1_get_tag( p, end, len,
766 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
767 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
768 if( ret != 0 )
769 return( ret );
770 end = *p + *len;
771 ret = mbedtls_asn1_get_tag( p, end, len, tag );
772 if( ret != 0 )
773 return( ret );
774 if( *p + *len != end )
775 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
776 return( 0 );
777}
778
779static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
780 uint8_t *exported, size_t exported_length )
781{
782 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100783 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200784 else
785 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200786
787#if defined(MBEDTLS_DES_C)
788 if( type == PSA_KEY_TYPE_DES )
789 {
790 /* Check the parity bits. */
791 unsigned i;
792 for( i = 0; i < bits / 8; i++ )
793 {
794 unsigned bit_count = 0;
795 unsigned m;
796 for( m = 1; m <= 0x100; m <<= 1 )
797 {
798 if( exported[i] & m )
799 ++bit_count;
800 }
801 TEST_ASSERT( bit_count % 2 != 0 );
802 }
803 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200804 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200805#endif
806
807#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
808 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
809 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200810 uint8_t *p = exported;
811 uint8_t *end = exported + exported_length;
812 size_t len;
813 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200814 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200815 * modulus INTEGER, -- n
816 * publicExponent INTEGER, -- e
817 * privateExponent INTEGER, -- d
818 * prime1 INTEGER, -- p
819 * prime2 INTEGER, -- q
820 * exponent1 INTEGER, -- d mod (p-1)
821 * exponent2 INTEGER, -- d mod (q-1)
822 * coefficient INTEGER, -- (inverse of q) mod p
823 * }
824 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100825 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
826 MBEDTLS_ASN1_SEQUENCE |
827 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
828 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200829 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
830 goto exit;
831 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
832 goto exit;
833 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
834 goto exit;
835 /* Require d to be at least half the size of n. */
836 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
837 goto exit;
838 /* Require p and q to be at most half the size of n, rounded up. */
839 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
840 goto exit;
841 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
842 goto exit;
843 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
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;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100849 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100850 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200851 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200852#endif /* MBEDTLS_RSA_C */
853
854#if defined(MBEDTLS_ECP_C)
855 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
856 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100857 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100858 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100859 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200860 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200861#endif /* MBEDTLS_ECP_C */
862
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200863 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
864 {
865 uint8_t *p = exported;
866 uint8_t *end = exported + exported_length;
867 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200868#if defined(MBEDTLS_RSA_C)
869 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
870 {
871 /* RSAPublicKey ::= SEQUENCE {
872 * modulus INTEGER, -- n
873 * publicExponent INTEGER } -- e
874 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100875 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
876 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100877 MBEDTLS_ASN1_CONSTRUCTED ),
878 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100879 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200880 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
881 goto exit;
882 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
883 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100884 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200885 }
886 else
887#endif /* MBEDTLS_RSA_C */
888#if defined(MBEDTLS_ECP_C)
889 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
890 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000891 /* The representation of an ECC public key is:
892 * - The byte 0x04;
893 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
894 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
895 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000896 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100897 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
898 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200899 }
900 else
901#endif /* MBEDTLS_ECP_C */
902 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100903 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200904 mbedtls_snprintf( message, sizeof( message ),
905 "No sanity check for public key type=0x%08lx",
906 (unsigned long) type );
907 test_fail( message, __LINE__, __FILE__ );
908 return( 0 );
909 }
910 }
911 else
912
913 {
914 /* No sanity checks for other types */
915 }
916
917 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200918
919exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200920 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200921}
922
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100923static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200924 psa_key_usage_t usage )
925{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200926 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200927 uint8_t *exported = NULL;
928 size_t exported_size = 0;
929 size_t exported_length = 0;
930 int ok = 0;
931
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200932 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200933
934 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200935 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200936 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100937 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
938 PSA_ERROR_NOT_PERMITTED );
Gilles Peskined14664a2018-08-10 19:07:32 +0200939 return( 1 );
940 }
941
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200942 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
943 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200944 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200945
Gilles Peskine8817f612018-12-18 00:18:46 +0100946 PSA_ASSERT( psa_export_key( handle,
947 exported, exported_size,
948 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200949 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
950 psa_get_key_bits( &attributes ),
951 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200952
953exit:
954 mbedtls_free( exported );
955 return( ok );
956}
957
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100958static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200959{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200960 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200961 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200962 uint8_t *exported = NULL;
963 size_t exported_size = 0;
964 size_t exported_length = 0;
965 int ok = 0;
966
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
968 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200969 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100970 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100971 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200972 return( 1 );
973 }
974
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200975 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
976 psa_get_key_type( &attributes ) );
977 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
978 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200979 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200980
Gilles Peskine8817f612018-12-18 00:18:46 +0100981 PSA_ASSERT( psa_export_public_key( handle,
982 exported, exported_size,
983 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200984 ok = exported_key_sanity_check( public_type,
985 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200986 exported, exported_length );
987
988exit:
989 mbedtls_free( exported );
990 return( ok );
991}
992
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100993/** Do smoke tests on a key.
994 *
995 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
996 * sign/verify, or derivation) that is permitted according to \p usage.
997 * \p usage and \p alg should correspond to the expected policy on the
998 * key.
999 *
1000 * Export the key if permitted by \p usage, and check that the output
1001 * looks sensible. If \p usage forbids export, check that
1002 * \p psa_export_key correctly rejects the attempt. If the key is
1003 * asymmetric, also check \p psa_export_public_key.
1004 *
1005 * If the key fails the tests, this function calls the test framework's
1006 * `test_fail` function and returns false. Otherwise this function returns
1007 * true. Therefore it should be used as follows:
1008 * ```
1009 * if( ! exercise_key( ... ) ) goto exit;
1010 * ```
1011 *
1012 * \param handle The key to exercise. It should be capable of performing
1013 * \p alg.
1014 * \param usage The usage flags to assume.
1015 * \param alg The algorithm to exercise.
1016 *
1017 * \retval 0 The key failed the smoke tests.
1018 * \retval 1 The key passed the smoke tests.
1019 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001020static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001021 psa_key_usage_t usage,
1022 psa_algorithm_t alg )
1023{
1024 int ok;
1025 if( alg == 0 )
1026 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1027 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001029 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001030 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001031 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001032 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001033 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001034 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001035 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001036 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001037 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001038 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001039 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1040 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001041 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001042 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001043 else
1044 {
1045 char message[40];
1046 mbedtls_snprintf( message, sizeof( message ),
1047 "No code to exercise alg=0x%08lx",
1048 (unsigned long) alg );
1049 test_fail( message, __LINE__, __FILE__ );
1050 ok = 0;
1051 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001052
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001053 ok = ok && exercise_export_key( handle, usage );
1054 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001055
Gilles Peskine02b75072018-07-01 22:31:34 +02001056 return( ok );
1057}
1058
Gilles Peskine10df3412018-10-25 22:35:43 +02001059static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1060 psa_algorithm_t alg )
1061{
1062 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1063 {
1064 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1065 PSA_KEY_USAGE_VERIFY :
1066 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1067 }
1068 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1069 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1070 {
1071 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1072 PSA_KEY_USAGE_ENCRYPT :
1073 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1074 }
1075 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1076 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1077 {
1078 return( PSA_KEY_USAGE_DERIVE );
1079 }
1080 else
1081 {
1082 return( 0 );
1083 }
1084
1085}
Darryl Green0c6575a2018-11-07 16:05:30 +00001086
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001087static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1088{
1089 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1090 uint8_t buffer[1];
1091 size_t length;
1092 int ok = 0;
1093
1094 psa_make_key_persistent( &attributes, 0x6964, PSA_KEY_LIFETIME_PERSISTENT );
1095 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1096 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1097 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1098 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1099 PSA_ERROR_INVALID_HANDLE );
1100 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1101 TEST_EQUAL( psa_get_key_attributes_lifetime( &attributes ), 0 );
1102 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1103 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1104 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1105 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1106
1107 TEST_EQUAL( psa_export_key( handle,
1108 buffer, sizeof( buffer ), &length ),
1109 PSA_ERROR_INVALID_HANDLE );
1110 TEST_EQUAL( psa_export_public_key( handle,
1111 buffer, sizeof( buffer ), &length ),
1112 PSA_ERROR_INVALID_HANDLE );
1113
1114 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1115 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1116
1117 ok = 1;
1118
1119exit:
1120 psa_reset_key_attributes( &attributes );
1121 return( ok );
1122}
1123
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001124/* An overapproximation of the amount of storage needed for a key of the
1125 * given type and with the given content. The API doesn't make it easy
1126 * to find a good value for the size. The current implementation doesn't
1127 * care about the value anyway. */
1128#define KEY_BITS_FROM_DATA( type, data ) \
1129 ( data )->len
1130
Darryl Green0c6575a2018-11-07 16:05:30 +00001131typedef enum {
1132 IMPORT_KEY = 0,
1133 GENERATE_KEY = 1,
1134 DERIVE_KEY = 2
1135} generate_method;
1136
Gilles Peskinee59236f2018-01-27 23:32:46 +01001137/* END_HEADER */
1138
1139/* BEGIN_DEPENDENCIES
1140 * depends_on:MBEDTLS_PSA_CRYPTO_C
1141 * END_DEPENDENCIES
1142 */
1143
1144/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001145void static_checks( )
1146{
1147 size_t max_truncated_mac_size =
1148 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1149
1150 /* Check that the length for a truncated MAC always fits in the algorithm
1151 * encoding. The shifted mask is the maximum truncated value. The
1152 * untruncated algorithm may be one byte larger. */
1153 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1154}
1155/* END_CASE */
1156
1157/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001158void attributes_set_get( int id_arg, int lifetime_arg,
1159 int usage_flags_arg, int alg_arg,
1160 int type_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001161{
Gilles Peskine4747d192019-04-17 15:05:45 +02001162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001163 psa_key_id_t id = id_arg;
1164 psa_key_lifetime_t lifetime = lifetime_arg;
1165 psa_key_usage_t usage_flags = usage_flags_arg;
1166 psa_algorithm_t alg = alg_arg;
1167 psa_key_type_t type = type_arg;
1168
1169 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1170 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1171 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1172 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1173 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1174
1175 psa_make_key_persistent( &attributes, id, lifetime );
1176 psa_set_key_usage_flags( &attributes, usage_flags );
1177 psa_set_key_algorithm( &attributes, alg );
1178 psa_set_key_type( &attributes, type );
1179
1180 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1181 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1182 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1183 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1184 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1185
1186 psa_reset_key_attributes( &attributes );
1187
1188 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1189 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1190 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1191 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1192 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1193}
1194/* END_CASE */
1195
1196/* BEGIN_CASE */
1197void import( data_t *data, int type_arg, int expected_status_arg )
1198{
1199 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1200 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001201 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001202 psa_key_type_t type = type_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001203 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001204 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001205
Gilles Peskine8817f612018-12-18 00:18:46 +01001206 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001207
Gilles Peskine4747d192019-04-17 15:05:45 +02001208 psa_set_key_type( &attributes, type );
1209 status = psa_import_key( &attributes, &handle, data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001210 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001211 if( status != PSA_SUCCESS )
1212 goto exit;
1213
1214 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1215 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1216
1217 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001218 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001219
1220exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001221 psa_destroy_key( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001222 mbedtls_psa_crypto_free( );
1223}
1224/* END_CASE */
1225
1226/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001227void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1228{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001229 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001230 size_t bits = bits_arg;
1231 psa_status_t expected_status = expected_status_arg;
1232 psa_status_t status;
1233 psa_key_type_t type =
1234 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1235 size_t buffer_size = /* Slight overapproximations */
1236 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001237 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001238 unsigned char *p;
1239 int ret;
1240 size_t length;
1241
Gilles Peskine8817f612018-12-18 00:18:46 +01001242 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001243 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001244
1245 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1246 bits, keypair ) ) >= 0 );
1247 length = ret;
1248
1249 /* Try importing the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001250 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02001251 status = psa_import_key_to_handle( handle, type, p, length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001252 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001253 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001254 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001255
1256exit:
1257 mbedtls_free( buffer );
1258 mbedtls_psa_crypto_free( );
1259}
1260/* END_CASE */
1261
1262/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001263void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001264 int type_arg,
1265 int alg_arg,
1266 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001267 int expected_bits,
1268 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001269 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001270 int canonical_input )
1271{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001272 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001273 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001274 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001275 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001276 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001277 unsigned char *exported = NULL;
1278 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001279 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001280 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001281 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001282 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001283 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001284
Moran Pekercb088e72018-07-17 17:36:59 +03001285 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001286 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001287 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001288 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001289 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001290
Gilles Peskine4747d192019-04-17 15:05:45 +02001291 psa_set_key_usage_flags( &attributes, usage_arg );
1292 psa_set_key_algorithm( &attributes, alg );
1293 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001294
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001295 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001296 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001297
1298 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001299 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1300 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1301 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001302
1303 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001304 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001305 exported, export_size,
1306 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001307 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001308
1309 /* The exported length must be set by psa_export_key() to a value between 0
1310 * and export_size. On errors, the exported length must be 0. */
1311 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1312 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1313 TEST_ASSERT( exported_length <= export_size );
1314
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001315 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001316 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001318 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001319 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001320 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001321 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001322
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001323 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001324 goto exit;
1325
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001326 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001327 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001328 else
1329 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001330 psa_key_handle_t handle2;
Gilles Peskine4747d192019-04-17 15:05:45 +02001331 PSA_ASSERT( psa_import_key( &attributes, &handle2,
1332 exported, exported_length ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001333 PSA_ASSERT( psa_export_key( handle2,
1334 reexported,
1335 export_size,
1336 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001337 ASSERT_COMPARE( exported, exported_length,
1338 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001339 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001340 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001341 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001342
1343destroy:
1344 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001345 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001346 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001347
1348exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001349 mbedtls_free( exported );
1350 mbedtls_free( reexported );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001351 mbedtls_psa_crypto_free( );
1352}
1353/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001354
Moran Pekerf709f4a2018-06-06 17:26:04 +03001355/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001356void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001357{
Gilles Peskine8817f612018-12-18 00:18:46 +01001358 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001359 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001360
1361exit:
1362 mbedtls_psa_crypto_free( );
1363}
1364/* END_CASE */
1365
1366/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001367void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001368 int type_arg,
1369 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001370 int export_size_delta,
1371 int expected_export_status_arg,
1372 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001373{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001374 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001375 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001376 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001377 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001378 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001379 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001380 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001381 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001382 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001383
Gilles Peskine8817f612018-12-18 00:18:46 +01001384 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001385
Gilles Peskine4747d192019-04-17 15:05:45 +02001386 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1387 psa_set_key_algorithm( &attributes, alg );
1388 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001389
1390 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001391 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001392
Gilles Peskine49c25912018-10-29 15:15:31 +01001393 /* Export the public key */
1394 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001395 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001396 exported, export_size,
1397 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001398 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001399 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001400 {
1401 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1402 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001403 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1404 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001405 TEST_ASSERT( expected_public_key->len <=
1406 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001407 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1408 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001409 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001410
1411exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001412 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001413 psa_destroy_key( handle );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001414 mbedtls_psa_crypto_free( );
1415}
1416/* END_CASE */
1417
Gilles Peskine20035e32018-02-03 22:44:14 +01001418/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001419void import_and_exercise_key( data_t *data,
1420 int type_arg,
1421 int bits_arg,
1422 int alg_arg )
1423{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001424 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001425 psa_key_type_t type = type_arg;
1426 size_t bits = bits_arg;
1427 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001428 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001429 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001430 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001431
Gilles Peskine8817f612018-12-18 00:18:46 +01001432 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001433
Gilles Peskine4747d192019-04-17 15:05:45 +02001434 psa_set_key_usage_flags( &attributes, usage );
1435 psa_set_key_algorithm( &attributes, alg );
1436 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001437
1438 /* Import the key */
Gilles Peskine4747d192019-04-17 15:05:45 +02001439 PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001440
1441 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001442 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1443 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1444 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001445
1446 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001447 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001448 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001449
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001450 PSA_ASSERT( psa_destroy_key( handle ) );
1451 test_operations_on_invalid_handle( handle );
1452
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001453exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001454 psa_destroy_key( handle );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001455 mbedtls_psa_crypto_free( );
1456}
1457/* END_CASE */
1458
1459/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001460void key_policy( int usage_arg, int alg_arg )
1461{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001462 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001463 psa_algorithm_t alg = alg_arg;
1464 psa_key_usage_t usage = usage_arg;
1465 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1466 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001467 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001468
1469 memset( key, 0x2a, sizeof( key ) );
1470
Gilles Peskine8817f612018-12-18 00:18:46 +01001471 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001472
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001473 psa_set_key_usage_flags( &attributes, usage );
1474 psa_set_key_algorithm( &attributes, alg );
1475 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001476
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001477 PSA_ASSERT( psa_import_key( &attributes, &handle, key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001478
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001479 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1480 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1481 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1482 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001483
1484exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001485 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001486 mbedtls_psa_crypto_free( );
1487}
1488/* END_CASE */
1489
1490/* BEGIN_CASE */
Jaeden Amero70261c52019-01-04 11:47:20 +00001491void key_policy_init( )
1492{
1493 /* Test each valid way of initializing the object, except for `= {0}`, as
1494 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1495 * though it's OK by the C standard. We could test for this, but we'd need
1496 * to supress the Clang warning for the test. */
1497 psa_key_policy_t func = psa_key_policy_init( );
1498 psa_key_policy_t init = PSA_KEY_POLICY_INIT;
1499 psa_key_policy_t zero;
1500
1501 memset( &zero, 0, sizeof( zero ) );
1502
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001503 /* A default key policy should not permit any usage. */
1504 TEST_EQUAL( psa_key_policy_get_usage( &func ), 0 );
1505 TEST_EQUAL( psa_key_policy_get_usage( &init ), 0 );
1506 TEST_EQUAL( psa_key_policy_get_usage( &zero ), 0 );
1507
1508 /* A default key policy should not permit any algorithm. */
1509 TEST_EQUAL( psa_key_policy_get_algorithm( &func ), 0 );
1510 TEST_EQUAL( psa_key_policy_get_algorithm( &init ), 0 );
1511 TEST_EQUAL( psa_key_policy_get_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001512}
1513/* END_CASE */
1514
1515/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001516void mac_key_policy( int policy_usage,
1517 int policy_alg,
1518 int key_type,
1519 data_t *key_data,
1520 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001521{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001522 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001523 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001524 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001525 psa_status_t status;
1526 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001527
Gilles Peskine8817f612018-12-18 00:18:46 +01001528 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001529
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001530 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001531 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001532 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001533
Gilles Peskine87a5e562019-04-17 12:28:25 +02001534 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001535 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001536
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001537 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001538 if( policy_alg == exercise_alg &&
1539 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001540 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001541 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001542 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001543 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001544
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001545 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001546 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001547 if( policy_alg == exercise_alg &&
1548 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001549 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001550 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001551 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001552
1553exit:
1554 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001555 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001556 mbedtls_psa_crypto_free( );
1557}
1558/* END_CASE */
1559
1560/* BEGIN_CASE */
1561void cipher_key_policy( int policy_usage,
1562 int policy_alg,
1563 int key_type,
1564 data_t *key_data,
1565 int exercise_alg )
1566{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001567 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001568 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001569 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001570 psa_status_t status;
1571
Gilles Peskine8817f612018-12-18 00:18:46 +01001572 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001573
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001574 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001575 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001576 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001577
Gilles Peskine87a5e562019-04-17 12:28:25 +02001578 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001579 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001580
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001581 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001582 if( policy_alg == exercise_alg &&
1583 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001584 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001585 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001586 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001587 psa_cipher_abort( &operation );
1588
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001589 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001590 if( policy_alg == exercise_alg &&
1591 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001592 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001593 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001594 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001595
1596exit:
1597 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001598 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001599 mbedtls_psa_crypto_free( );
1600}
1601/* END_CASE */
1602
1603/* BEGIN_CASE */
1604void aead_key_policy( int policy_usage,
1605 int policy_alg,
1606 int key_type,
1607 data_t *key_data,
1608 int nonce_length_arg,
1609 int tag_length_arg,
1610 int exercise_alg )
1611{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001612 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001613 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001614 psa_status_t status;
1615 unsigned char nonce[16] = {0};
1616 size_t nonce_length = nonce_length_arg;
1617 unsigned char tag[16];
1618 size_t tag_length = tag_length_arg;
1619 size_t output_length;
1620
1621 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1622 TEST_ASSERT( tag_length <= sizeof( tag ) );
1623
Gilles Peskine8817f612018-12-18 00:18:46 +01001624 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001625
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001626 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001627 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001628 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001629
Gilles Peskine87a5e562019-04-17 12:28:25 +02001630 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001631 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001632
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001633 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001634 nonce, nonce_length,
1635 NULL, 0,
1636 NULL, 0,
1637 tag, tag_length,
1638 &output_length );
1639 if( policy_alg == exercise_alg &&
1640 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001641 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001642 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001643 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001644
1645 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001646 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001647 nonce, nonce_length,
1648 NULL, 0,
1649 tag, tag_length,
1650 NULL, 0,
1651 &output_length );
1652 if( policy_alg == exercise_alg &&
1653 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001654 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001655 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001656 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001657
1658exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001659 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001660 mbedtls_psa_crypto_free( );
1661}
1662/* END_CASE */
1663
1664/* BEGIN_CASE */
1665void asymmetric_encryption_key_policy( int policy_usage,
1666 int policy_alg,
1667 int key_type,
1668 data_t *key_data,
1669 int exercise_alg )
1670{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001671 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001672 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001673 psa_status_t status;
1674 size_t key_bits;
1675 size_t buffer_length;
1676 unsigned char *buffer = NULL;
1677 size_t output_length;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001678 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001679
Gilles Peskine8817f612018-12-18 00:18:46 +01001680 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001681
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001682 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001683 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001684 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001685
Gilles Peskine87a5e562019-04-17 12:28:25 +02001686 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001687 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001688
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001689 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1690 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001691 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1692 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001693 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001694
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001695 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001696 NULL, 0,
1697 NULL, 0,
1698 buffer, buffer_length,
1699 &output_length );
1700 if( policy_alg == exercise_alg &&
1701 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001702 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001703 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001704 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001706 if( buffer_length != 0 )
1707 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001708 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001709 buffer, buffer_length,
1710 NULL, 0,
1711 buffer, buffer_length,
1712 &output_length );
1713 if( policy_alg == exercise_alg &&
1714 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001715 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001716 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001717 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001718
1719exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001720 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001721 mbedtls_psa_crypto_free( );
1722 mbedtls_free( buffer );
1723}
1724/* END_CASE */
1725
1726/* BEGIN_CASE */
1727void asymmetric_signature_key_policy( int policy_usage,
1728 int policy_alg,
1729 int key_type,
1730 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001731 int exercise_alg,
1732 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001733{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001734 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001735 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001736 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001737 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1738 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1739 * compatible with the policy and `payload_length_arg` is supposed to be
1740 * a valid input length to sign. If `payload_length_arg <= 0`,
1741 * `exercise_alg` is supposed to be forbidden by the policy. */
1742 int compatible_alg = payload_length_arg > 0;
1743 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001744 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1745 size_t signature_length;
1746
Gilles Peskine8817f612018-12-18 00:18:46 +01001747 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001749 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001750 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001751 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001752
Gilles Peskine87a5e562019-04-17 12:28:25 +02001753 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001754 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001755
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001756 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001757 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758 signature, sizeof( signature ),
1759 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001760 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001761 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001763 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001764
1765 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001766 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001768 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001769 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001770 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001771 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001772 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001773
1774exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001775 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001776 mbedtls_psa_crypto_free( );
1777}
1778/* END_CASE */
1779
1780/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001781void derive_key_policy( int policy_usage,
1782 int policy_alg,
1783 int key_type,
1784 data_t *key_data,
1785 int exercise_alg )
1786{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001787 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001788 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001789 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1790 psa_status_t status;
1791
Gilles Peskine8817f612018-12-18 00:18:46 +01001792 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001793
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001794 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001795 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001796 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001797
Gilles Peskine87a5e562019-04-17 12:28:25 +02001798 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001799 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001800
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001801 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001802 exercise_alg,
1803 NULL, 0,
1804 NULL, 0,
1805 1 );
1806 if( policy_alg == exercise_alg &&
1807 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001808 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001809 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001810 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001811
1812exit:
1813 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001814 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001815 mbedtls_psa_crypto_free( );
1816}
1817/* END_CASE */
1818
1819/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001820void agreement_key_policy( int policy_usage,
1821 int policy_alg,
1822 int key_type_arg,
1823 data_t *key_data,
1824 int exercise_alg )
1825{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001826 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001827 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001828 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001829 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1830 psa_status_t status;
1831
Gilles Peskine8817f612018-12-18 00:18:46 +01001832 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001833
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001834 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001835 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001836 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001837
Gilles Peskine87a5e562019-04-17 12:28:25 +02001838 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01001839 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001840
Gilles Peskine969c5d62019-01-16 15:53:06 +01001841 PSA_ASSERT( psa_key_derivation_setup( &generator, exercise_alg ) );
1842 status = key_agreement_with_self( &generator, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001843
Gilles Peskine01d718c2018-09-18 12:01:02 +02001844 if( policy_alg == exercise_alg &&
1845 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001846 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001847 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001848 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001849
1850exit:
1851 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001852 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001853 mbedtls_psa_crypto_free( );
1854}
1855/* END_CASE */
1856
1857/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001858void raw_agreement_key_policy( int policy_usage,
1859 int policy_alg,
1860 int key_type_arg,
1861 data_t *key_data,
1862 int exercise_alg )
1863{
1864 psa_key_handle_t handle = 0;
1865 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
1866 psa_key_type_t key_type = key_type_arg;
1867 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1868 psa_status_t status;
1869
1870 PSA_ASSERT( psa_crypto_init( ) );
1871
1872 PSA_ASSERT( psa_allocate_key( &handle ) );
1873 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
1874 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
1875
Gilles Peskine87a5e562019-04-17 12:28:25 +02001876 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001877 key_data->x, key_data->len ) );
1878
1879 status = raw_key_agreement_with_self( exercise_alg, handle );
1880
1881 if( policy_alg == exercise_alg &&
1882 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1883 PSA_ASSERT( status );
1884 else
1885 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1886
1887exit:
1888 psa_generator_abort( &generator );
1889 psa_destroy_key( handle );
1890 mbedtls_psa_crypto_free( );
1891}
1892/* END_CASE */
1893
1894/* BEGIN_CASE */
Gilles Peskine57ab7212019-01-28 13:03:09 +01001895void copy_key_policy( int source_usage_arg, int source_alg_arg,
1896 int type_arg, data_t *material,
1897 int target_usage_arg, int target_alg_arg,
1898 int constraint_usage_arg, int constraint_alg_arg,
1899 int expected_usage_arg, int expected_alg_arg )
1900{
1901 psa_key_usage_t source_usage = source_usage_arg;
1902 psa_algorithm_t source_alg = source_alg_arg;
1903 psa_key_handle_t source_handle = 0;
1904 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
1905 psa_key_type_t source_type = type_arg;
1906 size_t source_bits;
1907 psa_key_usage_t target_usage = target_usage_arg;
1908 psa_algorithm_t target_alg = target_alg_arg;
1909 psa_key_handle_t target_handle = 0;
1910 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
1911 psa_key_type_t target_type;
1912 size_t target_bits;
1913 psa_key_usage_t constraint_usage = constraint_usage_arg;
1914 psa_algorithm_t constraint_alg = constraint_alg_arg;
1915 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
1916 psa_key_policy_t *p_constraint = NULL;
1917 psa_key_usage_t expected_usage = expected_usage_arg;
1918 psa_algorithm_t expected_alg = expected_alg_arg;
1919 uint8_t *export_buffer = NULL;
1920
1921 if( constraint_usage_arg != -1 )
1922 {
1923 p_constraint = &constraint;
1924 psa_key_policy_set_usage( p_constraint,
1925 constraint_usage, constraint_alg );
1926 }
1927
1928 PSA_ASSERT( psa_crypto_init( ) );
1929
1930 /* Populate the source slot. */
1931 PSA_ASSERT( psa_allocate_key( &source_handle ) );
1932 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
1933 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02001934 PSA_ASSERT( psa_import_key_to_handle( source_handle, source_type,
Gilles Peskine57ab7212019-01-28 13:03:09 +01001935 material->x, material->len ) );
1936 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
1937
1938 /* Prepare the target slot. */
1939 PSA_ASSERT( psa_allocate_key( &target_handle ) );
1940 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
1941 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
1942 target_policy = psa_key_policy_init();
1943
1944 /* Copy the key. */
Gilles Peskine87a5e562019-04-17 12:28:25 +02001945 PSA_ASSERT( psa_copy_key_to_handle( source_handle, target_handle, p_constraint ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001946
1947 /* Destroy the source to ensure that this doesn't affect the target. */
1948 PSA_ASSERT( psa_destroy_key( source_handle ) );
1949
1950 /* Test that the target slot has the expected content and policy. */
1951 PSA_ASSERT( psa_get_key_information( target_handle,
1952 &target_type, &target_bits ) );
1953 TEST_EQUAL( source_type, target_type );
1954 TEST_EQUAL( source_bits, target_bits );
1955 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
1956 TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
1957 TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
1958 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1959 {
1960 size_t length;
1961 ASSERT_ALLOC( export_buffer, material->len );
1962 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1963 material->len, &length ) );
1964 ASSERT_COMPARE( material->x, material->len,
1965 export_buffer, length );
1966 }
1967 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1968 goto exit;
1969
1970 PSA_ASSERT( psa_close_key( target_handle ) );
1971
1972exit:
1973 mbedtls_psa_crypto_free( );
1974 mbedtls_free( export_buffer );
1975}
1976/* END_CASE */
1977
1978/* BEGIN_CASE */
1979void copy_fail( int source_usage_arg, int source_alg_arg,
1980 int type_arg, data_t *material,
1981 int target_usage_arg, int target_alg_arg,
1982 int constraint_usage_arg, int constraint_alg_arg,
1983 int expected_status_arg )
1984{
1985 /* Test copy failure into an empty slot. There is a test for copy failure
1986 * into an occupied slot in
1987 * test_suite_psa_crypto_slot_management.function. */
1988
1989 psa_key_usage_t source_usage = source_usage_arg;
1990 psa_algorithm_t source_alg = source_alg_arg;
1991 psa_key_handle_t source_handle = 0;
1992 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
1993 psa_key_type_t source_type = type_arg;
1994 size_t source_bits;
1995 psa_key_usage_t target_usage = target_usage_arg;
1996 psa_algorithm_t target_alg = target_alg_arg;
1997 psa_key_handle_t target_handle = 0;
1998 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
1999 psa_key_type_t target_type;
2000 size_t target_bits;
2001 psa_key_usage_t constraint_usage = constraint_usage_arg;
2002 psa_algorithm_t constraint_alg = constraint_alg_arg;
2003 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
2004 psa_key_policy_t *p_constraint = NULL;
2005 psa_status_t expected_status = expected_status_arg;
2006
2007 if( constraint_usage_arg != -1 )
2008 {
2009 p_constraint = &constraint;
2010 psa_key_policy_set_usage( p_constraint,
2011 constraint_usage, constraint_alg );
2012 }
2013
2014 PSA_ASSERT( psa_crypto_init( ) );
2015
2016 /* Populate the source slot. */
2017 PSA_ASSERT( psa_allocate_key( &source_handle ) );
2018 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
2019 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02002020 PSA_ASSERT( psa_import_key_to_handle( source_handle, source_type,
Gilles Peskine57ab7212019-01-28 13:03:09 +01002021 material->x, material->len ) );
2022 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
2023
2024 /* Prepare the target slot. */
2025 PSA_ASSERT( psa_allocate_key( &target_handle ) );
2026 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
2027 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
2028 target_policy = psa_key_policy_init();
2029
2030 /* Copy the key. */
Gilles Peskine87a5e562019-04-17 12:28:25 +02002031 TEST_EQUAL( psa_copy_key_to_handle( source_handle, target_handle, p_constraint ),
Gilles Peskine57ab7212019-01-28 13:03:09 +01002032 expected_status );
2033
2034 /* Test that the target slot is unaffected. */
2035 TEST_EQUAL( psa_get_key_information( target_handle,
2036 &target_type, &target_bits ),
David Saadab4ecc272019-02-14 13:48:10 +02002037 PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002038 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
2039 TEST_EQUAL( target_usage, psa_key_policy_get_usage( &target_policy ) );
2040 TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &target_policy ) );
2041
2042exit:
2043 mbedtls_psa_crypto_free( );
2044}
2045/* END_CASE */
2046
2047/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002048void hash_operation_init( )
2049{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002050 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002051 /* Test each valid way of initializing the object, except for `= {0}`, as
2052 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2053 * though it's OK by the C standard. We could test for this, but we'd need
2054 * to supress the Clang warning for the test. */
2055 psa_hash_operation_t func = psa_hash_operation_init( );
2056 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2057 psa_hash_operation_t zero;
2058
2059 memset( &zero, 0, sizeof( zero ) );
2060
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002061 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002062 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2063 PSA_ERROR_BAD_STATE );
2064 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2065 PSA_ERROR_BAD_STATE );
2066 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2067 PSA_ERROR_BAD_STATE );
2068
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002069 /* A default hash operation should be abortable without error. */
2070 PSA_ASSERT( psa_hash_abort( &func ) );
2071 PSA_ASSERT( psa_hash_abort( &init ) );
2072 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002073}
2074/* END_CASE */
2075
2076/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002077void hash_setup( int alg_arg,
2078 int expected_status_arg )
2079{
2080 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002081 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002082 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002083 psa_status_t status;
2084
Gilles Peskine8817f612018-12-18 00:18:46 +01002085 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002086
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002087 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002088 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002089
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002090 /* Whether setup succeeded or failed, abort must succeed. */
2091 PSA_ASSERT( psa_hash_abort( &operation ) );
2092
2093 /* If setup failed, reproduce the failure, so as to
2094 * test the resulting state of the operation object. */
2095 if( status != PSA_SUCCESS )
2096 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2097
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002098 /* Now the operation object should be reusable. */
2099#if defined(KNOWN_SUPPORTED_HASH_ALG)
2100 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2101 PSA_ASSERT( psa_hash_abort( &operation ) );
2102#endif
2103
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002104exit:
2105 mbedtls_psa_crypto_free( );
2106}
2107/* END_CASE */
2108
2109/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002110void hash_bad_order( )
2111{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002112 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002113 unsigned char input[] = "";
2114 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002115 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002116 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2117 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2118 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002119 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002120 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002121 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002122
Gilles Peskine8817f612018-12-18 00:18:46 +01002123 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002124
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002125 /* Call setup twice in a row. */
2126 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2127 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2128 PSA_ERROR_BAD_STATE );
2129 PSA_ASSERT( psa_hash_abort( &operation ) );
2130
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002131 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002132 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002133 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002134 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002135
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002136 /* Call update after finish. */
2137 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2138 PSA_ASSERT( psa_hash_finish( &operation,
2139 hash, sizeof( hash ), &hash_len ) );
2140 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002141 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002142 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002143
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002144 /* Call verify without calling setup beforehand. */
2145 TEST_EQUAL( psa_hash_verify( &operation,
2146 valid_hash, sizeof( valid_hash ) ),
2147 PSA_ERROR_BAD_STATE );
2148 PSA_ASSERT( psa_hash_abort( &operation ) );
2149
2150 /* Call verify after finish. */
2151 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2152 PSA_ASSERT( psa_hash_finish( &operation,
2153 hash, sizeof( hash ), &hash_len ) );
2154 TEST_EQUAL( psa_hash_verify( &operation,
2155 valid_hash, sizeof( valid_hash ) ),
2156 PSA_ERROR_BAD_STATE );
2157 PSA_ASSERT( psa_hash_abort( &operation ) );
2158
2159 /* Call verify twice in a row. */
2160 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2161 PSA_ASSERT( psa_hash_verify( &operation,
2162 valid_hash, sizeof( valid_hash ) ) );
2163 TEST_EQUAL( psa_hash_verify( &operation,
2164 valid_hash, sizeof( valid_hash ) ),
2165 PSA_ERROR_BAD_STATE );
2166 PSA_ASSERT( psa_hash_abort( &operation ) );
2167
2168 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002169 TEST_EQUAL( psa_hash_finish( &operation,
2170 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002171 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002172 PSA_ASSERT( psa_hash_abort( &operation ) );
2173
2174 /* Call finish twice in a row. */
2175 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2176 PSA_ASSERT( psa_hash_finish( &operation,
2177 hash, sizeof( hash ), &hash_len ) );
2178 TEST_EQUAL( psa_hash_finish( &operation,
2179 hash, sizeof( hash ), &hash_len ),
2180 PSA_ERROR_BAD_STATE );
2181 PSA_ASSERT( psa_hash_abort( &operation ) );
2182
2183 /* Call finish after calling verify. */
2184 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2185 PSA_ASSERT( psa_hash_verify( &operation,
2186 valid_hash, sizeof( valid_hash ) ) );
2187 TEST_EQUAL( psa_hash_finish( &operation,
2188 hash, sizeof( hash ), &hash_len ),
2189 PSA_ERROR_BAD_STATE );
2190 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002191
2192exit:
2193 mbedtls_psa_crypto_free( );
2194}
2195/* END_CASE */
2196
itayzafrir27e69452018-11-01 14:26:34 +02002197/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2198void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002199{
2200 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002201 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2202 * appended to it */
2203 unsigned char hash[] = {
2204 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2205 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2206 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002207 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002208 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002209
Gilles Peskine8817f612018-12-18 00:18:46 +01002210 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002211
itayzafrir27e69452018-11-01 14:26:34 +02002212 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002213 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002214 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002215 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002216
itayzafrir27e69452018-11-01 14:26:34 +02002217 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002218 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002219 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002220 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002221
itayzafrir27e69452018-11-01 14:26:34 +02002222 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002223 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002224 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002225 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002226
itayzafrirec93d302018-10-18 18:01:10 +03002227exit:
2228 mbedtls_psa_crypto_free( );
2229}
2230/* END_CASE */
2231
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002232/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2233void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002234{
2235 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002236 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002237 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002238 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002239 size_t hash_len;
2240
Gilles Peskine8817f612018-12-18 00:18:46 +01002241 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002242
itayzafrir58028322018-10-25 10:22:01 +03002243 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002244 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002245 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002246 hash, expected_size - 1, &hash_len ),
2247 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002248
2249exit:
2250 mbedtls_psa_crypto_free( );
2251}
2252/* END_CASE */
2253
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002254/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2255void hash_clone_source_state( )
2256{
2257 psa_algorithm_t alg = PSA_ALG_SHA_256;
2258 unsigned char hash[PSA_HASH_MAX_SIZE];
2259 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2260 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2261 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2262 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2263 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2264 size_t hash_len;
2265
2266 PSA_ASSERT( psa_crypto_init( ) );
2267 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2268
2269 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2270 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2271 PSA_ASSERT( psa_hash_finish( &op_finished,
2272 hash, sizeof( hash ), &hash_len ) );
2273 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2274 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2275
2276 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2277 PSA_ERROR_BAD_STATE );
2278
2279 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2280 PSA_ASSERT( psa_hash_finish( &op_init,
2281 hash, sizeof( hash ), &hash_len ) );
2282 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2283 PSA_ASSERT( psa_hash_finish( &op_finished,
2284 hash, sizeof( hash ), &hash_len ) );
2285 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2286 PSA_ASSERT( psa_hash_finish( &op_aborted,
2287 hash, sizeof( hash ), &hash_len ) );
2288
2289exit:
2290 psa_hash_abort( &op_source );
2291 psa_hash_abort( &op_init );
2292 psa_hash_abort( &op_setup );
2293 psa_hash_abort( &op_finished );
2294 psa_hash_abort( &op_aborted );
2295 mbedtls_psa_crypto_free( );
2296}
2297/* END_CASE */
2298
2299/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2300void hash_clone_target_state( )
2301{
2302 psa_algorithm_t alg = PSA_ALG_SHA_256;
2303 unsigned char hash[PSA_HASH_MAX_SIZE];
2304 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2305 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2306 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2307 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2308 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2309 size_t hash_len;
2310
2311 PSA_ASSERT( psa_crypto_init( ) );
2312
2313 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2314 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2315 PSA_ASSERT( psa_hash_finish( &op_finished,
2316 hash, sizeof( hash ), &hash_len ) );
2317 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2318 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2319
2320 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2321 PSA_ASSERT( psa_hash_finish( &op_target,
2322 hash, sizeof( hash ), &hash_len ) );
2323
2324 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2325 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2326 PSA_ERROR_BAD_STATE );
2327 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2328 PSA_ERROR_BAD_STATE );
2329
2330exit:
2331 psa_hash_abort( &op_target );
2332 psa_hash_abort( &op_init );
2333 psa_hash_abort( &op_setup );
2334 psa_hash_abort( &op_finished );
2335 psa_hash_abort( &op_aborted );
2336 mbedtls_psa_crypto_free( );
2337}
2338/* END_CASE */
2339
itayzafrir58028322018-10-25 10:22:01 +03002340/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002341void mac_operation_init( )
2342{
Jaeden Amero252ef282019-02-15 14:05:35 +00002343 const uint8_t input[1] = { 0 };
2344
Jaeden Amero769ce272019-01-04 11:48:03 +00002345 /* Test each valid way of initializing the object, except for `= {0}`, as
2346 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2347 * though it's OK by the C standard. We could test for this, but we'd need
2348 * to supress the Clang warning for the test. */
2349 psa_mac_operation_t func = psa_mac_operation_init( );
2350 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2351 psa_mac_operation_t zero;
2352
2353 memset( &zero, 0, sizeof( zero ) );
2354
Jaeden Amero252ef282019-02-15 14:05:35 +00002355 /* A freshly-initialized MAC operation should not be usable. */
2356 TEST_EQUAL( psa_mac_update( &func,
2357 input, sizeof( input ) ),
2358 PSA_ERROR_BAD_STATE );
2359 TEST_EQUAL( psa_mac_update( &init,
2360 input, sizeof( input ) ),
2361 PSA_ERROR_BAD_STATE );
2362 TEST_EQUAL( psa_mac_update( &zero,
2363 input, sizeof( input ) ),
2364 PSA_ERROR_BAD_STATE );
2365
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002366 /* A default MAC operation should be abortable without error. */
2367 PSA_ASSERT( psa_mac_abort( &func ) );
2368 PSA_ASSERT( psa_mac_abort( &init ) );
2369 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002370}
2371/* END_CASE */
2372
2373/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002374void mac_setup( int key_type_arg,
2375 data_t *key,
2376 int alg_arg,
2377 int expected_status_arg )
2378{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002379 psa_key_type_t key_type = key_type_arg;
2380 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002381 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002382 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002383 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2384#if defined(KNOWN_SUPPORTED_MAC_ALG)
2385 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2386#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002387
Gilles Peskine8817f612018-12-18 00:18:46 +01002388 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002389
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002390 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2391 &operation, &status ) )
2392 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002393 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002394
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002395 /* The operation object should be reusable. */
2396#if defined(KNOWN_SUPPORTED_MAC_ALG)
2397 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2398 smoke_test_key_data,
2399 sizeof( smoke_test_key_data ),
2400 KNOWN_SUPPORTED_MAC_ALG,
2401 &operation, &status ) )
2402 goto exit;
2403 TEST_EQUAL( status, PSA_SUCCESS );
2404#endif
2405
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002406exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002407 mbedtls_psa_crypto_free( );
2408}
2409/* END_CASE */
2410
2411/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002412void mac_bad_order( )
2413{
2414 psa_key_handle_t handle = 0;
2415 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2416 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2417 const uint8_t key[] = {
2418 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2419 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2420 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
2421 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2422 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2423 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2424 size_t sign_mac_length = 0;
2425 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2426 const uint8_t verify_mac[] = {
2427 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2428 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2429 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2430
2431 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir3e02b3b2018-06-12 17:06:52 +03002432 PSA_ASSERT( psa_allocate_key( &handle ) );
2433 psa_key_policy_set_usage( &policy,
2434 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002435 alg );
2436 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2437
Gilles Peskine87a5e562019-04-17 12:28:25 +02002438 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Jaeden Amero252ef282019-02-15 14:05:35 +00002439 key, sizeof(key) ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002440
Jaeden Amero252ef282019-02-15 14:05:35 +00002441 /* Call update without calling setup beforehand. */
2442 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2443 PSA_ERROR_BAD_STATE );
2444 PSA_ASSERT( psa_mac_abort( &operation ) );
2445
2446 /* Call sign finish without calling setup beforehand. */
2447 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2448 &sign_mac_length),
2449 PSA_ERROR_BAD_STATE );
2450 PSA_ASSERT( psa_mac_abort( &operation ) );
2451
2452 /* Call verify finish without calling setup beforehand. */
2453 TEST_EQUAL( psa_mac_verify_finish( &operation,
2454 verify_mac, sizeof( verify_mac ) ),
2455 PSA_ERROR_BAD_STATE );
2456 PSA_ASSERT( psa_mac_abort( &operation ) );
2457
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002458 /* Call setup twice in a row. */
2459 PSA_ASSERT( psa_mac_sign_setup( &operation,
2460 handle, alg ) );
2461 TEST_EQUAL( psa_mac_sign_setup( &operation,
2462 handle, alg ),
2463 PSA_ERROR_BAD_STATE );
2464 PSA_ASSERT( psa_mac_abort( &operation ) );
2465
Jaeden Amero252ef282019-02-15 14:05:35 +00002466 /* Call update after sign finish. */
2467 PSA_ASSERT( psa_mac_sign_setup( &operation,
2468 handle, alg ) );
2469 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2470 PSA_ASSERT( psa_mac_sign_finish( &operation,
2471 sign_mac, sizeof( sign_mac ),
2472 &sign_mac_length ) );
2473 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2474 PSA_ERROR_BAD_STATE );
2475 PSA_ASSERT( psa_mac_abort( &operation ) );
2476
2477 /* Call update after verify finish. */
2478 PSA_ASSERT( psa_mac_verify_setup( &operation,
2479 handle, alg ) );
2480 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2481 PSA_ASSERT( psa_mac_verify_finish( &operation,
2482 verify_mac, sizeof( verify_mac ) ) );
2483 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2484 PSA_ERROR_BAD_STATE );
2485 PSA_ASSERT( psa_mac_abort( &operation ) );
2486
2487 /* Call sign finish twice in a row. */
2488 PSA_ASSERT( psa_mac_sign_setup( &operation,
2489 handle, alg ) );
2490 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2491 PSA_ASSERT( psa_mac_sign_finish( &operation,
2492 sign_mac, sizeof( sign_mac ),
2493 &sign_mac_length ) );
2494 TEST_EQUAL( psa_mac_sign_finish( &operation,
2495 sign_mac, sizeof( sign_mac ),
2496 &sign_mac_length ),
2497 PSA_ERROR_BAD_STATE );
2498 PSA_ASSERT( psa_mac_abort( &operation ) );
2499
2500 /* Call verify finish twice in a row. */
2501 PSA_ASSERT( psa_mac_verify_setup( &operation,
2502 handle, alg ) );
2503 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2504 PSA_ASSERT( psa_mac_verify_finish( &operation,
2505 verify_mac, sizeof( verify_mac ) ) );
2506 TEST_EQUAL( psa_mac_verify_finish( &operation,
2507 verify_mac, sizeof( verify_mac ) ),
2508 PSA_ERROR_BAD_STATE );
2509 PSA_ASSERT( psa_mac_abort( &operation ) );
2510
2511 /* Setup sign but try verify. */
2512 PSA_ASSERT( psa_mac_sign_setup( &operation,
2513 handle, alg ) );
2514 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2515 TEST_EQUAL( psa_mac_verify_finish( &operation,
2516 verify_mac, sizeof( verify_mac ) ),
2517 PSA_ERROR_BAD_STATE );
2518 PSA_ASSERT( psa_mac_abort( &operation ) );
2519
2520 /* Setup verify but try sign. */
2521 PSA_ASSERT( psa_mac_verify_setup( &operation,
2522 handle, alg ) );
2523 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2524 TEST_EQUAL( psa_mac_sign_finish( &operation,
2525 sign_mac, sizeof( sign_mac ),
2526 &sign_mac_length ),
2527 PSA_ERROR_BAD_STATE );
2528 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002529
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002530exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002531 mbedtls_psa_crypto_free( );
2532}
2533/* END_CASE */
2534
2535/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002536void mac_sign( int key_type_arg,
2537 data_t *key,
2538 int alg_arg,
2539 data_t *input,
2540 data_t *expected_mac )
2541{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002542 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002543 psa_key_type_t key_type = key_type_arg;
2544 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002545 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002546 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002547 /* Leave a little extra room in the output buffer. At the end of the
2548 * test, we'll check that the implementation didn't overwrite onto
2549 * this extra room. */
2550 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2551 size_t mac_buffer_size =
2552 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2553 size_t mac_length = 0;
2554
2555 memset( actual_mac, '+', sizeof( actual_mac ) );
2556 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2557 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2558
Gilles Peskine8817f612018-12-18 00:18:46 +01002559 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002560
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002561 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002562 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002563 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002564
Gilles Peskine87a5e562019-04-17 12:28:25 +02002565 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002566 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002567
2568 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002569 PSA_ASSERT( psa_mac_sign_setup( &operation,
2570 handle, alg ) );
2571 PSA_ASSERT( psa_mac_update( &operation,
2572 input->x, input->len ) );
2573 PSA_ASSERT( psa_mac_sign_finish( &operation,
2574 actual_mac, mac_buffer_size,
2575 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002576
2577 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002578 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2579 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002580
2581 /* Verify that the end of the buffer is untouched. */
2582 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2583 sizeof( actual_mac ) - mac_length ) );
2584
2585exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002586 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002587 mbedtls_psa_crypto_free( );
2588}
2589/* END_CASE */
2590
2591/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002592void mac_verify( int key_type_arg,
2593 data_t *key,
2594 int alg_arg,
2595 data_t *input,
2596 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002597{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002598 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002599 psa_key_type_t key_type = key_type_arg;
2600 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002601 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002602 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002603
Gilles Peskine69c12672018-06-28 00:07:19 +02002604 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2605
Gilles Peskine8817f612018-12-18 00:18:46 +01002606 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002607
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002608 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002609 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002610 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad16036df908f2018-04-02 08:34:15 -07002611
Gilles Peskine87a5e562019-04-17 12:28:25 +02002612 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002613 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002614
Gilles Peskine8817f612018-12-18 00:18:46 +01002615 PSA_ASSERT( psa_mac_verify_setup( &operation,
2616 handle, alg ) );
2617 PSA_ASSERT( psa_destroy_key( handle ) );
2618 PSA_ASSERT( psa_mac_update( &operation,
2619 input->x, input->len ) );
2620 PSA_ASSERT( psa_mac_verify_finish( &operation,
2621 expected_mac->x,
2622 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002623
2624exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002625 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002626 mbedtls_psa_crypto_free( );
2627}
2628/* END_CASE */
2629
2630/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002631void cipher_operation_init( )
2632{
Jaeden Ameroab439972019-02-15 14:12:05 +00002633 const uint8_t input[1] = { 0 };
2634 unsigned char output[1] = { 0 };
2635 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002636 /* Test each valid way of initializing the object, except for `= {0}`, as
2637 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2638 * though it's OK by the C standard. We could test for this, but we'd need
2639 * to supress the Clang warning for the test. */
2640 psa_cipher_operation_t func = psa_cipher_operation_init( );
2641 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2642 psa_cipher_operation_t zero;
2643
2644 memset( &zero, 0, sizeof( zero ) );
2645
Jaeden Ameroab439972019-02-15 14:12:05 +00002646 /* A freshly-initialized cipher operation should not be usable. */
2647 TEST_EQUAL( psa_cipher_update( &func,
2648 input, sizeof( input ),
2649 output, sizeof( output ),
2650 &output_length ),
2651 PSA_ERROR_BAD_STATE );
2652 TEST_EQUAL( psa_cipher_update( &init,
2653 input, sizeof( input ),
2654 output, sizeof( output ),
2655 &output_length ),
2656 PSA_ERROR_BAD_STATE );
2657 TEST_EQUAL( psa_cipher_update( &zero,
2658 input, sizeof( input ),
2659 output, sizeof( output ),
2660 &output_length ),
2661 PSA_ERROR_BAD_STATE );
2662
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002663 /* A default cipher operation should be abortable without error. */
2664 PSA_ASSERT( psa_cipher_abort( &func ) );
2665 PSA_ASSERT( psa_cipher_abort( &init ) );
2666 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002667}
2668/* END_CASE */
2669
2670/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002671void cipher_setup( int key_type_arg,
2672 data_t *key,
2673 int alg_arg,
2674 int expected_status_arg )
2675{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002676 psa_key_type_t key_type = key_type_arg;
2677 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002678 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002679 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002680 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002681#if defined(KNOWN_SUPPORTED_MAC_ALG)
2682 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2683#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002684
Gilles Peskine8817f612018-12-18 00:18:46 +01002685 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002686
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002687 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2688 &operation, &status ) )
2689 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002690 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002691
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002692 /* The operation object should be reusable. */
2693#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2694 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2695 smoke_test_key_data,
2696 sizeof( smoke_test_key_data ),
2697 KNOWN_SUPPORTED_CIPHER_ALG,
2698 &operation, &status ) )
2699 goto exit;
2700 TEST_EQUAL( status, PSA_SUCCESS );
2701#endif
2702
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002703exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002704 mbedtls_psa_crypto_free( );
2705}
2706/* END_CASE */
2707
2708/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002709void cipher_bad_order( )
2710{
2711 psa_key_handle_t handle = 0;
2712 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2713 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
2714 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2715 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2716 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2717 const uint8_t key[] = {
2718 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2719 0xaa, 0xaa, 0xaa, 0xaa };
2720 const uint8_t text[] = {
2721 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2722 0xbb, 0xbb, 0xbb, 0xbb };
2723 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2724 size_t length = 0;
2725
2726 PSA_ASSERT( psa_crypto_init( ) );
2727 PSA_ASSERT( psa_allocate_key( &handle ) );
2728 psa_key_policy_set_usage( &policy,
2729 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
2730 alg );
2731 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02002732 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Jaeden Ameroab439972019-02-15 14:12:05 +00002733 key, sizeof(key) ) );
2734
2735
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002736 /* Call encrypt setup twice in a row. */
2737 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2738 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2739 PSA_ERROR_BAD_STATE );
2740 PSA_ASSERT( psa_cipher_abort( &operation ) );
2741
2742 /* Call decrypt setup twice in a row. */
2743 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2744 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2745 PSA_ERROR_BAD_STATE );
2746 PSA_ASSERT( psa_cipher_abort( &operation ) );
2747
Jaeden Ameroab439972019-02-15 14:12:05 +00002748 /* Generate an IV without calling setup beforehand. */
2749 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2750 buffer, sizeof( buffer ),
2751 &length ),
2752 PSA_ERROR_BAD_STATE );
2753 PSA_ASSERT( psa_cipher_abort( &operation ) );
2754
2755 /* Generate an IV twice in a row. */
2756 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2757 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2758 buffer, sizeof( buffer ),
2759 &length ) );
2760 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2761 buffer, sizeof( buffer ),
2762 &length ),
2763 PSA_ERROR_BAD_STATE );
2764 PSA_ASSERT( psa_cipher_abort( &operation ) );
2765
2766 /* Generate an IV after it's already set. */
2767 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2768 PSA_ASSERT( psa_cipher_set_iv( &operation,
2769 iv, sizeof( iv ) ) );
2770 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2771 buffer, sizeof( buffer ),
2772 &length ),
2773 PSA_ERROR_BAD_STATE );
2774 PSA_ASSERT( psa_cipher_abort( &operation ) );
2775
2776 /* Set an IV without calling setup beforehand. */
2777 TEST_EQUAL( psa_cipher_set_iv( &operation,
2778 iv, sizeof( iv ) ),
2779 PSA_ERROR_BAD_STATE );
2780 PSA_ASSERT( psa_cipher_abort( &operation ) );
2781
2782 /* Set an IV after it's already set. */
2783 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2784 PSA_ASSERT( psa_cipher_set_iv( &operation,
2785 iv, sizeof( iv ) ) );
2786 TEST_EQUAL( psa_cipher_set_iv( &operation,
2787 iv, sizeof( iv ) ),
2788 PSA_ERROR_BAD_STATE );
2789 PSA_ASSERT( psa_cipher_abort( &operation ) );
2790
2791 /* Set an IV after it's already generated. */
2792 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2793 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2794 buffer, sizeof( buffer ),
2795 &length ) );
2796 TEST_EQUAL( psa_cipher_set_iv( &operation,
2797 iv, sizeof( iv ) ),
2798 PSA_ERROR_BAD_STATE );
2799 PSA_ASSERT( psa_cipher_abort( &operation ) );
2800
2801 /* Call update without calling setup beforehand. */
2802 TEST_EQUAL( psa_cipher_update( &operation,
2803 text, sizeof( text ),
2804 buffer, sizeof( buffer ),
2805 &length ),
2806 PSA_ERROR_BAD_STATE );
2807 PSA_ASSERT( psa_cipher_abort( &operation ) );
2808
2809 /* Call update without an IV where an IV is required. */
2810 TEST_EQUAL( psa_cipher_update( &operation,
2811 text, sizeof( text ),
2812 buffer, sizeof( buffer ),
2813 &length ),
2814 PSA_ERROR_BAD_STATE );
2815 PSA_ASSERT( psa_cipher_abort( &operation ) );
2816
2817 /* Call update after finish. */
2818 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2819 PSA_ASSERT( psa_cipher_set_iv( &operation,
2820 iv, sizeof( iv ) ) );
2821 PSA_ASSERT( psa_cipher_finish( &operation,
2822 buffer, sizeof( buffer ), &length ) );
2823 TEST_EQUAL( psa_cipher_update( &operation,
2824 text, sizeof( text ),
2825 buffer, sizeof( buffer ),
2826 &length ),
2827 PSA_ERROR_BAD_STATE );
2828 PSA_ASSERT( psa_cipher_abort( &operation ) );
2829
2830 /* Call finish without calling setup beforehand. */
2831 TEST_EQUAL( psa_cipher_finish( &operation,
2832 buffer, sizeof( buffer ), &length ),
2833 PSA_ERROR_BAD_STATE );
2834 PSA_ASSERT( psa_cipher_abort( &operation ) );
2835
2836 /* Call finish without an IV where an IV is required. */
2837 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2838 /* Not calling update means we are encrypting an empty buffer, which is OK
2839 * for cipher modes with padding. */
2840 TEST_EQUAL( psa_cipher_finish( &operation,
2841 buffer, sizeof( buffer ), &length ),
2842 PSA_ERROR_BAD_STATE );
2843 PSA_ASSERT( psa_cipher_abort( &operation ) );
2844
2845 /* Call finish twice in a row. */
2846 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2847 PSA_ASSERT( psa_cipher_set_iv( &operation,
2848 iv, sizeof( iv ) ) );
2849 PSA_ASSERT( psa_cipher_finish( &operation,
2850 buffer, sizeof( buffer ), &length ) );
2851 TEST_EQUAL( psa_cipher_finish( &operation,
2852 buffer, sizeof( buffer ), &length ),
2853 PSA_ERROR_BAD_STATE );
2854 PSA_ASSERT( psa_cipher_abort( &operation ) );
2855
2856exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002857 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002858}
2859/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002860
Gilles Peskine50e586b2018-06-08 14:28:46 +02002861/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002862void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002863 data_t *key,
2864 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002865 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002866{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002867 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002868 psa_status_t status;
2869 psa_key_type_t key_type = key_type_arg;
2870 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002871 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002872 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002873 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002874 unsigned char *output = NULL;
2875 size_t output_buffer_size = 0;
2876 size_t function_output_length = 0;
2877 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002878 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002879 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002880
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002881 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2882 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002883
Gilles Peskine8817f612018-12-18 00:18:46 +01002884 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002885
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002886 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002887 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002888 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002889
Gilles Peskine87a5e562019-04-17 12:28:25 +02002890 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002891 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002892
Gilles Peskine8817f612018-12-18 00:18:46 +01002893 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2894 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002895
Gilles Peskine8817f612018-12-18 00:18:46 +01002896 PSA_ASSERT( psa_cipher_set_iv( &operation,
2897 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002898 output_buffer_size = ( (size_t) input->len +
2899 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002900 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002901
Gilles Peskine8817f612018-12-18 00:18:46 +01002902 PSA_ASSERT( psa_cipher_update( &operation,
2903 input->x, input->len,
2904 output, output_buffer_size,
2905 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002906 total_output_length += function_output_length;
2907 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002908 output + total_output_length,
2909 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002910 &function_output_length );
2911 total_output_length += function_output_length;
2912
Gilles Peskinefe11b722018-12-18 00:24:04 +01002913 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002914 if( expected_status == PSA_SUCCESS )
2915 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002916 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002917 ASSERT_COMPARE( expected_output->x, expected_output->len,
2918 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002919 }
2920
2921exit:
2922 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002923 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924 mbedtls_psa_crypto_free( );
2925}
2926/* END_CASE */
2927
2928/* BEGIN_CASE */
2929void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
2930 data_t *key,
2931 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002932 int first_part_size_arg,
2933 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002934 data_t *expected_output )
2935{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002936 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002937 psa_key_type_t key_type = key_type_arg;
2938 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002939 size_t first_part_size = first_part_size_arg;
2940 size_t output1_length = output1_length_arg;
2941 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002942 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002943 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002944 unsigned char *output = NULL;
2945 size_t output_buffer_size = 0;
2946 size_t function_output_length = 0;
2947 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002948 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002949 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002950
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002951 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2952 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002953
Gilles Peskine8817f612018-12-18 00:18:46 +01002954 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002955
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002956 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002957 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002958 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002959
Gilles Peskine87a5e562019-04-17 12:28:25 +02002960 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01002961 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002962
Gilles Peskine8817f612018-12-18 00:18:46 +01002963 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2964 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002965
Gilles Peskine8817f612018-12-18 00:18:46 +01002966 PSA_ASSERT( psa_cipher_set_iv( &operation,
2967 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002968 output_buffer_size = ( (size_t) input->len +
2969 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002970 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002971
Gilles Peskinee0866522019-02-19 19:44:00 +01002972 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002973 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2974 output, output_buffer_size,
2975 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002976 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002977 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002978 PSA_ASSERT( psa_cipher_update( &operation,
2979 input->x + first_part_size,
2980 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002981 output + total_output_length,
2982 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002983 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002984 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002985 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002986 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002987 output + total_output_length,
2988 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002989 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002990 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002991 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002992
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002993 ASSERT_COMPARE( expected_output->x, expected_output->len,
2994 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002995
2996exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002997 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002998 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002999 mbedtls_psa_crypto_free( );
3000}
3001/* END_CASE */
3002
3003/* BEGIN_CASE */
3004void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003005 data_t *key,
3006 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003007 int first_part_size_arg,
3008 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003009 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003010{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003011 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012
3013 psa_key_type_t key_type = key_type_arg;
3014 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003015 size_t first_part_size = first_part_size_arg;
3016 size_t output1_length = output1_length_arg;
3017 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003018 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003019 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003020 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003021 size_t output_buffer_size = 0;
3022 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003023 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003024 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003025 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003026
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003027 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3028 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003029
Gilles Peskine8817f612018-12-18 00:18:46 +01003030 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003031
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003032 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003033 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003034 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003035
Gilles Peskine87a5e562019-04-17 12:28:25 +02003036 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003037 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003038
Gilles Peskine8817f612018-12-18 00:18:46 +01003039 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3040 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003041
Gilles Peskine8817f612018-12-18 00:18:46 +01003042 PSA_ASSERT( psa_cipher_set_iv( &operation,
3043 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003044
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003045 output_buffer_size = ( (size_t) input->len +
3046 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003047 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003048
Gilles Peskinee0866522019-02-19 19:44:00 +01003049 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003050 PSA_ASSERT( psa_cipher_update( &operation,
3051 input->x, first_part_size,
3052 output, output_buffer_size,
3053 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003054 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003055 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003056 PSA_ASSERT( psa_cipher_update( &operation,
3057 input->x + first_part_size,
3058 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003059 output + total_output_length,
3060 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003061 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003062 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003063 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003064 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003065 output + total_output_length,
3066 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003067 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003068 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003069 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003070
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003071 ASSERT_COMPARE( expected_output->x, expected_output->len,
3072 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003073
3074exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003075 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003076 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003077 mbedtls_psa_crypto_free( );
3078}
3079/* END_CASE */
3080
Gilles Peskine50e586b2018-06-08 14:28:46 +02003081/* BEGIN_CASE */
3082void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003083 data_t *key,
3084 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003085 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003087 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003088 psa_status_t status;
3089 psa_key_type_t key_type = key_type_arg;
3090 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003091 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003092 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003093 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003094 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003095 size_t output_buffer_size = 0;
3096 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003097 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003098 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003099 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003100
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003101 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3102 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003103
Gilles Peskine8817f612018-12-18 00:18:46 +01003104 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003105
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003106 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003107 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003108 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003109
Gilles Peskine87a5e562019-04-17 12:28:25 +02003110 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003111 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003112
Gilles Peskine8817f612018-12-18 00:18:46 +01003113 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3114 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003115
Gilles Peskine8817f612018-12-18 00:18:46 +01003116 PSA_ASSERT( psa_cipher_set_iv( &operation,
3117 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003118
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003119 output_buffer_size = ( (size_t) input->len +
3120 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003121 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003122
Gilles Peskine8817f612018-12-18 00:18:46 +01003123 PSA_ASSERT( psa_cipher_update( &operation,
3124 input->x, input->len,
3125 output, output_buffer_size,
3126 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003127 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003128 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003129 output + total_output_length,
3130 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003131 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003132 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003133 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003134
3135 if( expected_status == PSA_SUCCESS )
3136 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003137 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003138 ASSERT_COMPARE( expected_output->x, expected_output->len,
3139 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003140 }
3141
Gilles Peskine50e586b2018-06-08 14:28:46 +02003142exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003143 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003144 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003145 mbedtls_psa_crypto_free( );
3146}
3147/* END_CASE */
3148
Gilles Peskine50e586b2018-06-08 14:28:46 +02003149/* BEGIN_CASE */
3150void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003151 data_t *key,
3152 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003153{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003154 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003155 psa_key_type_t key_type = key_type_arg;
3156 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003157 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003158 size_t iv_size = 16;
3159 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003160 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003161 size_t output1_size = 0;
3162 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003163 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003164 size_t output2_size = 0;
3165 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003166 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003167 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3168 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003169 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003170
Gilles Peskine8817f612018-12-18 00:18:46 +01003171 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003172
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003173 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003174 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003175 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003176
Gilles Peskine87a5e562019-04-17 12:28:25 +02003177 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003178 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003179
Gilles Peskine8817f612018-12-18 00:18:46 +01003180 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3181 handle, alg ) );
3182 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3183 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003184
Gilles Peskine8817f612018-12-18 00:18:46 +01003185 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3186 iv, iv_size,
3187 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003188 output1_size = ( (size_t) input->len +
3189 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003190 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003191
Gilles Peskine8817f612018-12-18 00:18:46 +01003192 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3193 output1, output1_size,
3194 &output1_length ) );
3195 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003196 output1 + output1_length,
3197 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003198 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003199
Gilles Peskine048b7f02018-06-08 14:20:49 +02003200 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003201
Gilles Peskine8817f612018-12-18 00:18:46 +01003202 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003203
3204 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003205 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003206
Gilles Peskine8817f612018-12-18 00:18:46 +01003207 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3208 iv, iv_length ) );
3209 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3210 output2, output2_size,
3211 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003212 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003213 PSA_ASSERT( psa_cipher_finish( &operation2,
3214 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003215 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003216 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003217
Gilles Peskine048b7f02018-06-08 14:20:49 +02003218 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003219
Gilles Peskine8817f612018-12-18 00:18:46 +01003220 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003221
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003222 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003223
3224exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003225 mbedtls_free( output1 );
3226 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003227 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003228 mbedtls_psa_crypto_free( );
3229}
3230/* END_CASE */
3231
3232/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003233void cipher_verify_output_multipart( int alg_arg,
3234 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003235 data_t *key,
3236 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003237 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003238{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003239 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003240 psa_key_type_t key_type = key_type_arg;
3241 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003242 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003243 unsigned char iv[16] = {0};
3244 size_t iv_size = 16;
3245 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003246 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003247 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003248 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003249 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003250 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003251 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003252 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003253 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3254 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003255 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003256
Gilles Peskine8817f612018-12-18 00:18:46 +01003257 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003258
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003259 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003260 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003261 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003262
Gilles Peskine87a5e562019-04-17 12:28:25 +02003263 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003264 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003265
Gilles Peskine8817f612018-12-18 00:18:46 +01003266 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3267 handle, alg ) );
3268 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3269 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003270
Gilles Peskine8817f612018-12-18 00:18:46 +01003271 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3272 iv, iv_size,
3273 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003274 output1_buffer_size = ( (size_t) input->len +
3275 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003276 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003277
Gilles Peskinee0866522019-02-19 19:44:00 +01003278 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003279
Gilles Peskine8817f612018-12-18 00:18:46 +01003280 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3281 output1, output1_buffer_size,
3282 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003283 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003284
Gilles Peskine8817f612018-12-18 00:18:46 +01003285 PSA_ASSERT( psa_cipher_update( &operation1,
3286 input->x + first_part_size,
3287 input->len - first_part_size,
3288 output1, output1_buffer_size,
3289 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003290 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003291
Gilles Peskine8817f612018-12-18 00:18:46 +01003292 PSA_ASSERT( psa_cipher_finish( &operation1,
3293 output1 + output1_length,
3294 output1_buffer_size - output1_length,
3295 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003296 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003297
Gilles Peskine8817f612018-12-18 00:18:46 +01003298 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003299
Gilles Peskine048b7f02018-06-08 14:20:49 +02003300 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003301 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003302
Gilles Peskine8817f612018-12-18 00:18:46 +01003303 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3304 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003305
Gilles Peskine8817f612018-12-18 00:18:46 +01003306 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3307 output2, output2_buffer_size,
3308 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003309 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003310
Gilles Peskine8817f612018-12-18 00:18:46 +01003311 PSA_ASSERT( psa_cipher_update( &operation2,
3312 output1 + first_part_size,
3313 output1_length - first_part_size,
3314 output2, output2_buffer_size,
3315 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003316 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003317
Gilles Peskine8817f612018-12-18 00:18:46 +01003318 PSA_ASSERT( psa_cipher_finish( &operation2,
3319 output2 + output2_length,
3320 output2_buffer_size - output2_length,
3321 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003322 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003323
Gilles Peskine8817f612018-12-18 00:18:46 +01003324 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003325
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003326 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003327
3328exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003329 mbedtls_free( output1 );
3330 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003331 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003332 mbedtls_psa_crypto_free( );
3333}
3334/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003335
Gilles Peskine20035e32018-02-03 22:44:14 +01003336/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003337void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003338 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003339 data_t *nonce,
3340 data_t *additional_data,
3341 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003342 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003343{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003344 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003345 psa_key_type_t key_type = key_type_arg;
3346 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003347 unsigned char *output_data = NULL;
3348 size_t output_size = 0;
3349 size_t output_length = 0;
3350 unsigned char *output_data2 = NULL;
3351 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003352 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003353 psa_status_t expected_result = expected_result_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003354 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003355
Gilles Peskine4abf7412018-06-18 16:35:34 +02003356 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003357 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003358
Gilles Peskine8817f612018-12-18 00:18:46 +01003359 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003360
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003361 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003362 psa_key_policy_set_usage( &policy,
3363 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
3364 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003365 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003366
Gilles Peskine87a5e562019-04-17 12:28:25 +02003367 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003368 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003369
Gilles Peskinefe11b722018-12-18 00:24:04 +01003370 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3371 nonce->x, nonce->len,
3372 additional_data->x,
3373 additional_data->len,
3374 input_data->x, input_data->len,
3375 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003376 &output_length ),
3377 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003378
3379 if( PSA_SUCCESS == expected_result )
3380 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003381 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003382
Gilles Peskinefe11b722018-12-18 00:24:04 +01003383 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3384 nonce->x, nonce->len,
3385 additional_data->x,
3386 additional_data->len,
3387 output_data, output_length,
3388 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003389 &output_length2 ),
3390 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003391
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003392 ASSERT_COMPARE( input_data->x, input_data->len,
3393 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003394 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003395
Gilles Peskinea1cac842018-06-11 19:33:02 +02003396exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003397 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003398 mbedtls_free( output_data );
3399 mbedtls_free( output_data2 );
3400 mbedtls_psa_crypto_free( );
3401}
3402/* END_CASE */
3403
3404/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003405void aead_encrypt( int key_type_arg, data_t *key_data,
3406 int alg_arg,
3407 data_t *nonce,
3408 data_t *additional_data,
3409 data_t *input_data,
3410 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003411{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003412 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003413 psa_key_type_t key_type = key_type_arg;
3414 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003415 unsigned char *output_data = NULL;
3416 size_t output_size = 0;
3417 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003419 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003420
Gilles Peskine4abf7412018-06-18 16:35:34 +02003421 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003422 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003423
Gilles Peskine8817f612018-12-18 00:18:46 +01003424 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003425
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003426 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003427 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003428 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003429
Gilles Peskine87a5e562019-04-17 12:28:25 +02003430 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003431 key_data->x,
3432 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003433
Gilles Peskine8817f612018-12-18 00:18:46 +01003434 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3435 nonce->x, nonce->len,
3436 additional_data->x, additional_data->len,
3437 input_data->x, input_data->len,
3438 output_data, output_size,
3439 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003440
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003441 ASSERT_COMPARE( expected_result->x, expected_result->len,
3442 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003443
Gilles Peskinea1cac842018-06-11 19:33:02 +02003444exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003445 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003446 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003447 mbedtls_psa_crypto_free( );
3448}
3449/* END_CASE */
3450
3451/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003452void aead_decrypt( int key_type_arg, data_t *key_data,
3453 int alg_arg,
3454 data_t *nonce,
3455 data_t *additional_data,
3456 data_t *input_data,
3457 data_t *expected_data,
3458 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003459{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003460 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003461 psa_key_type_t key_type = key_type_arg;
3462 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003463 unsigned char *output_data = NULL;
3464 size_t output_size = 0;
3465 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003466 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003467 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003468 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003469
Gilles Peskine4abf7412018-06-18 16:35:34 +02003470 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003471 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003472
Gilles Peskine8817f612018-12-18 00:18:46 +01003473 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003474
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003475 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003476 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003477 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003478
Gilles Peskine87a5e562019-04-17 12:28:25 +02003479 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003480 key_data->x,
3481 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003482
Gilles Peskinefe11b722018-12-18 00:24:04 +01003483 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3484 nonce->x, nonce->len,
3485 additional_data->x,
3486 additional_data->len,
3487 input_data->x, input_data->len,
3488 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003489 &output_length ),
3490 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003491
Gilles Peskine2d277862018-06-18 15:41:12 +02003492 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003493 ASSERT_COMPARE( expected_data->x, expected_data->len,
3494 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003495
Gilles Peskinea1cac842018-06-11 19:33:02 +02003496exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003497 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003498 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003499 mbedtls_psa_crypto_free( );
3500}
3501/* END_CASE */
3502
3503/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003504void signature_size( int type_arg,
3505 int bits,
3506 int alg_arg,
3507 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003508{
3509 psa_key_type_t type = type_arg;
3510 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003511 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003512 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003513exit:
3514 ;
3515}
3516/* END_CASE */
3517
3518/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003519void sign_deterministic( int key_type_arg, data_t *key_data,
3520 int alg_arg, data_t *input_data,
3521 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003522{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003523 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003524 psa_key_type_t key_type = key_type_arg;
3525 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003526 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003527 unsigned char *signature = NULL;
3528 size_t signature_size;
3529 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003530 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003531 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003532
Gilles Peskine8817f612018-12-18 00:18:46 +01003533 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003534
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003535 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003536 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003537 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003538
Gilles Peskine87a5e562019-04-17 12:28:25 +02003539 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003540 key_data->x,
3541 key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003542 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3543 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003544
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003545 /* Allocate a buffer which has the size advertized by the
3546 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003547 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3548 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003549 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003550 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003551 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003552
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003553 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003554 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3555 input_data->x, input_data->len,
3556 signature, signature_size,
3557 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003558 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003559 ASSERT_COMPARE( output_data->x, output_data->len,
3560 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003561
3562exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003563 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003564 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003565 mbedtls_psa_crypto_free( );
3566}
3567/* END_CASE */
3568
3569/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003570void sign_fail( int key_type_arg, data_t *key_data,
3571 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003572 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003573{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003574 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003575 psa_key_type_t key_type = key_type_arg;
3576 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003577 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003578 psa_status_t actual_status;
3579 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003580 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003581 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003582 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003583
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003584 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003585
Gilles Peskine8817f612018-12-18 00:18:46 +01003586 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003587
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003588 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003589 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003590 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003591
Gilles Peskine87a5e562019-04-17 12:28:25 +02003592 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003593 key_data->x,
3594 key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003595
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003596 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003597 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003598 signature, signature_size,
3599 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003600 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003601 /* The value of *signature_length is unspecified on error, but
3602 * whatever it is, it should be less than signature_size, so that
3603 * if the caller tries to read *signature_length bytes without
3604 * checking the error code then they don't overflow a buffer. */
3605 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003606
3607exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003608 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003609 mbedtls_free( signature );
3610 mbedtls_psa_crypto_free( );
3611}
3612/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003613
3614/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003615void sign_verify( int key_type_arg, data_t *key_data,
3616 int alg_arg, data_t *input_data )
3617{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003618 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003619 psa_key_type_t key_type = key_type_arg;
3620 psa_algorithm_t alg = alg_arg;
3621 size_t key_bits;
3622 unsigned char *signature = NULL;
3623 size_t signature_size;
3624 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003625 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003626 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003627
Gilles Peskine8817f612018-12-18 00:18:46 +01003628 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003629
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003630 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003631 psa_key_policy_set_usage( &policy,
3632 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
3633 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003634 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003635
Gilles Peskine87a5e562019-04-17 12:28:25 +02003636 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003637 key_data->x,
3638 key_data->len ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003639 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3640 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003641
3642 /* Allocate a buffer which has the size advertized by the
3643 * library. */
3644 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3645 key_bits, alg );
3646 TEST_ASSERT( signature_size != 0 );
3647 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003648 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003649
3650 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003651 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3652 input_data->x, input_data->len,
3653 signature, signature_size,
3654 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003655 /* Check that the signature length looks sensible. */
3656 TEST_ASSERT( signature_length <= signature_size );
3657 TEST_ASSERT( signature_length > 0 );
3658
3659 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003660 PSA_ASSERT( psa_asymmetric_verify(
3661 handle, alg,
3662 input_data->x, input_data->len,
3663 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003664
3665 if( input_data->len != 0 )
3666 {
3667 /* Flip a bit in the input and verify that the signature is now
3668 * detected as invalid. Flip a bit at the beginning, not at the end,
3669 * because ECDSA may ignore the last few bits of the input. */
3670 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003671 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3672 input_data->x, input_data->len,
3673 signature, signature_length ),
3674 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003675 }
3676
3677exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003678 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003679 mbedtls_free( signature );
3680 mbedtls_psa_crypto_free( );
3681}
3682/* END_CASE */
3683
3684/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003685void asymmetric_verify( int key_type_arg, data_t *key_data,
3686 int alg_arg, data_t *hash_data,
3687 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003688{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003689 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003690 psa_key_type_t key_type = key_type_arg;
3691 psa_algorithm_t alg = alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003692 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003693
Gilles Peskine69c12672018-06-28 00:07:19 +02003694 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3695
Gilles Peskine8817f612018-12-18 00:18:46 +01003696 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003697
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003698 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003699 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003700 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
itayzafrir5c753392018-05-08 11:18:38 +03003701
Gilles Peskine87a5e562019-04-17 12:28:25 +02003702 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003703 key_data->x,
3704 key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003705
Gilles Peskine8817f612018-12-18 00:18:46 +01003706 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3707 hash_data->x, hash_data->len,
3708 signature_data->x,
3709 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003710exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003711 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003712 mbedtls_psa_crypto_free( );
3713}
3714/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003715
3716/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003717void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3718 int alg_arg, data_t *hash_data,
3719 data_t *signature_data,
3720 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003721{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003722 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003723 psa_key_type_t key_type = key_type_arg;
3724 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003725 psa_status_t actual_status;
3726 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003727 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003728
Gilles Peskine8817f612018-12-18 00:18:46 +01003729 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003730
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003731 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003732 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003733 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003734
Gilles Peskine87a5e562019-04-17 12:28:25 +02003735 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003736 key_data->x,
3737 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003738
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003739 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003740 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003741 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003742 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003743
Gilles Peskinefe11b722018-12-18 00:24:04 +01003744 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003745
3746exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003747 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003748 mbedtls_psa_crypto_free( );
3749}
3750/* END_CASE */
3751
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003752/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003753void asymmetric_encrypt( int key_type_arg,
3754 data_t *key_data,
3755 int alg_arg,
3756 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003757 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003758 int expected_output_length_arg,
3759 int expected_status_arg )
3760{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003761 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003762 psa_key_type_t key_type = key_type_arg;
3763 psa_algorithm_t alg = alg_arg;
3764 size_t expected_output_length = expected_output_length_arg;
3765 size_t key_bits;
3766 unsigned char *output = NULL;
3767 size_t output_size;
3768 size_t output_length = ~0;
3769 psa_status_t actual_status;
3770 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003771 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003772 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003773
Gilles Peskine8817f612018-12-18 00:18:46 +01003774 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003775
Gilles Peskine656896e2018-06-29 19:12:28 +02003776 /* Import the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003777 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003778 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003779 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02003780 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003781 key_data->x,
3782 key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003783
3784 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003785 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3786 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003787 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003788 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003789
3790 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003791 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003792 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003793 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003794 output, output_size,
3795 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003796 TEST_EQUAL( actual_status, expected_status );
3797 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003798
Gilles Peskine68428122018-06-30 18:42:41 +02003799 /* If the label is empty, the test framework puts a non-null pointer
3800 * in label->x. Test that a null pointer works as well. */
3801 if( label->len == 0 )
3802 {
3803 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003804 if( output_size != 0 )
3805 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003806 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003807 input_data->x, input_data->len,
3808 NULL, label->len,
3809 output, output_size,
3810 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003811 TEST_EQUAL( actual_status, expected_status );
3812 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003813 }
3814
Gilles Peskine656896e2018-06-29 19:12:28 +02003815exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003816 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003817 mbedtls_free( output );
3818 mbedtls_psa_crypto_free( );
3819}
3820/* END_CASE */
3821
3822/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003823void asymmetric_encrypt_decrypt( int key_type_arg,
3824 data_t *key_data,
3825 int alg_arg,
3826 data_t *input_data,
3827 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003828{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003829 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003830 psa_key_type_t key_type = key_type_arg;
3831 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003832 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003833 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003834 size_t output_size;
3835 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003836 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003837 size_t output2_size;
3838 size_t output2_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003839 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003840 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003841
Gilles Peskine8817f612018-12-18 00:18:46 +01003842 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003843
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003844 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003845 psa_key_policy_set_usage( &policy,
3846 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003847 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003848 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003849
Gilles Peskine87a5e562019-04-17 12:28:25 +02003850 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003851 key_data->x,
3852 key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003853
3854 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003855 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3856 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003857 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003858 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003859 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003860 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003861
Gilles Peskineeebd7382018-06-08 18:11:54 +02003862 /* We test encryption by checking that encrypt-then-decrypt gives back
3863 * the original plaintext because of the non-optional random
3864 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003865 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3866 input_data->x, input_data->len,
3867 label->x, label->len,
3868 output, output_size,
3869 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003870 /* We don't know what ciphertext length to expect, but check that
3871 * it looks sensible. */
3872 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003873
Gilles Peskine8817f612018-12-18 00:18:46 +01003874 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3875 output, output_length,
3876 label->x, label->len,
3877 output2, output2_size,
3878 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003879 ASSERT_COMPARE( input_data->x, input_data->len,
3880 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881
3882exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003883 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003884 mbedtls_free( output );
3885 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003886 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003887}
3888/* END_CASE */
3889
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003890/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003891void asymmetric_decrypt( int key_type_arg,
3892 data_t *key_data,
3893 int alg_arg,
3894 data_t *input_data,
3895 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003896 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003897{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003898 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003899 psa_key_type_t key_type = key_type_arg;
3900 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003901 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003902 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003903 size_t output_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003904 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003905
Jaeden Amero412654a2019-02-06 12:57:46 +00003906 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003907 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003908
Gilles Peskine8817f612018-12-18 00:18:46 +01003909 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003910
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003911 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003912 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003913 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003914
Gilles Peskine87a5e562019-04-17 12:28:25 +02003915 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003916 key_data->x,
3917 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003918
Gilles Peskine8817f612018-12-18 00:18:46 +01003919 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3920 input_data->x, input_data->len,
3921 label->x, label->len,
3922 output,
3923 output_size,
3924 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003925 ASSERT_COMPARE( expected_data->x, expected_data->len,
3926 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003927
Gilles Peskine68428122018-06-30 18:42:41 +02003928 /* If the label is empty, the test framework puts a non-null pointer
3929 * in label->x. Test that a null pointer works as well. */
3930 if( label->len == 0 )
3931 {
3932 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003933 if( output_size != 0 )
3934 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003935 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3936 input_data->x, input_data->len,
3937 NULL, label->len,
3938 output,
3939 output_size,
3940 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003941 ASSERT_COMPARE( expected_data->x, expected_data->len,
3942 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003943 }
3944
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003945exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003946 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003947 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003948 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003949}
3950/* END_CASE */
3951
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003952/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003953void asymmetric_decrypt_fail( int key_type_arg,
3954 data_t *key_data,
3955 int alg_arg,
3956 data_t *input_data,
3957 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003958 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003959 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003960{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003961 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003962 psa_key_type_t key_type = key_type_arg;
3963 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003964 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003965 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003966 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003967 psa_status_t actual_status;
3968 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003969 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003970
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003971 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003972
Gilles Peskine8817f612018-12-18 00:18:46 +01003973 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003974
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003975 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003976 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003977 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003978
Gilles Peskine87a5e562019-04-17 12:28:25 +02003979 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01003980 key_data->x,
3981 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003982
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003983 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003984 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003985 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003986 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003987 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003988 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003989 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003990
Gilles Peskine68428122018-06-30 18:42:41 +02003991 /* If the label is empty, the test framework puts a non-null pointer
3992 * in label->x. Test that a null pointer works as well. */
3993 if( label->len == 0 )
3994 {
3995 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003996 if( output_size != 0 )
3997 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003998 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003999 input_data->x, input_data->len,
4000 NULL, label->len,
4001 output, output_size,
4002 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004003 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004004 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004005 }
4006
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004007exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004008 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004009 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004010 mbedtls_psa_crypto_free( );
4011}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004012/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004013
4014/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00004015void crypto_generator_init( )
4016{
4017 /* Test each valid way of initializing the object, except for `= {0}`, as
4018 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4019 * though it's OK by the C standard. We could test for this, but we'd need
4020 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004021 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004022 psa_crypto_generator_t func = psa_crypto_generator_init( );
4023 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
4024 psa_crypto_generator_t zero;
4025
4026 memset( &zero, 0, sizeof( zero ) );
4027
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004028 /* A default generator should not be able to report its capacity. */
4029 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
4030 PSA_ERROR_BAD_STATE );
4031 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
4032 PSA_ERROR_BAD_STATE );
4033 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
4034 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004035
4036 /* A default generator should be abortable without error. */
4037 PSA_ASSERT( psa_generator_abort(&func) );
4038 PSA_ASSERT( psa_generator_abort(&init) );
4039 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004040}
4041/* END_CASE */
4042
4043/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004044void derive_setup( int key_type_arg,
4045 data_t *key_data,
4046 int alg_arg,
4047 data_t *salt,
4048 data_t *label,
4049 int requested_capacity_arg,
4050 int expected_status_arg )
4051{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004052 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004053 size_t key_type = key_type_arg;
4054 psa_algorithm_t alg = alg_arg;
4055 size_t requested_capacity = requested_capacity_arg;
4056 psa_status_t expected_status = expected_status_arg;
4057 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004058 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004059
Gilles Peskine8817f612018-12-18 00:18:46 +01004060 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004061
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004062 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004063 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004064 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004065
Gilles Peskine87a5e562019-04-17 12:28:25 +02004066 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004067 key_data->x,
4068 key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004069
Gilles Peskinefe11b722018-12-18 00:24:04 +01004070 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4071 salt->x, salt->len,
4072 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004073 requested_capacity ),
4074 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004075
4076exit:
4077 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004078 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004079 mbedtls_psa_crypto_free( );
4080}
4081/* END_CASE */
4082
4083/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004084void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004085{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004086 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004087 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004088 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004089 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004090 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004091 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004092 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4093 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4094 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Jaeden Amero70261c52019-01-04 11:47:20 +00004095 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004096
Gilles Peskine8817f612018-12-18 00:18:46 +01004097 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004098
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004099 PSA_ASSERT( psa_allocate_key( &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004100 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004101 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004102
Gilles Peskine87a5e562019-04-17 12:28:25 +02004103 PSA_ASSERT( psa_import_key_to_handle( handle, key_type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004104 key_data,
4105 sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004106
4107 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004108 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4109 NULL, 0,
4110 NULL, 0,
4111 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004112
4113 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004114 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4115 NULL, 0,
4116 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004117 capacity ),
4118 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004119
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004120 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004121
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004122 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004123 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004124
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004125exit:
4126 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004127 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004128 mbedtls_psa_crypto_free( );
4129}
4130/* END_CASE */
4131
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004132/* BEGIN_CASE */
4133void test_derive_invalid_generator_tests( )
4134{
4135 uint8_t output_buffer[16];
4136 size_t buffer_size = 16;
4137 size_t capacity = 0;
4138 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4139
Nir Sonnenschein50789302018-10-31 12:16:38 +02004140 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004141 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004142
4143 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004144 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004145
Gilles Peskine8817f612018-12-18 00:18:46 +01004146 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004147
Nir Sonnenschein50789302018-10-31 12:16:38 +02004148 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004149 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004150
Nir Sonnenschein50789302018-10-31 12:16:38 +02004151 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004152 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004153
4154exit:
4155 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004156}
4157/* END_CASE */
4158
4159/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004160void derive_output( int alg_arg,
4161 data_t *key_data,
4162 data_t *salt,
4163 data_t *label,
4164 int requested_capacity_arg,
4165 data_t *expected_output1,
4166 data_t *expected_output2 )
4167{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004168 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004169 psa_algorithm_t alg = alg_arg;
4170 size_t requested_capacity = requested_capacity_arg;
4171 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4172 uint8_t *expected_outputs[2] =
4173 {expected_output1->x, expected_output2->x};
4174 size_t output_sizes[2] =
4175 {expected_output1->len, expected_output2->len};
4176 size_t output_buffer_size = 0;
4177 uint8_t *output_buffer = NULL;
4178 size_t expected_capacity;
4179 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004180 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004181 psa_status_t status;
4182 unsigned i;
4183
4184 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4185 {
4186 if( output_sizes[i] > output_buffer_size )
4187 output_buffer_size = output_sizes[i];
4188 if( output_sizes[i] == 0 )
4189 expected_outputs[i] = NULL;
4190 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004191 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004192 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004193
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004194 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4195 psa_set_key_algorithm( &attributes, alg );
4196 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004197
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004198 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004199 key_data->x,
4200 key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004201
4202 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004203 if( PSA_ALG_IS_HKDF( alg ) )
4204 {
4205 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4206 PSA_ASSERT( psa_set_generator_capacity( &generator,
4207 requested_capacity ) );
4208 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4209 PSA_KDF_STEP_SALT,
4210 salt->x, salt->len ) );
4211 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4212 PSA_KDF_STEP_SECRET,
4213 handle ) );
4214 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4215 PSA_KDF_STEP_INFO,
4216 label->x, label->len ) );
4217 }
4218 else
4219 {
4220 // legacy
4221 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4222 salt->x, salt->len,
4223 label->x, label->len,
4224 requested_capacity ) );
4225 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004226 PSA_ASSERT( psa_get_generator_capacity( &generator,
4227 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004228 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004229 expected_capacity = requested_capacity;
4230
4231 /* Expansion phase. */
4232 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4233 {
4234 /* Read some bytes. */
4235 status = psa_generator_read( &generator,
4236 output_buffer, output_sizes[i] );
4237 if( expected_capacity == 0 && output_sizes[i] == 0 )
4238 {
4239 /* Reading 0 bytes when 0 bytes are available can go either way. */
4240 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004241 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004242 continue;
4243 }
4244 else if( expected_capacity == 0 ||
4245 output_sizes[i] > expected_capacity )
4246 {
4247 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004248 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004249 expected_capacity = 0;
4250 continue;
4251 }
4252 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004253 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004254 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004255 ASSERT_COMPARE( output_buffer, output_sizes[i],
4256 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004257 /* Check the generator status. */
4258 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004259 PSA_ASSERT( psa_get_generator_capacity( &generator,
4260 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004261 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004262 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004263 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004264
4265exit:
4266 mbedtls_free( output_buffer );
4267 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004268 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004269 mbedtls_psa_crypto_free( );
4270}
4271/* END_CASE */
4272
4273/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004274void derive_full( int alg_arg,
4275 data_t *key_data,
4276 data_t *salt,
4277 data_t *label,
4278 int requested_capacity_arg )
4279{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004280 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004281 psa_algorithm_t alg = alg_arg;
4282 size_t requested_capacity = requested_capacity_arg;
4283 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4284 unsigned char output_buffer[16];
4285 size_t expected_capacity = requested_capacity;
4286 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004287 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004288
Gilles Peskine8817f612018-12-18 00:18:46 +01004289 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004290
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004291 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4292 psa_set_key_algorithm( &attributes, alg );
4293 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004294
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004295 PSA_ASSERT( psa_import_key( &attributes, &handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004296 key_data->x,
4297 key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004298
4299 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004300 if( PSA_ALG_IS_HKDF( alg ) )
4301 {
4302 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4303 PSA_ASSERT( psa_set_generator_capacity( &generator,
4304 requested_capacity ) );
4305 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4306 PSA_KDF_STEP_SALT,
4307 salt->x, salt->len ) );
4308 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4309 PSA_KDF_STEP_SECRET,
4310 handle ) );
4311 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4312 PSA_KDF_STEP_INFO,
4313 label->x, label->len ) );
4314 }
4315 else
4316 {
4317 // legacy
4318 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4319 salt->x, salt->len,
4320 label->x, label->len,
4321 requested_capacity ) );
4322 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004323 PSA_ASSERT( psa_get_generator_capacity( &generator,
4324 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004325 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004326
4327 /* Expansion phase. */
4328 while( current_capacity > 0 )
4329 {
4330 size_t read_size = sizeof( output_buffer );
4331 if( read_size > current_capacity )
4332 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004333 PSA_ASSERT( psa_generator_read( &generator,
4334 output_buffer,
4335 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004336 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004337 PSA_ASSERT( psa_get_generator_capacity( &generator,
4338 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004339 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004340 }
4341
4342 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004343 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004344 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004345
Gilles Peskine8817f612018-12-18 00:18:46 +01004346 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004347
4348exit:
4349 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004350 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004351 mbedtls_psa_crypto_free( );
4352}
4353/* END_CASE */
4354
4355/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004356void derive_key_exercise( int alg_arg,
4357 data_t *key_data,
4358 data_t *salt,
4359 data_t *label,
4360 int derived_type_arg,
4361 int derived_bits_arg,
4362 int derived_usage_arg,
4363 int derived_alg_arg )
4364{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004365 psa_key_handle_t base_handle = 0;
4366 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004367 psa_algorithm_t alg = alg_arg;
4368 psa_key_type_t derived_type = derived_type_arg;
4369 size_t derived_bits = derived_bits_arg;
4370 psa_key_usage_t derived_usage = derived_usage_arg;
4371 psa_algorithm_t derived_alg = derived_alg_arg;
4372 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4373 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004374 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004375 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004376
Gilles Peskine8817f612018-12-18 00:18:46 +01004377 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004378
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004379 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4380 psa_set_key_algorithm( &attributes, alg );
4381 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
4382 PSA_ASSERT( psa_import_key( &attributes, &base_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004383 key_data->x,
4384 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004385
4386 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004387 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4388 salt->x, salt->len,
4389 label->x, label->len,
4390 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004391 psa_set_key_usage_flags( &attributes, derived_usage );
4392 psa_set_key_algorithm( &attributes, derived_alg );
4393 psa_set_key_type( &attributes, derived_type );
4394 PSA_ASSERT( psa_generator_import_key( &attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004395 derived_bits,
4396 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004397
4398 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004399 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4400 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4401 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004402
4403 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004404 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004405 goto exit;
4406
4407exit:
4408 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004409 psa_destroy_key( base_handle );
4410 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004411 mbedtls_psa_crypto_free( );
4412}
4413/* END_CASE */
4414
4415/* BEGIN_CASE */
4416void derive_key_export( int alg_arg,
4417 data_t *key_data,
4418 data_t *salt,
4419 data_t *label,
4420 int bytes1_arg,
4421 int bytes2_arg )
4422{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004423 psa_key_handle_t base_handle = 0;
4424 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004425 psa_algorithm_t alg = alg_arg;
4426 size_t bytes1 = bytes1_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004427 size_t derived_bits = PSA_BYTES_TO_BITS( bytes1 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004428 size_t bytes2 = bytes2_arg;
4429 size_t capacity = bytes1 + bytes2;
4430 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004431 uint8_t *output_buffer = NULL;
4432 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004433 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4434 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004435 size_t length;
4436
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004437 ASSERT_ALLOC( output_buffer, capacity );
4438 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004439 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004440
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004441 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4442 psa_set_key_algorithm( &base_attributes, alg );
4443 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4444 PSA_ASSERT( psa_import_key( &base_attributes, &base_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004445 key_data->x,
4446 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004447
4448 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004449 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4450 salt->x, salt->len,
4451 label->x, label->len,
4452 capacity ) );
4453 PSA_ASSERT( psa_generator_read( &generator,
4454 output_buffer,
4455 capacity ) );
4456 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004457
4458 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004459 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4460 salt->x, salt->len,
4461 label->x, label->len,
4462 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004463 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4464 psa_set_key_algorithm( &derived_attributes, 0 );
4465 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
4466 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004467 derived_bits,
4468 &generator ) );
4469 PSA_ASSERT( psa_export_key( derived_handle,
4470 export_buffer, bytes1,
4471 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004472 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004473 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004474 PSA_ASSERT( psa_generator_import_key( &derived_attributes, &derived_handle,
Gilles Peskine8817f612018-12-18 00:18:46 +01004475 PSA_BYTES_TO_BITS( bytes2 ),
4476 &generator ) );
4477 PSA_ASSERT( psa_export_key( derived_handle,
4478 export_buffer + bytes1, bytes2,
4479 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004480 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004481
4482 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004483 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4484 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004485
4486exit:
4487 mbedtls_free( output_buffer );
4488 mbedtls_free( export_buffer );
4489 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004490 psa_destroy_key( base_handle );
4491 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004492 mbedtls_psa_crypto_free( );
4493}
4494/* END_CASE */
4495
4496/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004497void key_agreement_setup( int alg_arg,
4498 int our_key_type_arg, data_t *our_key_data,
4499 data_t *peer_key_data,
4500 int expected_status_arg )
4501{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004502 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004503 psa_algorithm_t alg = alg_arg;
4504 psa_key_type_t our_key_type = our_key_type_arg;
4505 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004506 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004507 psa_status_t expected_status = expected_status_arg;
4508 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004509
Gilles Peskine8817f612018-12-18 00:18:46 +01004510 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004511
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004512 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4513 psa_set_key_algorithm( &attributes, alg );
4514 psa_set_key_type( &attributes, our_key_type );
4515 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004516 our_key_data->x,
4517 our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004518
Gilles Peskine77f40d82019-04-11 21:27:06 +02004519 /* The tests currently include inputs that should fail at either step.
4520 * Test cases that fail at the setup step should be changed to call
4521 * key_derivation_setup instead, and this function should be renamed
4522 * to key_agreement_fail. */
4523 status = psa_key_derivation_setup( &generator, alg );
4524 if( status == PSA_SUCCESS )
4525 {
4526 TEST_EQUAL( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
4527 our_key,
4528 peer_key_data->x, peer_key_data->len ),
4529 expected_status );
4530 }
4531 else
4532 {
4533 TEST_ASSERT( status == expected_status );
4534 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004535
4536exit:
4537 psa_generator_abort( &generator );
4538 psa_destroy_key( our_key );
4539 mbedtls_psa_crypto_free( );
4540}
4541/* END_CASE */
4542
4543/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004544void raw_key_agreement( int alg_arg,
4545 int our_key_type_arg, data_t *our_key_data,
4546 data_t *peer_key_data,
4547 data_t *expected_output )
4548{
4549 psa_key_handle_t our_key = 0;
4550 psa_algorithm_t alg = alg_arg;
4551 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004552 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004553 unsigned char *output = NULL;
4554 size_t output_length = ~0;
4555
4556 ASSERT_ALLOC( output, expected_output->len );
4557 PSA_ASSERT( psa_crypto_init( ) );
4558
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004559 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4560 psa_set_key_algorithm( &attributes, alg );
4561 psa_set_key_type( &attributes, our_key_type );
4562 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskinef0cba732019-04-11 22:12:38 +02004563 our_key_data->x,
4564 our_key_data->len ) );
4565
4566 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4567 alg, our_key,
4568 peer_key_data->x, peer_key_data->len,
4569 output, expected_output->len, &output_length ) );
4570 ASSERT_COMPARE( output, output_length,
4571 expected_output->x, expected_output->len );
4572
4573exit:
4574 mbedtls_free( output );
4575 psa_destroy_key( our_key );
4576 mbedtls_psa_crypto_free( );
4577}
4578/* END_CASE */
4579
4580/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004581void key_agreement_capacity( int alg_arg,
4582 int our_key_type_arg, data_t *our_key_data,
4583 data_t *peer_key_data,
4584 int expected_capacity_arg )
4585{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004586 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004587 psa_algorithm_t alg = alg_arg;
4588 psa_key_type_t our_key_type = our_key_type_arg;
4589 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004590 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004591 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004592 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004593
Gilles Peskine8817f612018-12-18 00:18:46 +01004594 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004595
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004596 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4597 psa_set_key_algorithm( &attributes, alg );
4598 psa_set_key_type( &attributes, our_key_type );
4599 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004600 our_key_data->x,
4601 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004602
Gilles Peskine969c5d62019-01-16 15:53:06 +01004603 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4604 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004605 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004606 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004607 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4608 {
4609 /* The test data is for info="" */
4610 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4611 PSA_KDF_STEP_INFO,
4612 NULL, 0 ) );
4613 }
Gilles Peskine59685592018-09-18 12:11:34 +02004614
Gilles Peskinebf491972018-10-25 22:36:12 +02004615 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004616 PSA_ASSERT( psa_get_generator_capacity(
4617 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004618 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004619
Gilles Peskinebf491972018-10-25 22:36:12 +02004620 /* Test the actual capacity by reading the output. */
4621 while( actual_capacity > sizeof( output ) )
4622 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004623 PSA_ASSERT( psa_generator_read( &generator,
4624 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004625 actual_capacity -= sizeof( output );
4626 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004627 PSA_ASSERT( psa_generator_read( &generator,
4628 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004629 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004630 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004631
Gilles Peskine59685592018-09-18 12:11:34 +02004632exit:
4633 psa_generator_abort( &generator );
4634 psa_destroy_key( our_key );
4635 mbedtls_psa_crypto_free( );
4636}
4637/* END_CASE */
4638
4639/* BEGIN_CASE */
4640void key_agreement_output( int alg_arg,
4641 int our_key_type_arg, data_t *our_key_data,
4642 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004643 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004644{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004645 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004646 psa_algorithm_t alg = alg_arg;
4647 psa_key_type_t our_key_type = our_key_type_arg;
4648 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004649 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004650 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004651
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004652 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4653 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004654
Gilles Peskine8817f612018-12-18 00:18:46 +01004655 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004656
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004657 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4658 psa_set_key_algorithm( &attributes, alg );
4659 psa_set_key_type( &attributes, our_key_type );
4660 PSA_ASSERT( psa_import_key( &attributes, &our_key,
Gilles Peskine8817f612018-12-18 00:18:46 +01004661 our_key_data->x,
4662 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004663
Gilles Peskine969c5d62019-01-16 15:53:06 +01004664 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4665 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004666 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004667 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004668 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4669 {
4670 /* The test data is for info="" */
4671 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4672 PSA_KDF_STEP_INFO,
4673 NULL, 0 ) );
4674 }
Gilles Peskine59685592018-09-18 12:11:34 +02004675
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004676 PSA_ASSERT( psa_generator_read( &generator,
4677 actual_output,
4678 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004679 ASSERT_COMPARE( actual_output, expected_output1->len,
4680 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004681 if( expected_output2->len != 0 )
4682 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004683 PSA_ASSERT( psa_generator_read( &generator,
4684 actual_output,
4685 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004686 ASSERT_COMPARE( actual_output, expected_output2->len,
4687 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004688 }
Gilles Peskine59685592018-09-18 12:11:34 +02004689
4690exit:
4691 psa_generator_abort( &generator );
4692 psa_destroy_key( our_key );
4693 mbedtls_psa_crypto_free( );
4694 mbedtls_free( actual_output );
4695}
4696/* END_CASE */
4697
4698/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004699void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004700{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004701 size_t bytes = bytes_arg;
4702 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004703 unsigned char *output = NULL;
4704 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004705 size_t i;
4706 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004707
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004708 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4709 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004710 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004711
Gilles Peskine8817f612018-12-18 00:18:46 +01004712 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004713
Gilles Peskinea50d7392018-06-21 10:22:13 +02004714 /* Run several times, to ensure that every output byte will be
4715 * nonzero at least once with overwhelming probability
4716 * (2^(-8*number_of_runs)). */
4717 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004718 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004719 if( bytes != 0 )
4720 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004721 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004722
4723 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004724 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4725 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004726
4727 for( i = 0; i < bytes; i++ )
4728 {
4729 if( output[i] != 0 )
4730 ++changed[i];
4731 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004732 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004733
4734 /* Check that every byte was changed to nonzero at least once. This
4735 * validates that psa_generate_random is overwriting every byte of
4736 * the output buffer. */
4737 for( i = 0; i < bytes; i++ )
4738 {
4739 TEST_ASSERT( changed[i] != 0 );
4740 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004741
4742exit:
4743 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004744 mbedtls_free( output );
4745 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004746}
4747/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004748
4749/* BEGIN_CASE */
4750void generate_key( int type_arg,
4751 int bits_arg,
4752 int usage_arg,
4753 int alg_arg,
4754 int expected_status_arg )
4755{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004756 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004757 psa_key_type_t type = type_arg;
4758 psa_key_usage_t usage = usage_arg;
4759 size_t bits = bits_arg;
4760 psa_algorithm_t alg = alg_arg;
4761 psa_status_t expected_status = expected_status_arg;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004762 psa_status_t expected_info_status =
David Saadab4ecc272019-02-14 13:48:10 +02004763 expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004764 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004765 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004766
Gilles Peskine8817f612018-12-18 00:18:46 +01004767 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004768
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004769 psa_set_key_usage_flags( &attributes, usage );
4770 psa_set_key_algorithm( &attributes, alg );
4771 psa_set_key_type( &attributes, type );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004772
4773 /* Generate a key */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004774 TEST_EQUAL( psa_generate_key( &attributes, &handle, bits, NULL, 0 ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004775 expected_status );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004776 if( expected_info_status != PSA_SUCCESS )
4777 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004778
4779 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004780 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4781 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4782 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004783
Gilles Peskine818ca122018-06-20 18:16:48 +02004784 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004785 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004786 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004787
4788exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004789 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004790 mbedtls_psa_crypto_free( );
4791}
4792/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004793
Darryl Greend49a4992018-06-18 17:27:26 +01004794/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
4795void persistent_key_load_key_from_storage( data_t *data, int type_arg,
4796 int bits, int usage_arg,
Darryl Green0c6575a2018-11-07 16:05:30 +00004797 int alg_arg, int generation_method,
4798 int export_status )
Darryl Greend49a4992018-06-18 17:27:26 +01004799{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004800 psa_key_handle_t handle = 0;
4801 psa_key_handle_t base_key;
Darryl Greend49a4992018-06-18 17:27:26 +01004802 psa_key_type_t type = (psa_key_type_t) type_arg;
4803 psa_key_type_t type_get;
4804 size_t bits_get;
Jaeden Amero70261c52019-01-04 11:47:20 +00004805 psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT;
4806 psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004807 psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg;
4808 psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00004809 psa_key_policy_t base_policy_set = PSA_KEY_POLICY_INIT;
Darryl Green0c6575a2018-11-07 16:05:30 +00004810 psa_algorithm_t base_policy_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
4811 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004812 unsigned char *first_export = NULL;
4813 unsigned char *second_export = NULL;
4814 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4815 size_t first_exported_length;
4816 size_t second_exported_length;
4817
4818 ASSERT_ALLOC( first_export, export_size );
4819 ASSERT_ALLOC( second_export, export_size );
4820
Gilles Peskine8817f612018-12-18 00:18:46 +01004821 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004822
Gilles Peskine8817f612018-12-18 00:18:46 +01004823 PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
Gilles Peskine8817f612018-12-18 00:18:46 +01004824 &handle ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004825 psa_key_policy_set_usage( &policy_set, policy_usage,
4826 policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004827 PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004828
Darryl Green0c6575a2018-11-07 16:05:30 +00004829 switch( generation_method )
4830 {
4831 case IMPORT_KEY:
4832 /* Import the key */
Gilles Peskine87a5e562019-04-17 12:28:25 +02004833 PSA_ASSERT( psa_import_key_to_handle( handle, type,
Gilles Peskine8817f612018-12-18 00:18:46 +01004834 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004835 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004836
Darryl Green0c6575a2018-11-07 16:05:30 +00004837 case GENERATE_KEY:
4838 /* Generate a key */
Gilles Peskine87a5e562019-04-17 12:28:25 +02004839 PSA_ASSERT( psa_generate_key_to_handle( handle, type, bits,
Gilles Peskine8817f612018-12-18 00:18:46 +01004840 NULL, 0 ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004841 break;
4842
4843 case DERIVE_KEY:
4844 /* Create base key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004845 PSA_ASSERT( psa_allocate_key( &base_key ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004846 psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE,
4847 base_policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004848 PSA_ASSERT( psa_set_key_policy(
4849 base_key, &base_policy_set ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02004850 PSA_ASSERT( psa_import_key_to_handle( base_key, PSA_KEY_TYPE_DERIVE,
Gilles Peskine8817f612018-12-18 00:18:46 +01004851 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004852 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004853 PSA_ASSERT( psa_key_derivation( &generator, base_key,
4854 base_policy_alg,
4855 NULL, 0, NULL, 0,
4856 export_size ) );
Gilles Peskine87a5e562019-04-17 12:28:25 +02004857 PSA_ASSERT( psa_generator_import_key_to_handle(
Gilles Peskine8817f612018-12-18 00:18:46 +01004858 handle, PSA_KEY_TYPE_RAW_DATA,
4859 bits, &generator ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004860 break;
4861 }
Darryl Greend49a4992018-06-18 17:27:26 +01004862
4863 /* Export the key */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004864 TEST_EQUAL( psa_export_key( handle,
4865 first_export, export_size,
4866 &first_exported_length ),
4867 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004868
4869 /* Shutdown and restart */
4870 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004871 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004872
Darryl Greend49a4992018-06-18 17:27:26 +01004873 /* Check key slot still contains key data */
Gilles Peskine8817f612018-12-18 00:18:46 +01004874 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
4875 &handle ) );
4876 PSA_ASSERT( psa_get_key_information(
4877 handle, &type_get, &bits_get ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004878 TEST_EQUAL( type_get, type );
4879 TEST_EQUAL( bits_get, (size_t) bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004880
Gilles Peskine8817f612018-12-18 00:18:46 +01004881 PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004882 TEST_EQUAL( psa_key_policy_get_usage( &policy_get ), policy_usage );
4883 TEST_EQUAL( psa_key_policy_get_algorithm( &policy_get ), policy_alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004884
4885 /* Export the key again */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004886 TEST_EQUAL( psa_export_key( handle,
4887 second_export, export_size,
4888 &second_exported_length ),
4889 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004890
Darryl Green0c6575a2018-11-07 16:05:30 +00004891 if( export_status == PSA_SUCCESS )
4892 {
4893 ASSERT_COMPARE( first_export, first_exported_length,
4894 second_export, second_exported_length );
Darryl Greend49a4992018-06-18 17:27:26 +01004895
Darryl Green0c6575a2018-11-07 16:05:30 +00004896 switch( generation_method )
4897 {
4898 case IMPORT_KEY:
4899 ASSERT_COMPARE( data->x, data->len,
4900 first_export, first_exported_length );
4901 break;
4902 default:
4903 break;
4904 }
4905 }
4906
4907 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004908 if( ! exercise_key( handle, policy_usage, policy_alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004909 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004910
4911exit:
4912 mbedtls_free( first_export );
4913 mbedtls_free( second_export );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004914 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004915 mbedtls_psa_crypto_free();
4916}
4917/* END_CASE */