blob: 6aed64dd5a9ae6a0aa417b218a37e5ef031beadf [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 ) );
219 PSA_ASSERT( psa_import_key( handle, key_type, key_bytes, key_length ) );
220
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 ) );
253 PSA_ASSERT( psa_import_key( handle, key_type, key_bytes, key_length ) );
254
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;
Mohammad AboMokhadb9b232018-06-28 01:52:54 -0700349 psa_key_type_t type = PSA_KEY_TYPE_NONE;
Gilles Peskine818ca122018-06-20 18:16:48 +0200350 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
351 {
Gilles Peskine818ca122018-06-20 18:16:48 +0200352 size_t bits;
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100353 TEST_ASSERT( psa_get_key_information( handle, &type, &bits ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200354 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE( type );
355 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100356 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
357 handle, alg ) );
358 PSA_ASSERT( psa_cipher_set_iv( &operation,
359 iv, iv_length ) );
360 PSA_ASSERT( psa_cipher_update( &operation,
361 ciphertext, ciphertext_length,
362 decrypted, sizeof( decrypted ),
363 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200364 status = psa_cipher_finish( &operation,
365 decrypted + part_length,
366 sizeof( decrypted ) - part_length,
367 &part_length );
368 /* For a stream cipher, all inputs are valid. For a block cipher,
369 * if the input is some aribtrary data rather than an actual
370 ciphertext, a padding error is likely. */
Mohammad AboMokh65fa0b82018-06-28 02:14:00 -0700371 if( ( usage & PSA_KEY_USAGE_ENCRYPT ) ||
Mohammad AboMokhadb9b232018-06-28 01:52:54 -0700372 PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) == 1 )
Gilles Peskine8817f612018-12-18 00:18:46 +0100373 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200374 else
375 TEST_ASSERT( status == PSA_SUCCESS ||
376 status == PSA_ERROR_INVALID_PADDING );
377 }
378
379 return( 1 );
380
381exit:
382 psa_cipher_abort( &operation );
383 return( 0 );
384}
385
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100386static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200387 psa_key_usage_t usage,
388 psa_algorithm_t alg )
389{
390 unsigned char nonce[16] = {0};
391 size_t nonce_length = sizeof( nonce );
392 unsigned char plaintext[16] = "Hello, world...";
393 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
394 size_t ciphertext_length = sizeof( ciphertext );
395 size_t plaintext_length = sizeof( ciphertext );
396
397 if( usage & PSA_KEY_USAGE_ENCRYPT )
398 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100399 PSA_ASSERT( psa_aead_encrypt( handle, alg,
400 nonce, nonce_length,
401 NULL, 0,
402 plaintext, sizeof( plaintext ),
403 ciphertext, sizeof( ciphertext ),
404 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200405 }
406
407 if( usage & PSA_KEY_USAGE_DECRYPT )
408 {
409 psa_status_t verify_status =
410 ( usage & PSA_KEY_USAGE_ENCRYPT ?
411 PSA_SUCCESS :
412 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100413 TEST_EQUAL( psa_aead_decrypt( handle, alg,
414 nonce, nonce_length,
415 NULL, 0,
416 ciphertext, ciphertext_length,
417 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100418 &plaintext_length ),
419 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200420 }
421
422 return( 1 );
423
424exit:
425 return( 0 );
426}
427
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100428static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200429 psa_key_usage_t usage,
430 psa_algorithm_t alg )
431{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200432 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
433 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200434 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200435 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100436 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
437
438 /* If the policy allows signing with any hash, just pick one. */
439 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
440 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100441#if defined(KNOWN_SUPPORTED_HASH_ALG)
442 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
443 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100444#else
445 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100446 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100447#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100448 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200449
450 if( usage & PSA_KEY_USAGE_SIGN )
451 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200452 /* Some algorithms require the payload to have the size of
453 * the hash encoded in the algorithm. Use this input size
454 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200455 if( hash_alg != 0 )
456 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100457 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
458 payload, payload_length,
459 signature, sizeof( signature ),
460 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200461 }
462
463 if( usage & PSA_KEY_USAGE_VERIFY )
464 {
465 psa_status_t verify_status =
466 ( usage & PSA_KEY_USAGE_SIGN ?
467 PSA_SUCCESS :
468 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100469 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
470 payload, payload_length,
471 signature, signature_length ),
472 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200473 }
474
475 return( 1 );
476
477exit:
478 return( 0 );
479}
480
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100481static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200482 psa_key_usage_t usage,
483 psa_algorithm_t alg )
484{
485 unsigned char plaintext[256] = "Hello, world...";
486 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
487 size_t ciphertext_length = sizeof( ciphertext );
488 size_t plaintext_length = 16;
489
490 if( usage & PSA_KEY_USAGE_ENCRYPT )
491 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100492 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
493 plaintext, plaintext_length,
494 NULL, 0,
495 ciphertext, sizeof( ciphertext ),
496 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200497 }
498
499 if( usage & PSA_KEY_USAGE_DECRYPT )
500 {
501 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100502 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200503 ciphertext, ciphertext_length,
504 NULL, 0,
505 plaintext, sizeof( plaintext ),
506 &plaintext_length );
507 TEST_ASSERT( status == PSA_SUCCESS ||
508 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
509 ( status == PSA_ERROR_INVALID_ARGUMENT ||
510 status == PSA_ERROR_INVALID_PADDING ) ) );
511 }
512
513 return( 1 );
514
515exit:
516 return( 0 );
517}
Gilles Peskine02b75072018-07-01 22:31:34 +0200518
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100519static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200520 psa_key_usage_t usage,
521 psa_algorithm_t alg )
522{
523 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
524 unsigned char label[16] = "This is a label.";
525 size_t label_length = sizeof( label );
526 unsigned char seed[16] = "abcdefghijklmnop";
527 size_t seed_length = sizeof( seed );
528 unsigned char output[1];
529
530 if( usage & PSA_KEY_USAGE_DERIVE )
531 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100532 PSA_ASSERT( psa_key_derivation( &generator,
533 handle, alg,
534 label, label_length,
535 seed, seed_length,
536 sizeof( output ) ) );
537 PSA_ASSERT( psa_generator_read( &generator,
538 output,
539 sizeof( output ) ) );
540 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200541 }
542
543 return( 1 );
544
545exit:
546 return( 0 );
547}
548
Gilles Peskinec7998b72018-11-07 18:45:02 +0100549/* We need two keys to exercise key agreement. Exercise the
550 * private key against its own public key. */
551static psa_status_t key_agreement_with_self( psa_crypto_generator_t *generator,
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100552 psa_key_handle_t handle,
Gilles Peskinec7998b72018-11-07 18:45:02 +0100553 psa_algorithm_t alg )
554{
555 psa_key_type_t private_key_type;
556 psa_key_type_t public_key_type;
557 size_t key_bits;
558 uint8_t *public_key = NULL;
559 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200560 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinec7998b72018-11-07 18:45:02 +0100561 * psa_key_agreement fails. This isn't fully satisfactory, but it's
562 * good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200563 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100564
Gilles Peskine8817f612018-12-18 00:18:46 +0100565 PSA_ASSERT( psa_get_key_information( handle,
566 &private_key_type,
567 &key_bits ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100568 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
569 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
570 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100571 PSA_ASSERT( psa_export_public_key( handle,
572 public_key, public_key_length,
573 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100574
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100575 status = psa_key_agreement( generator, handle,
Gilles Peskinec7998b72018-11-07 18:45:02 +0100576 public_key, public_key_length,
577 alg );
578exit:
579 mbedtls_free( public_key );
580 return( status );
581}
582
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100583static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200584 psa_key_usage_t usage,
585 psa_algorithm_t alg )
586{
587 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200588 unsigned char output[1];
589 int ok = 0;
590
591 if( usage & PSA_KEY_USAGE_DERIVE )
592 {
593 /* We need two keys to exercise key agreement. Exercise the
594 * private key against its own public key. */
Gilles Peskine8817f612018-12-18 00:18:46 +0100595 PSA_ASSERT( key_agreement_with_self( &generator, handle, alg ) );
596 PSA_ASSERT( psa_generator_read( &generator,
597 output,
598 sizeof( output ) ) );
599 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200600 }
601 ok = 1;
602
603exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200604 return( ok );
605}
606
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200607static int is_oid_of_key_type( psa_key_type_t type,
608 const uint8_t *oid, size_t oid_length )
609{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200610 const uint8_t *expected_oid = NULL;
611 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200612#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200613 if( PSA_KEY_TYPE_IS_RSA( type ) )
614 {
615 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
616 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
617 }
618 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200619#endif /* MBEDTLS_RSA_C */
620#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200621 if( PSA_KEY_TYPE_IS_ECC( type ) )
622 {
623 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
624 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
625 }
626 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200627#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200628 {
629 char message[40];
630 mbedtls_snprintf( message, sizeof( message ),
631 "OID not known for key type=0x%08lx",
632 (unsigned long) type );
633 test_fail( message, __LINE__, __FILE__ );
634 return( 0 );
635 }
636
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200637 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200638 return( 1 );
639
640exit:
641 return( 0 );
642}
643
644static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
645 size_t min_bits, size_t max_bits,
646 int must_be_odd )
647{
648 size_t len;
649 size_t actual_bits;
650 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100651 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100652 MBEDTLS_ASN1_INTEGER ),
653 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200654 /* Tolerate a slight departure from DER encoding:
655 * - 0 may be represented by an empty string or a 1-byte string.
656 * - The sign bit may be used as a value bit. */
657 if( ( len == 1 && ( *p )[0] == 0 ) ||
658 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
659 {
660 ++( *p );
661 --len;
662 }
663 if( min_bits == 0 && len == 0 )
664 return( 1 );
665 msb = ( *p )[0];
666 TEST_ASSERT( msb != 0 );
667 actual_bits = 8 * ( len - 1 );
668 while( msb != 0 )
669 {
670 msb >>= 1;
671 ++actual_bits;
672 }
673 TEST_ASSERT( actual_bits >= min_bits );
674 TEST_ASSERT( actual_bits <= max_bits );
675 if( must_be_odd )
676 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
677 *p += len;
678 return( 1 );
679exit:
680 return( 0 );
681}
682
683static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
684 size_t *len,
685 unsigned char n, unsigned char tag )
686{
687 int ret;
688 ret = mbedtls_asn1_get_tag( p, end, len,
689 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
690 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
691 if( ret != 0 )
692 return( ret );
693 end = *p + *len;
694 ret = mbedtls_asn1_get_tag( p, end, len, tag );
695 if( ret != 0 )
696 return( ret );
697 if( *p + *len != end )
698 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
699 return( 0 );
700}
701
702static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
703 uint8_t *exported, size_t exported_length )
704{
705 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100706 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200707 else
708 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200709
710#if defined(MBEDTLS_DES_C)
711 if( type == PSA_KEY_TYPE_DES )
712 {
713 /* Check the parity bits. */
714 unsigned i;
715 for( i = 0; i < bits / 8; i++ )
716 {
717 unsigned bit_count = 0;
718 unsigned m;
719 for( m = 1; m <= 0x100; m <<= 1 )
720 {
721 if( exported[i] & m )
722 ++bit_count;
723 }
724 TEST_ASSERT( bit_count % 2 != 0 );
725 }
726 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200727 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200728#endif
729
730#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
731 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
732 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200733 uint8_t *p = exported;
734 uint8_t *end = exported + exported_length;
735 size_t len;
736 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200737 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200738 * modulus INTEGER, -- n
739 * publicExponent INTEGER, -- e
740 * privateExponent INTEGER, -- d
741 * prime1 INTEGER, -- p
742 * prime2 INTEGER, -- q
743 * exponent1 INTEGER, -- d mod (p-1)
744 * exponent2 INTEGER, -- d mod (q-1)
745 * coefficient INTEGER, -- (inverse of q) mod p
746 * }
747 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100748 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
749 MBEDTLS_ASN1_SEQUENCE |
750 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
751 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200752 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
753 goto exit;
754 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
755 goto exit;
756 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
757 goto exit;
758 /* Require d to be at least half the size of n. */
759 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
760 goto exit;
761 /* Require p and q to be at most half the size of n, rounded up. */
762 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
763 goto exit;
764 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
765 goto exit;
766 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
767 goto exit;
768 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
769 goto exit;
770 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
771 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100772 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100773 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200774 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200775#endif /* MBEDTLS_RSA_C */
776
777#if defined(MBEDTLS_ECP_C)
778 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
779 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100780 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100781 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100782 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200783 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200784#endif /* MBEDTLS_ECP_C */
785
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200786 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
787 {
788 uint8_t *p = exported;
789 uint8_t *end = exported + exported_length;
790 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200791#if defined(MBEDTLS_RSA_C)
792 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
793 {
794 /* RSAPublicKey ::= SEQUENCE {
795 * modulus INTEGER, -- n
796 * publicExponent INTEGER } -- e
797 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100798 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
799 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100800 MBEDTLS_ASN1_CONSTRUCTED ),
801 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100802 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200803 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
804 goto exit;
805 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
806 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100807 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200808 }
809 else
810#endif /* MBEDTLS_RSA_C */
811#if defined(MBEDTLS_ECP_C)
812 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
813 {
Jaeden Ameroccdce902019-01-10 11:42:27 +0000814 /* The representation of an ECC public key is:
815 * - The byte 0x04;
816 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
817 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
818 * - where m is the bit size associated with the curve.
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200819 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100820 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
821 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200822 }
823 else
824#endif /* MBEDTLS_ECP_C */
825 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100826 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200827 mbedtls_snprintf( message, sizeof( message ),
828 "No sanity check for public key type=0x%08lx",
829 (unsigned long) type );
830 test_fail( message, __LINE__, __FILE__ );
831 return( 0 );
832 }
833 }
834 else
835
836 {
837 /* No sanity checks for other types */
838 }
839
840 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200841
842exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200843 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200844}
845
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100846static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200847 psa_key_usage_t usage )
848{
849 psa_key_type_t type;
850 size_t bits;
851 uint8_t *exported = NULL;
852 size_t exported_size = 0;
853 size_t exported_length = 0;
854 int ok = 0;
855
Gilles Peskine8817f612018-12-18 00:18:46 +0100856 PSA_ASSERT( psa_get_key_information( handle, &type, &bits ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200857
858 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
859 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200860 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100861 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
862 PSA_ERROR_NOT_PERMITTED );
Gilles Peskined14664a2018-08-10 19:07:32 +0200863 return( 1 );
864 }
865
Gilles Peskined14664a2018-08-10 19:07:32 +0200866 exported_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200867 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200868
Gilles Peskine8817f612018-12-18 00:18:46 +0100869 PSA_ASSERT( psa_export_key( handle,
870 exported, exported_size,
871 &exported_length ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200872 ok = exported_key_sanity_check( type, bits, exported, exported_length );
873
874exit:
875 mbedtls_free( exported );
876 return( ok );
877}
878
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100879static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200880{
881 psa_key_type_t type;
882 psa_key_type_t public_type;
883 size_t bits;
884 uint8_t *exported = NULL;
885 size_t exported_size = 0;
886 size_t exported_length = 0;
887 int ok = 0;
888
Gilles Peskine8817f612018-12-18 00:18:46 +0100889 PSA_ASSERT( psa_get_key_information( handle, &type, &bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200890 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( type ) )
891 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100892 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100893 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200894 return( 1 );
895 }
896
897 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
898 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type, bits );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200899 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200900
Gilles Peskine8817f612018-12-18 00:18:46 +0100901 PSA_ASSERT( psa_export_public_key( handle,
902 exported, exported_size,
903 &exported_length ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200904 ok = exported_key_sanity_check( public_type, bits,
905 exported, exported_length );
906
907exit:
908 mbedtls_free( exported );
909 return( ok );
910}
911
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100912/** Do smoke tests on a key.
913 *
914 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
915 * sign/verify, or derivation) that is permitted according to \p usage.
916 * \p usage and \p alg should correspond to the expected policy on the
917 * key.
918 *
919 * Export the key if permitted by \p usage, and check that the output
920 * looks sensible. If \p usage forbids export, check that
921 * \p psa_export_key correctly rejects the attempt. If the key is
922 * asymmetric, also check \p psa_export_public_key.
923 *
924 * If the key fails the tests, this function calls the test framework's
925 * `test_fail` function and returns false. Otherwise this function returns
926 * true. Therefore it should be used as follows:
927 * ```
928 * if( ! exercise_key( ... ) ) goto exit;
929 * ```
930 *
931 * \param handle The key to exercise. It should be capable of performing
932 * \p alg.
933 * \param usage The usage flags to assume.
934 * \param alg The algorithm to exercise.
935 *
936 * \retval 0 The key failed the smoke tests.
937 * \retval 1 The key passed the smoke tests.
938 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100939static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +0200940 psa_key_usage_t usage,
941 psa_algorithm_t alg )
942{
943 int ok;
944 if( alg == 0 )
945 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
946 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100947 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200948 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100949 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200950 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100951 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200952 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100953 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200954 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100955 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200956 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100957 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200958 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100959 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +0200960 else
961 {
962 char message[40];
963 mbedtls_snprintf( message, sizeof( message ),
964 "No code to exercise alg=0x%08lx",
965 (unsigned long) alg );
966 test_fail( message, __LINE__, __FILE__ );
967 ok = 0;
968 }
Gilles Peskined14664a2018-08-10 19:07:32 +0200969
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100970 ok = ok && exercise_export_key( handle, usage );
971 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +0200972
Gilles Peskine02b75072018-07-01 22:31:34 +0200973 return( ok );
974}
975
Gilles Peskine10df3412018-10-25 22:35:43 +0200976static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
977 psa_algorithm_t alg )
978{
979 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
980 {
981 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
982 PSA_KEY_USAGE_VERIFY :
983 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
984 }
985 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
986 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
987 {
988 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
989 PSA_KEY_USAGE_ENCRYPT :
990 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
991 }
992 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
993 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
994 {
995 return( PSA_KEY_USAGE_DERIVE );
996 }
997 else
998 {
999 return( 0 );
1000 }
1001
1002}
Darryl Green0c6575a2018-11-07 16:05:30 +00001003
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001004/* An overapproximation of the amount of storage needed for a key of the
1005 * given type and with the given content. The API doesn't make it easy
1006 * to find a good value for the size. The current implementation doesn't
1007 * care about the value anyway. */
1008#define KEY_BITS_FROM_DATA( type, data ) \
1009 ( data )->len
1010
Darryl Green0c6575a2018-11-07 16:05:30 +00001011typedef enum {
1012 IMPORT_KEY = 0,
1013 GENERATE_KEY = 1,
1014 DERIVE_KEY = 2
1015} generate_method;
1016
Gilles Peskinee59236f2018-01-27 23:32:46 +01001017/* END_HEADER */
1018
1019/* BEGIN_DEPENDENCIES
1020 * depends_on:MBEDTLS_PSA_CRYPTO_C
1021 * END_DEPENDENCIES
1022 */
1023
1024/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001025void static_checks( )
1026{
1027 size_t max_truncated_mac_size =
1028 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1029
1030 /* Check that the length for a truncated MAC always fits in the algorithm
1031 * encoding. The shifted mask is the maximum truncated value. The
1032 * untruncated algorithm may be one byte larger. */
1033 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1034}
1035/* END_CASE */
1036
1037/* BEGIN_CASE */
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001038void import( data_t *data, int type, int expected_status_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001039{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001040 psa_key_handle_t handle = 0;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001041 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001042 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001043
Gilles Peskine8817f612018-12-18 00:18:46 +01001044 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001045
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001046 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001047 status = psa_import_key( handle, type, data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001048 TEST_EQUAL( status, expected_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001049 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001050 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001051
1052exit:
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001053 mbedtls_psa_crypto_free( );
1054}
1055/* END_CASE */
1056
1057/* BEGIN_CASE */
Gilles Peskineca5bed72019-05-13 11:29:51 +02001058void import_twice( int usage_arg, int alg_arg,
Gilles Peskinea4261682018-12-03 11:34:01 +01001059 int type1_arg, data_t *data1,
1060 int expected_import1_status_arg,
1061 int type2_arg, data_t *data2,
1062 int expected_import2_status_arg )
1063{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001064 psa_key_handle_t handle = 0;
Gilles Peskinea4261682018-12-03 11:34:01 +01001065 psa_algorithm_t alg = alg_arg;
1066 psa_key_usage_t usage = usage_arg;
1067 psa_key_type_t type1 = type1_arg;
1068 psa_status_t expected_import1_status = expected_import1_status_arg;
1069 psa_key_type_t type2 = type2_arg;
1070 psa_status_t expected_import2_status = expected_import2_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00001071 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea4261682018-12-03 11:34:01 +01001072 psa_status_t status;
1073
Gilles Peskine8817f612018-12-18 00:18:46 +01001074 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea4261682018-12-03 11:34:01 +01001075
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001076 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea4261682018-12-03 11:34:01 +01001077 psa_key_policy_set_usage( &policy, usage, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001078 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea4261682018-12-03 11:34:01 +01001079
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001080 status = psa_import_key( handle, type1, data1->x, data1->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001081 TEST_EQUAL( status, expected_import1_status );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001082 status = psa_import_key( handle, type2, data2->x, data2->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001083 TEST_EQUAL( status, expected_import2_status );
Gilles Peskinea4261682018-12-03 11:34:01 +01001084
1085 if( expected_import1_status == PSA_SUCCESS ||
1086 expected_import2_status == PSA_SUCCESS )
1087 {
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001088 if( ! exercise_key( handle, usage, alg ) )
1089 goto exit;
Gilles Peskinea4261682018-12-03 11:34:01 +01001090 }
1091
1092exit:
1093 mbedtls_psa_crypto_free( );
1094}
1095/* END_CASE */
1096
1097/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001098void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1099{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001100 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001101 size_t bits = bits_arg;
1102 psa_status_t expected_status = expected_status_arg;
1103 psa_status_t status;
1104 psa_key_type_t type =
1105 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1106 size_t buffer_size = /* Slight overapproximations */
1107 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001108 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001109 unsigned char *p;
1110 int ret;
1111 size_t length;
1112
Gilles Peskine8817f612018-12-18 00:18:46 +01001113 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001114 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001115
1116 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1117 bits, keypair ) ) >= 0 );
1118 length = ret;
1119
1120 /* Try importing the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001121 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001122 status = psa_import_key( handle, type, p, length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001123 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001124 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001125 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001126
1127exit:
1128 mbedtls_free( buffer );
1129 mbedtls_psa_crypto_free( );
1130}
1131/* END_CASE */
1132
1133/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001134void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001135 int type_arg,
Gilles Peskineca5bed72019-05-13 11:29:51 +02001136 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001137 int expected_bits,
1138 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001139 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001140 int canonical_input )
1141{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001142 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001143 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001144 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001145 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001146 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001147 unsigned char *exported = NULL;
1148 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001149 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001150 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001151 size_t reexported_length;
1152 psa_key_type_t got_type;
1153 size_t got_bits;
Jaeden Amero70261c52019-01-04 11:47:20 +00001154 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001155
Moran Pekercb088e72018-07-17 17:36:59 +03001156 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001157 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001158 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001159 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001160 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001161
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001162 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02001163 psa_key_policy_set_usage( &policy, usage_arg, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001164 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001165
Gilles Peskinef812dcf2018-12-18 00:33:25 +01001166 TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
David Saadab4ecc272019-02-14 13:48:10 +02001167 PSA_ERROR_DOES_NOT_EXIST );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001168
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001169 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001170 PSA_ASSERT( psa_import_key( handle, type,
1171 data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001172
1173 /* Test the key information */
Gilles Peskine8817f612018-12-18 00:18:46 +01001174 PSA_ASSERT( psa_get_key_information( handle,
1175 &got_type,
1176 &got_bits ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001177 TEST_EQUAL( got_type, type );
1178 TEST_EQUAL( got_bits, (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001179
1180 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001181 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001182 exported, export_size,
1183 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001184 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001185
1186 /* The exported length must be set by psa_export_key() to a value between 0
1187 * and export_size. On errors, the exported length must be 0. */
1188 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1189 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1190 TEST_ASSERT( exported_length <= export_size );
1191
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001192 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001193 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001194 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001195 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001196 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001197 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001198 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001199
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001200 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001201 goto exit;
1202
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001203 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001204 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001205 else
1206 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001207 psa_key_handle_t handle2;
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001208 PSA_ASSERT( psa_allocate_key( &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001209 PSA_ASSERT( psa_set_key_policy( handle2, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001210
Gilles Peskine8817f612018-12-18 00:18:46 +01001211 PSA_ASSERT( psa_import_key( handle2, type,
1212 exported,
1213 exported_length ) );
1214 PSA_ASSERT( psa_export_key( handle2,
1215 reexported,
1216 export_size,
1217 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001218 ASSERT_COMPARE( exported, exported_length,
1219 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001220 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001221 }
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001222 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, got_bits ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001223
1224destroy:
1225 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001226 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01001227 TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
1228 PSA_ERROR_INVALID_HANDLE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001229
1230exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001231 mbedtls_free( exported );
1232 mbedtls_free( reexported );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001233 mbedtls_psa_crypto_free( );
1234}
1235/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001236
Moran Pekerf709f4a2018-06-06 17:26:04 +03001237/* BEGIN_CASE */
Moran Peker28a38e62018-11-07 16:18:24 +02001238void import_key_nonempty_slot( )
1239{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001240 psa_key_handle_t handle = 0;
Moran Peker28a38e62018-11-07 16:18:24 +02001241 psa_key_type_t type = PSA_KEY_TYPE_RAW_DATA;
1242 psa_status_t status;
1243 const uint8_t data[] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
Gilles Peskine8817f612018-12-18 00:18:46 +01001244 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker28a38e62018-11-07 16:18:24 +02001245
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001246 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001247
Moran Peker28a38e62018-11-07 16:18:24 +02001248 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001249 PSA_ASSERT( psa_import_key( handle, type,
1250 data, sizeof( data ) ) );
Moran Peker28a38e62018-11-07 16:18:24 +02001251
1252 /* Import the key again */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001253 status = psa_import_key( handle, type, data, sizeof( data ) );
David Saadab4ecc272019-02-14 13:48:10 +02001254 TEST_EQUAL( status, PSA_ERROR_ALREADY_EXISTS );
Moran Peker28a38e62018-11-07 16:18:24 +02001255
1256exit:
1257 mbedtls_psa_crypto_free( );
1258}
1259/* END_CASE */
1260
1261/* BEGIN_CASE */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001262void export_invalid_handle( int handle, int expected_export_status_arg )
Moran Peker28a38e62018-11-07 16:18:24 +02001263{
1264 psa_status_t status;
1265 unsigned char *exported = NULL;
1266 size_t export_size = 0;
1267 size_t exported_length = INVALID_EXPORT_LENGTH;
1268 psa_status_t expected_export_status = expected_export_status_arg;
1269
Gilles Peskine8817f612018-12-18 00:18:46 +01001270 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker28a38e62018-11-07 16:18:24 +02001271
1272 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001273 status = psa_export_key( (psa_key_handle_t) handle,
Moran Peker28a38e62018-11-07 16:18:24 +02001274 exported, export_size,
1275 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001276 TEST_EQUAL( status, expected_export_status );
Moran Peker28a38e62018-11-07 16:18:24 +02001277
1278exit:
1279 mbedtls_psa_crypto_free( );
1280}
1281/* END_CASE */
1282
1283/* BEGIN_CASE */
Moran Peker34550092018-11-07 16:19:34 +02001284void export_with_no_key_activity( )
1285{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001286 psa_key_handle_t handle = 0;
Moran Peker34550092018-11-07 16:19:34 +02001287 psa_algorithm_t alg = PSA_ALG_CTR;
1288 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +00001289 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Peker34550092018-11-07 16:19:34 +02001290 unsigned char *exported = NULL;
1291 size_t export_size = 0;
1292 size_t exported_length = INVALID_EXPORT_LENGTH;
1293
Gilles Peskine8817f612018-12-18 00:18:46 +01001294 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker34550092018-11-07 16:19:34 +02001295
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001296 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Peker34550092018-11-07 16:19:34 +02001297 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001298 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Peker34550092018-11-07 16:19:34 +02001299
1300 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001301 status = psa_export_key( handle,
Moran Peker34550092018-11-07 16:19:34 +02001302 exported, export_size,
1303 &exported_length );
David Saadab4ecc272019-02-14 13:48:10 +02001304 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Peker34550092018-11-07 16:19:34 +02001305
1306exit:
1307 mbedtls_psa_crypto_free( );
1308}
1309/* END_CASE */
1310
1311/* BEGIN_CASE */
Moran Pekerce500072018-11-07 16:20:07 +02001312void cipher_with_no_key_activity( )
1313{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001314 psa_key_handle_t handle = 0;
Moran Pekerce500072018-11-07 16:20:07 +02001315 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +00001316 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001317 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Moran Pekerce500072018-11-07 16:20:07 +02001318 int exercise_alg = PSA_ALG_CTR;
1319
Gilles Peskine8817f612018-12-18 00:18:46 +01001320 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerce500072018-11-07 16:20:07 +02001321
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001322 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekerce500072018-11-07 16:20:07 +02001323 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, exercise_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001324 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekerce500072018-11-07 16:20:07 +02001325
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001326 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
David Saadab4ecc272019-02-14 13:48:10 +02001327 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Pekerce500072018-11-07 16:20:07 +02001328
1329exit:
1330 psa_cipher_abort( &operation );
1331 mbedtls_psa_crypto_free( );
1332}
1333/* END_CASE */
1334
1335/* BEGIN_CASE */
Moran Peker34550092018-11-07 16:19:34 +02001336void export_after_import_failure( data_t *data, int type_arg,
1337 int expected_import_status_arg )
1338{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001339 psa_key_handle_t handle = 0;
Moran Peker34550092018-11-07 16:19:34 +02001340 psa_key_type_t type = type_arg;
1341 psa_status_t status;
1342 unsigned char *exported = NULL;
1343 size_t export_size = 0;
1344 psa_status_t expected_import_status = expected_import_status_arg;
1345 size_t exported_length = INVALID_EXPORT_LENGTH;
1346
Gilles Peskine8817f612018-12-18 00:18:46 +01001347 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker34550092018-11-07 16:19:34 +02001348
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001349 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001350
Moran Peker34550092018-11-07 16:19:34 +02001351 /* Import the key - expect failure */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001352 status = psa_import_key( handle, type,
Gilles Peskine0f915f12018-12-17 23:35:42 +01001353 data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001354 TEST_EQUAL( status, expected_import_status );
Moran Peker34550092018-11-07 16:19:34 +02001355
1356 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001357 status = psa_export_key( handle,
Moran Peker34550092018-11-07 16:19:34 +02001358 exported, export_size,
1359 &exported_length );
David Saadab4ecc272019-02-14 13:48:10 +02001360 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Peker34550092018-11-07 16:19:34 +02001361
1362exit:
1363 mbedtls_psa_crypto_free( );
1364}
1365/* END_CASE */
1366
1367/* BEGIN_CASE */
Moran Pekerce500072018-11-07 16:20:07 +02001368void cipher_after_import_failure( data_t *data, int type_arg,
1369 int expected_import_status_arg )
1370{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001371 psa_key_handle_t handle = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001372 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Moran Pekerce500072018-11-07 16:20:07 +02001373 psa_key_type_t type = type_arg;
1374 psa_status_t status;
1375 psa_status_t expected_import_status = expected_import_status_arg;
1376 int exercise_alg = PSA_ALG_CTR;
1377
Gilles Peskine8817f612018-12-18 00:18:46 +01001378 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerce500072018-11-07 16:20:07 +02001379
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001380 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001381
Moran Pekerce500072018-11-07 16:20:07 +02001382 /* Import the key - expect failure */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001383 status = psa_import_key( handle, type,
Gilles Peskine0f915f12018-12-17 23:35:42 +01001384 data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001385 TEST_EQUAL( status, expected_import_status );
Moran Pekerce500072018-11-07 16:20:07 +02001386
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001387 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
David Saadab4ecc272019-02-14 13:48:10 +02001388 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Pekerce500072018-11-07 16:20:07 +02001389
1390exit:
1391 psa_cipher_abort( &operation );
1392 mbedtls_psa_crypto_free( );
1393}
1394/* END_CASE */
1395
1396/* BEGIN_CASE */
Moran Peker34550092018-11-07 16:19:34 +02001397void export_after_destroy_key( data_t *data, int type_arg )
1398{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001399 psa_key_handle_t handle = 0;
Moran Peker34550092018-11-07 16:19:34 +02001400 psa_key_type_t type = type_arg;
1401 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +00001402 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Peker34550092018-11-07 16:19:34 +02001403 psa_algorithm_t alg = PSA_ALG_CTR;
1404 unsigned char *exported = NULL;
1405 size_t export_size = 0;
1406 size_t exported_length = INVALID_EXPORT_LENGTH;
1407
Gilles Peskine8817f612018-12-18 00:18:46 +01001408 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker34550092018-11-07 16:19:34 +02001409
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001410 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Peker34550092018-11-07 16:19:34 +02001411 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001412 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Peker34550092018-11-07 16:19:34 +02001413 export_size = (ptrdiff_t) data->len;
1414 ASSERT_ALLOC( exported, export_size );
1415
1416 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001417 PSA_ASSERT( psa_import_key( handle, type,
1418 data->x, data->len ) );
Moran Peker34550092018-11-07 16:19:34 +02001419
Gilles Peskine8817f612018-12-18 00:18:46 +01001420 PSA_ASSERT( psa_export_key( handle, exported, export_size,
1421 &exported_length ) );
Moran Peker34550092018-11-07 16:19:34 +02001422
1423 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001424 PSA_ASSERT( psa_destroy_key( handle ) );
Moran Peker34550092018-11-07 16:19:34 +02001425
1426 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001427 status = psa_export_key( handle, exported, export_size,
Moran Peker34550092018-11-07 16:19:34 +02001428 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001429 TEST_EQUAL( status, PSA_ERROR_INVALID_HANDLE );
Moran Peker34550092018-11-07 16:19:34 +02001430
1431exit:
1432 mbedtls_free( exported );
1433 mbedtls_psa_crypto_free( );
1434}
1435/* END_CASE */
1436
1437/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001438void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001439 int type_arg,
1440 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001441 int export_size_delta,
1442 int expected_export_status_arg,
1443 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001444{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001445 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001446 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001447 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001448 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001449 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001450 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001451 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001452 size_t exported_length = INVALID_EXPORT_LENGTH;
Jaeden Amero70261c52019-01-04 11:47:20 +00001453 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001454
Gilles Peskine8817f612018-12-18 00:18:46 +01001455 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001456
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001457 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02001458 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001459 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001460
1461 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001462 PSA_ASSERT( psa_import_key( handle, type,
1463 data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001464
Gilles Peskine49c25912018-10-29 15:15:31 +01001465 /* Export the public key */
1466 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001467 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001468 exported, export_size,
1469 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001470 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001471 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001472 {
1473 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1474 size_t bits;
Gilles Peskine8817f612018-12-18 00:18:46 +01001475 PSA_ASSERT( psa_get_key_information( handle, NULL, &bits ) );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001476 TEST_ASSERT( expected_public_key->len <=
1477 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001478 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1479 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001480 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001481
1482exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001483 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001484 psa_destroy_key( handle );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001485 mbedtls_psa_crypto_free( );
1486}
1487/* END_CASE */
1488
Gilles Peskine20035e32018-02-03 22:44:14 +01001489/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001490void import_and_exercise_key( data_t *data,
1491 int type_arg,
1492 int bits_arg,
1493 int alg_arg )
1494{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001495 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001496 psa_key_type_t type = type_arg;
1497 size_t bits = bits_arg;
1498 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001499 psa_key_usage_t usage = usage_to_exercise( type, alg );
Jaeden Amero70261c52019-01-04 11:47:20 +00001500 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001501 psa_key_type_t got_type;
1502 size_t got_bits;
1503 psa_status_t status;
1504
Gilles Peskine8817f612018-12-18 00:18:46 +01001505 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001506
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001507 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001508 psa_key_policy_set_usage( &policy, usage, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001509 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001510
1511 /* Import the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001512 status = psa_import_key( handle, type, data->x, data->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01001513 PSA_ASSERT( status );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001514
1515 /* Test the key information */
Gilles Peskine8817f612018-12-18 00:18:46 +01001516 PSA_ASSERT( psa_get_key_information( handle,
1517 &got_type,
1518 &got_bits ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001519 TEST_EQUAL( got_type, type );
1520 TEST_EQUAL( got_bits, bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001521
1522 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001523 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001524 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001525
1526exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001527 psa_destroy_key( handle );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001528 mbedtls_psa_crypto_free( );
1529}
1530/* END_CASE */
1531
1532/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001533void key_policy( int usage_arg, int alg_arg )
1534{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001535 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001536 psa_algorithm_t alg = alg_arg;
1537 psa_key_usage_t usage = usage_arg;
1538 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1539 unsigned char key[32] = {0};
Jaeden Amero70261c52019-01-04 11:47:20 +00001540 psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT;
1541 psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001542
1543 memset( key, 0x2a, sizeof( key ) );
1544
Gilles Peskine8817f612018-12-18 00:18:46 +01001545 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001546
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001547 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001548 psa_key_policy_set_usage( &policy_set, usage, alg );
1549
Gilles Peskinefe11b722018-12-18 00:24:04 +01001550 TEST_EQUAL( psa_key_policy_get_usage( &policy_set ), usage );
1551 TEST_EQUAL( psa_key_policy_get_algorithm( &policy_set ), alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001552 PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001553
Gilles Peskine8817f612018-12-18 00:18:46 +01001554 PSA_ASSERT( psa_import_key( handle, key_type,
1555 key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001556
Gilles Peskine8817f612018-12-18 00:18:46 +01001557 PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001558
Gilles Peskinefe11b722018-12-18 00:24:04 +01001559 TEST_EQUAL( policy_get.usage, policy_set.usage );
1560 TEST_EQUAL( policy_get.alg, policy_set.alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001561
1562exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001563 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001564 mbedtls_psa_crypto_free( );
1565}
1566/* END_CASE */
1567
1568/* BEGIN_CASE */
Jaeden Amero70261c52019-01-04 11:47:20 +00001569void key_policy_init( )
1570{
1571 /* Test each valid way of initializing the object, except for `= {0}`, as
1572 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1573 * though it's OK by the C standard. We could test for this, but we'd need
1574 * to supress the Clang warning for the test. */
1575 psa_key_policy_t func = psa_key_policy_init( );
1576 psa_key_policy_t init = PSA_KEY_POLICY_INIT;
1577 psa_key_policy_t zero;
1578
1579 memset( &zero, 0, sizeof( zero ) );
1580
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001581 /* A default key policy should not permit any usage. */
1582 TEST_EQUAL( psa_key_policy_get_usage( &func ), 0 );
1583 TEST_EQUAL( psa_key_policy_get_usage( &init ), 0 );
1584 TEST_EQUAL( psa_key_policy_get_usage( &zero ), 0 );
1585
1586 /* A default key policy should not permit any algorithm. */
1587 TEST_EQUAL( psa_key_policy_get_algorithm( &func ), 0 );
1588 TEST_EQUAL( psa_key_policy_get_algorithm( &init ), 0 );
1589 TEST_EQUAL( psa_key_policy_get_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001590}
1591/* END_CASE */
1592
1593/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001594void mac_key_policy( int policy_usage,
1595 int policy_alg,
1596 int key_type,
1597 data_t *key_data,
1598 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001599{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001600 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001601 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001602 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001603 psa_status_t status;
1604 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001605
Gilles Peskine8817f612018-12-18 00:18:46 +01001606 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001607
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001608 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001609 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001610 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001611
Gilles Peskine8817f612018-12-18 00:18:46 +01001612 PSA_ASSERT( psa_import_key( handle, key_type,
1613 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001614
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001615 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001616 if( policy_alg == exercise_alg &&
1617 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001618 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001619 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001620 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001621 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001622
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001623 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001624 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001625 if( policy_alg == exercise_alg &&
1626 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001627 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001628 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001629 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001630
1631exit:
1632 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001633 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001634 mbedtls_psa_crypto_free( );
1635}
1636/* END_CASE */
1637
1638/* BEGIN_CASE */
1639void cipher_key_policy( int policy_usage,
1640 int policy_alg,
1641 int key_type,
1642 data_t *key_data,
1643 int exercise_alg )
1644{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001645 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001646 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001647 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001648 psa_status_t status;
1649
Gilles Peskine8817f612018-12-18 00:18:46 +01001650 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001651
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001652 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001653 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001654 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001655
Gilles Peskine8817f612018-12-18 00:18:46 +01001656 PSA_ASSERT( psa_import_key( handle, key_type,
1657 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001658
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001659 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001660 if( policy_alg == exercise_alg &&
1661 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001662 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001663 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001664 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001665 psa_cipher_abort( &operation );
1666
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001667 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001668 if( policy_alg == exercise_alg &&
1669 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001670 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001671 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001672 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001673
1674exit:
1675 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001676 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001677 mbedtls_psa_crypto_free( );
1678}
1679/* END_CASE */
1680
1681/* BEGIN_CASE */
1682void aead_key_policy( int policy_usage,
1683 int policy_alg,
1684 int key_type,
1685 data_t *key_data,
1686 int nonce_length_arg,
1687 int tag_length_arg,
1688 int exercise_alg )
1689{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001690 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001691 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001692 psa_status_t status;
1693 unsigned char nonce[16] = {0};
1694 size_t nonce_length = nonce_length_arg;
1695 unsigned char tag[16];
1696 size_t tag_length = tag_length_arg;
1697 size_t output_length;
1698
1699 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1700 TEST_ASSERT( tag_length <= sizeof( tag ) );
1701
Gilles Peskine8817f612018-12-18 00:18:46 +01001702 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001703
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001704 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001705 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001706 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001707
Gilles Peskine8817f612018-12-18 00:18:46 +01001708 PSA_ASSERT( psa_import_key( handle, key_type,
1709 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001710
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001711 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001712 nonce, nonce_length,
1713 NULL, 0,
1714 NULL, 0,
1715 tag, tag_length,
1716 &output_length );
1717 if( policy_alg == exercise_alg &&
1718 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001719 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001720 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001721 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001722
1723 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001724 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001725 nonce, nonce_length,
1726 NULL, 0,
1727 tag, tag_length,
1728 NULL, 0,
1729 &output_length );
1730 if( policy_alg == exercise_alg &&
1731 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001732 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001733 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001734 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001735
1736exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001737 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001738 mbedtls_psa_crypto_free( );
1739}
1740/* END_CASE */
1741
1742/* BEGIN_CASE */
1743void asymmetric_encryption_key_policy( int policy_usage,
1744 int policy_alg,
1745 int key_type,
1746 data_t *key_data,
1747 int exercise_alg )
1748{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001749 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001750 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751 psa_status_t status;
1752 size_t key_bits;
1753 size_t buffer_length;
1754 unsigned char *buffer = NULL;
1755 size_t output_length;
1756
Gilles Peskine8817f612018-12-18 00:18:46 +01001757 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001759 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001760 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001761 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001762
Gilles Peskine8817f612018-12-18 00:18:46 +01001763 PSA_ASSERT( psa_import_key( handle, key_type,
1764 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001765
Gilles Peskine8817f612018-12-18 00:18:46 +01001766 PSA_ASSERT( psa_get_key_information( handle,
1767 NULL,
1768 &key_bits ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001769 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1770 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001771 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001772
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001773 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001774 NULL, 0,
1775 NULL, 0,
1776 buffer, buffer_length,
1777 &output_length );
1778 if( policy_alg == exercise_alg &&
1779 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001780 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001781 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001782 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001783
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001784 if( buffer_length != 0 )
1785 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001786 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001787 buffer, buffer_length,
1788 NULL, 0,
1789 buffer, buffer_length,
1790 &output_length );
1791 if( policy_alg == exercise_alg &&
1792 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001793 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001794 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001795 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796
1797exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001798 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001799 mbedtls_psa_crypto_free( );
1800 mbedtls_free( buffer );
1801}
1802/* END_CASE */
1803
1804/* BEGIN_CASE */
1805void asymmetric_signature_key_policy( int policy_usage,
1806 int policy_alg,
1807 int key_type,
1808 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001809 int exercise_alg,
1810 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001811{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001812 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001813 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001814 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001815 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1816 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1817 * compatible with the policy and `payload_length_arg` is supposed to be
1818 * a valid input length to sign. If `payload_length_arg <= 0`,
1819 * `exercise_alg` is supposed to be forbidden by the policy. */
1820 int compatible_alg = payload_length_arg > 0;
1821 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001822 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1823 size_t signature_length;
1824
Gilles Peskine8817f612018-12-18 00:18:46 +01001825 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001826
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001827 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001828 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001829 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001830
Gilles Peskine8817f612018-12-18 00:18:46 +01001831 PSA_ASSERT( psa_import_key( handle, key_type,
1832 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001833
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001834 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001835 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001836 signature, sizeof( signature ),
1837 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001838 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001839 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001840 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001841 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001842
1843 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001844 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001845 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001846 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001847 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001848 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001849 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001850 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001851
1852exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001853 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001854 mbedtls_psa_crypto_free( );
1855}
1856/* END_CASE */
1857
1858/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001859void derive_key_policy( int policy_usage,
1860 int policy_alg,
1861 int key_type,
1862 data_t *key_data,
1863 int exercise_alg )
1864{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001865 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001866 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001867 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1868 psa_status_t status;
1869
Gilles Peskine8817f612018-12-18 00:18:46 +01001870 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001871
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001872 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001873 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001874 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001875
Gilles Peskine8817f612018-12-18 00:18:46 +01001876 PSA_ASSERT( psa_import_key( handle, key_type,
1877 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001878
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001879 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001880 exercise_alg,
1881 NULL, 0,
1882 NULL, 0,
1883 1 );
1884 if( policy_alg == exercise_alg &&
1885 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001886 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001887 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001888 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001889
1890exit:
1891 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001892 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001893 mbedtls_psa_crypto_free( );
1894}
1895/* END_CASE */
1896
1897/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001898void agreement_key_policy( int policy_usage,
1899 int policy_alg,
1900 int key_type_arg,
1901 data_t *key_data,
1902 int exercise_alg )
1903{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001904 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001905 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001906 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001907 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1908 psa_status_t status;
1909
Gilles Peskine8817f612018-12-18 00:18:46 +01001910 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001911
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001912 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001913 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001914 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001915
Gilles Peskine8817f612018-12-18 00:18:46 +01001916 PSA_ASSERT( psa_import_key( handle, key_type,
1917 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001918
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001919 status = key_agreement_with_self( &generator, handle, exercise_alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001920
Gilles Peskine01d718c2018-09-18 12:01:02 +02001921 if( policy_alg == exercise_alg &&
1922 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001923 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001924 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001925 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001926
1927exit:
1928 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001929 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001930 mbedtls_psa_crypto_free( );
1931}
1932/* END_CASE */
1933
1934/* BEGIN_CASE */
Gilles Peskined6f371b2019-05-10 19:33:38 +02001935void key_policy_alg2( int key_type_arg, data_t *key_data,
1936 int usage_arg, int alg_arg, int alg2_arg )
1937{
1938 psa_key_handle_t handle = 0;
1939 psa_key_type_t key_type = key_type_arg;
1940 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
1941 psa_key_policy_t got_policy = PSA_KEY_POLICY_INIT;
1942 psa_key_usage_t usage = usage_arg;
1943 psa_algorithm_t alg = alg_arg;
1944 psa_algorithm_t alg2 = alg2_arg;
1945
1946 PSA_ASSERT( psa_crypto_init( ) );
1947
1948 PSA_ASSERT( psa_allocate_key( &handle ) );
1949 psa_key_policy_set_usage( &policy, usage, alg );
1950 psa_key_policy_set_enrollment_algorithm( &policy, alg2 );
1951 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
1952 PSA_ASSERT( psa_import_key( handle, key_type,
1953 key_data->x, key_data->len ) );
1954
1955 PSA_ASSERT( psa_get_key_policy( handle, &got_policy ) );
1956 TEST_EQUAL( psa_key_policy_get_usage( &got_policy ), usage );
1957 TEST_EQUAL( psa_key_policy_get_algorithm( &got_policy ), alg );
1958 TEST_EQUAL( psa_key_policy_get_enrollment_algorithm( &got_policy ), alg2 );
1959
1960 if( ! exercise_key( handle, usage, alg ) )
1961 goto exit;
1962 if( ! exercise_key( handle, usage, alg2 ) )
1963 goto exit;
1964
1965exit:
1966 psa_destroy_key( handle );
1967 mbedtls_psa_crypto_free( );
1968}
1969/* END_CASE */
1970
1971/* BEGIN_CASE */
Gilles Peskine57ab7212019-01-28 13:03:09 +01001972void copy_key_policy( int source_usage_arg, int source_alg_arg,
1973 int type_arg, data_t *material,
1974 int target_usage_arg, int target_alg_arg,
1975 int constraint_usage_arg, int constraint_alg_arg,
1976 int expected_usage_arg, int expected_alg_arg )
1977{
1978 psa_key_usage_t source_usage = source_usage_arg;
1979 psa_algorithm_t source_alg = source_alg_arg;
1980 psa_key_handle_t source_handle = 0;
1981 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
1982 psa_key_type_t source_type = type_arg;
1983 size_t source_bits;
1984 psa_key_usage_t target_usage = target_usage_arg;
1985 psa_algorithm_t target_alg = target_alg_arg;
1986 psa_key_handle_t target_handle = 0;
1987 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
1988 psa_key_type_t target_type;
1989 size_t target_bits;
1990 psa_key_usage_t constraint_usage = constraint_usage_arg;
1991 psa_algorithm_t constraint_alg = constraint_alg_arg;
1992 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
1993 psa_key_policy_t *p_constraint = NULL;
1994 psa_key_usage_t expected_usage = expected_usage_arg;
1995 psa_algorithm_t expected_alg = expected_alg_arg;
1996 uint8_t *export_buffer = NULL;
1997
1998 if( constraint_usage_arg != -1 )
1999 {
2000 p_constraint = &constraint;
2001 psa_key_policy_set_usage( p_constraint,
2002 constraint_usage, constraint_alg );
2003 }
2004
2005 PSA_ASSERT( psa_crypto_init( ) );
2006
2007 /* Populate the source slot. */
2008 PSA_ASSERT( psa_allocate_key( &source_handle ) );
2009 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
2010 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
2011 PSA_ASSERT( psa_import_key( source_handle, source_type,
2012 material->x, material->len ) );
2013 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
2014
2015 /* Prepare the target slot. */
2016 PSA_ASSERT( psa_allocate_key( &target_handle ) );
2017 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
2018 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
2019 target_policy = psa_key_policy_init();
2020
2021 /* Copy the key. */
2022 PSA_ASSERT( psa_copy_key( source_handle, target_handle, p_constraint ) );
2023
2024 /* Destroy the source to ensure that this doesn't affect the target. */
2025 PSA_ASSERT( psa_destroy_key( source_handle ) );
2026
2027 /* Test that the target slot has the expected content and policy. */
2028 PSA_ASSERT( psa_get_key_information( target_handle,
2029 &target_type, &target_bits ) );
2030 TEST_EQUAL( source_type, target_type );
2031 TEST_EQUAL( source_bits, target_bits );
2032 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
2033 TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
2034 TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
2035 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2036 {
2037 size_t length;
2038 ASSERT_ALLOC( export_buffer, material->len );
2039 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2040 material->len, &length ) );
2041 ASSERT_COMPARE( material->x, material->len,
2042 export_buffer, length );
2043 }
2044 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2045 goto exit;
2046
2047 PSA_ASSERT( psa_close_key( target_handle ) );
2048
2049exit:
2050 mbedtls_psa_crypto_free( );
2051 mbedtls_free( export_buffer );
2052}
2053/* END_CASE */
2054
2055/* BEGIN_CASE */
2056void copy_fail( int source_usage_arg, int source_alg_arg,
2057 int type_arg, data_t *material,
2058 int target_usage_arg, int target_alg_arg,
2059 int constraint_usage_arg, int constraint_alg_arg,
2060 int expected_status_arg )
2061{
2062 /* Test copy failure into an empty slot. There is a test for copy failure
2063 * into an occupied slot in
2064 * test_suite_psa_crypto_slot_management.function. */
2065
2066 psa_key_usage_t source_usage = source_usage_arg;
2067 psa_algorithm_t source_alg = source_alg_arg;
2068 psa_key_handle_t source_handle = 0;
2069 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
2070 psa_key_type_t source_type = type_arg;
2071 size_t source_bits;
2072 psa_key_usage_t target_usage = target_usage_arg;
2073 psa_algorithm_t target_alg = target_alg_arg;
2074 psa_key_handle_t target_handle = 0;
2075 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
2076 psa_key_type_t target_type;
2077 size_t target_bits;
2078 psa_key_usage_t constraint_usage = constraint_usage_arg;
2079 psa_algorithm_t constraint_alg = constraint_alg_arg;
2080 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
2081 psa_key_policy_t *p_constraint = NULL;
2082 psa_status_t expected_status = expected_status_arg;
2083
2084 if( constraint_usage_arg != -1 )
2085 {
2086 p_constraint = &constraint;
2087 psa_key_policy_set_usage( p_constraint,
2088 constraint_usage, constraint_alg );
2089 }
2090
2091 PSA_ASSERT( psa_crypto_init( ) );
2092
2093 /* Populate the source slot. */
2094 PSA_ASSERT( psa_allocate_key( &source_handle ) );
2095 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
2096 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
2097 PSA_ASSERT( psa_import_key( source_handle, source_type,
2098 material->x, material->len ) );
2099 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
2100
2101 /* Prepare the target slot. */
2102 PSA_ASSERT( psa_allocate_key( &target_handle ) );
2103 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
2104 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
2105 target_policy = psa_key_policy_init();
2106
2107 /* Copy the key. */
2108 TEST_EQUAL( psa_copy_key( source_handle, target_handle, p_constraint ),
2109 expected_status );
2110
2111 /* Test that the target slot is unaffected. */
2112 TEST_EQUAL( psa_get_key_information( target_handle,
2113 &target_type, &target_bits ),
David Saadab4ecc272019-02-14 13:48:10 +02002114 PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002115 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
2116 TEST_EQUAL( target_usage, psa_key_policy_get_usage( &target_policy ) );
2117 TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &target_policy ) );
2118
2119exit:
2120 mbedtls_psa_crypto_free( );
2121}
2122/* END_CASE */
2123
2124/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002125void hash_operation_init( )
2126{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002127 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002128 /* Test each valid way of initializing the object, except for `= {0}`, as
2129 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2130 * though it's OK by the C standard. We could test for this, but we'd need
2131 * to supress the Clang warning for the test. */
2132 psa_hash_operation_t func = psa_hash_operation_init( );
2133 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2134 psa_hash_operation_t zero;
2135
2136 memset( &zero, 0, sizeof( zero ) );
2137
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002138 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002139 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2140 PSA_ERROR_BAD_STATE );
2141 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2142 PSA_ERROR_BAD_STATE );
2143 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2144 PSA_ERROR_BAD_STATE );
2145
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002146 /* A default hash operation should be abortable without error. */
2147 PSA_ASSERT( psa_hash_abort( &func ) );
2148 PSA_ASSERT( psa_hash_abort( &init ) );
2149 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002150}
2151/* END_CASE */
2152
2153/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002154void hash_setup( int alg_arg,
2155 int expected_status_arg )
2156{
2157 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002158 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002159 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002160 psa_status_t status;
2161
Gilles Peskine8817f612018-12-18 00:18:46 +01002162 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002163
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002164 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002165 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002166
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002167 /* Whether setup succeeded or failed, abort must succeed. */
2168 PSA_ASSERT( psa_hash_abort( &operation ) );
2169
2170 /* If setup failed, reproduce the failure, so as to
2171 * test the resulting state of the operation object. */
2172 if( status != PSA_SUCCESS )
2173 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2174
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002175 /* Now the operation object should be reusable. */
2176#if defined(KNOWN_SUPPORTED_HASH_ALG)
2177 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2178 PSA_ASSERT( psa_hash_abort( &operation ) );
2179#endif
2180
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002181exit:
2182 mbedtls_psa_crypto_free( );
2183}
2184/* END_CASE */
2185
2186/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002187void hash_bad_order( )
2188{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002189 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002190 unsigned char input[] = "";
2191 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002192 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002193 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2194 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2195 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002196 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002197 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002198 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002199
Gilles Peskine8817f612018-12-18 00:18:46 +01002200 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002201
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002202 /* Call setup twice in a row. */
2203 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2204 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2205 PSA_ERROR_BAD_STATE );
2206 PSA_ASSERT( psa_hash_abort( &operation ) );
2207
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002208 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002209 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002210 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002211 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002212
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002213 /* Call update after finish. */
2214 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2215 PSA_ASSERT( psa_hash_finish( &operation,
2216 hash, sizeof( hash ), &hash_len ) );
2217 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002218 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002219 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002220
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002221 /* Call verify without calling setup beforehand. */
2222 TEST_EQUAL( psa_hash_verify( &operation,
2223 valid_hash, sizeof( valid_hash ) ),
2224 PSA_ERROR_BAD_STATE );
2225 PSA_ASSERT( psa_hash_abort( &operation ) );
2226
2227 /* Call verify after finish. */
2228 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2229 PSA_ASSERT( psa_hash_finish( &operation,
2230 hash, sizeof( hash ), &hash_len ) );
2231 TEST_EQUAL( psa_hash_verify( &operation,
2232 valid_hash, sizeof( valid_hash ) ),
2233 PSA_ERROR_BAD_STATE );
2234 PSA_ASSERT( psa_hash_abort( &operation ) );
2235
2236 /* Call verify twice in a row. */
2237 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2238 PSA_ASSERT( psa_hash_verify( &operation,
2239 valid_hash, sizeof( valid_hash ) ) );
2240 TEST_EQUAL( psa_hash_verify( &operation,
2241 valid_hash, sizeof( valid_hash ) ),
2242 PSA_ERROR_BAD_STATE );
2243 PSA_ASSERT( psa_hash_abort( &operation ) );
2244
2245 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002246 TEST_EQUAL( psa_hash_finish( &operation,
2247 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002248 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002249 PSA_ASSERT( psa_hash_abort( &operation ) );
2250
2251 /* Call finish twice in a row. */
2252 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2253 PSA_ASSERT( psa_hash_finish( &operation,
2254 hash, sizeof( hash ), &hash_len ) );
2255 TEST_EQUAL( psa_hash_finish( &operation,
2256 hash, sizeof( hash ), &hash_len ),
2257 PSA_ERROR_BAD_STATE );
2258 PSA_ASSERT( psa_hash_abort( &operation ) );
2259
2260 /* Call finish after calling verify. */
2261 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2262 PSA_ASSERT( psa_hash_verify( &operation,
2263 valid_hash, sizeof( valid_hash ) ) );
2264 TEST_EQUAL( psa_hash_finish( &operation,
2265 hash, sizeof( hash ), &hash_len ),
2266 PSA_ERROR_BAD_STATE );
2267 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002268
2269exit:
2270 mbedtls_psa_crypto_free( );
2271}
2272/* END_CASE */
2273
itayzafrir27e69452018-11-01 14:26:34 +02002274/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2275void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002276{
2277 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002278 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2279 * appended to it */
2280 unsigned char hash[] = {
2281 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2282 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2283 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002284 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002285 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002286
Gilles Peskine8817f612018-12-18 00:18:46 +01002287 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002288
itayzafrir27e69452018-11-01 14:26:34 +02002289 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002290 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002291 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002292 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002293
itayzafrir27e69452018-11-01 14:26:34 +02002294 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002295 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002296 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002297 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002298
itayzafrir27e69452018-11-01 14:26:34 +02002299 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002300 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002301 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002302 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002303
itayzafrirec93d302018-10-18 18:01:10 +03002304exit:
2305 mbedtls_psa_crypto_free( );
2306}
2307/* END_CASE */
2308
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002309/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2310void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002311{
2312 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002313 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002314 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002315 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002316 size_t hash_len;
2317
Gilles Peskine8817f612018-12-18 00:18:46 +01002318 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002319
itayzafrir58028322018-10-25 10:22:01 +03002320 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002321 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002322 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002323 hash, expected_size - 1, &hash_len ),
2324 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002325
2326exit:
2327 mbedtls_psa_crypto_free( );
2328}
2329/* END_CASE */
2330
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002331/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2332void hash_clone_source_state( )
2333{
2334 psa_algorithm_t alg = PSA_ALG_SHA_256;
2335 unsigned char hash[PSA_HASH_MAX_SIZE];
2336 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2337 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2338 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2339 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2340 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2341 size_t hash_len;
2342
2343 PSA_ASSERT( psa_crypto_init( ) );
2344 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2345
2346 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2347 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2348 PSA_ASSERT( psa_hash_finish( &op_finished,
2349 hash, sizeof( hash ), &hash_len ) );
2350 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2351 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2352
2353 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2354 PSA_ERROR_BAD_STATE );
2355
2356 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2357 PSA_ASSERT( psa_hash_finish( &op_init,
2358 hash, sizeof( hash ), &hash_len ) );
2359 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2360 PSA_ASSERT( psa_hash_finish( &op_finished,
2361 hash, sizeof( hash ), &hash_len ) );
2362 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2363 PSA_ASSERT( psa_hash_finish( &op_aborted,
2364 hash, sizeof( hash ), &hash_len ) );
2365
2366exit:
2367 psa_hash_abort( &op_source );
2368 psa_hash_abort( &op_init );
2369 psa_hash_abort( &op_setup );
2370 psa_hash_abort( &op_finished );
2371 psa_hash_abort( &op_aborted );
2372 mbedtls_psa_crypto_free( );
2373}
2374/* END_CASE */
2375
2376/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2377void hash_clone_target_state( )
2378{
2379 psa_algorithm_t alg = PSA_ALG_SHA_256;
2380 unsigned char hash[PSA_HASH_MAX_SIZE];
2381 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2382 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2383 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2384 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2385 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2386 size_t hash_len;
2387
2388 PSA_ASSERT( psa_crypto_init( ) );
2389
2390 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2391 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2392 PSA_ASSERT( psa_hash_finish( &op_finished,
2393 hash, sizeof( hash ), &hash_len ) );
2394 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2395 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2396
2397 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2398 PSA_ASSERT( psa_hash_finish( &op_target,
2399 hash, sizeof( hash ), &hash_len ) );
2400
2401 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2402 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2403 PSA_ERROR_BAD_STATE );
2404 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2405 PSA_ERROR_BAD_STATE );
2406
2407exit:
2408 psa_hash_abort( &op_target );
2409 psa_hash_abort( &op_init );
2410 psa_hash_abort( &op_setup );
2411 psa_hash_abort( &op_finished );
2412 psa_hash_abort( &op_aborted );
2413 mbedtls_psa_crypto_free( );
2414}
2415/* END_CASE */
2416
itayzafrir58028322018-10-25 10:22:01 +03002417/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002418void mac_operation_init( )
2419{
Jaeden Amero252ef282019-02-15 14:05:35 +00002420 const uint8_t input[1] = { 0 };
2421
Jaeden Amero769ce272019-01-04 11:48:03 +00002422 /* Test each valid way of initializing the object, except for `= {0}`, as
2423 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2424 * though it's OK by the C standard. We could test for this, but we'd need
2425 * to supress the Clang warning for the test. */
2426 psa_mac_operation_t func = psa_mac_operation_init( );
2427 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2428 psa_mac_operation_t zero;
2429
2430 memset( &zero, 0, sizeof( zero ) );
2431
Jaeden Amero252ef282019-02-15 14:05:35 +00002432 /* A freshly-initialized MAC operation should not be usable. */
2433 TEST_EQUAL( psa_mac_update( &func,
2434 input, sizeof( input ) ),
2435 PSA_ERROR_BAD_STATE );
2436 TEST_EQUAL( psa_mac_update( &init,
2437 input, sizeof( input ) ),
2438 PSA_ERROR_BAD_STATE );
2439 TEST_EQUAL( psa_mac_update( &zero,
2440 input, sizeof( input ) ),
2441 PSA_ERROR_BAD_STATE );
2442
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002443 /* A default MAC operation should be abortable without error. */
2444 PSA_ASSERT( psa_mac_abort( &func ) );
2445 PSA_ASSERT( psa_mac_abort( &init ) );
2446 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002447}
2448/* END_CASE */
2449
2450/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002451void mac_setup( int key_type_arg,
2452 data_t *key,
2453 int alg_arg,
2454 int expected_status_arg )
2455{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002456 psa_key_type_t key_type = key_type_arg;
2457 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002458 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002459 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002460 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2461#if defined(KNOWN_SUPPORTED_MAC_ALG)
2462 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2463#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002464
Gilles Peskine8817f612018-12-18 00:18:46 +01002465 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002466
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002467 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2468 &operation, &status ) )
2469 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002470 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002471
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002472 /* The operation object should be reusable. */
2473#if defined(KNOWN_SUPPORTED_MAC_ALG)
2474 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2475 smoke_test_key_data,
2476 sizeof( smoke_test_key_data ),
2477 KNOWN_SUPPORTED_MAC_ALG,
2478 &operation, &status ) )
2479 goto exit;
2480 TEST_EQUAL( status, PSA_SUCCESS );
2481#endif
2482
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002483exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002484 mbedtls_psa_crypto_free( );
2485}
2486/* END_CASE */
2487
2488/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002489void mac_bad_order( )
2490{
2491 psa_key_handle_t handle = 0;
2492 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2493 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2494 const uint8_t key[] = {
2495 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2496 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2497 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
2498 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2499 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2500 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2501 size_t sign_mac_length = 0;
2502 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2503 const uint8_t verify_mac[] = {
2504 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2505 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2506 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2507
2508 PSA_ASSERT( psa_crypto_init( ) );
2509 PSA_ASSERT( psa_allocate_key( &handle ) );
2510 psa_key_policy_set_usage( &policy,
2511 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
2512 alg );
2513 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2514
2515 PSA_ASSERT( psa_import_key( handle, key_type,
2516 key, sizeof(key) ) );
2517
2518 /* Call update without calling setup beforehand. */
2519 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2520 PSA_ERROR_BAD_STATE );
2521 PSA_ASSERT( psa_mac_abort( &operation ) );
2522
2523 /* Call sign finish without calling setup beforehand. */
2524 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2525 &sign_mac_length),
2526 PSA_ERROR_BAD_STATE );
2527 PSA_ASSERT( psa_mac_abort( &operation ) );
2528
2529 /* Call verify finish without calling setup beforehand. */
2530 TEST_EQUAL( psa_mac_verify_finish( &operation,
2531 verify_mac, sizeof( verify_mac ) ),
2532 PSA_ERROR_BAD_STATE );
2533 PSA_ASSERT( psa_mac_abort( &operation ) );
2534
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002535 /* Call setup twice in a row. */
2536 PSA_ASSERT( psa_mac_sign_setup( &operation,
2537 handle, alg ) );
2538 TEST_EQUAL( psa_mac_sign_setup( &operation,
2539 handle, alg ),
2540 PSA_ERROR_BAD_STATE );
2541 PSA_ASSERT( psa_mac_abort( &operation ) );
2542
Jaeden Amero252ef282019-02-15 14:05:35 +00002543 /* Call update after sign finish. */
2544 PSA_ASSERT( psa_mac_sign_setup( &operation,
2545 handle, alg ) );
2546 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2547 PSA_ASSERT( psa_mac_sign_finish( &operation,
2548 sign_mac, sizeof( sign_mac ),
2549 &sign_mac_length ) );
2550 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2551 PSA_ERROR_BAD_STATE );
2552 PSA_ASSERT( psa_mac_abort( &operation ) );
2553
2554 /* Call update after verify finish. */
2555 PSA_ASSERT( psa_mac_verify_setup( &operation,
2556 handle, alg ) );
2557 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2558 PSA_ASSERT( psa_mac_verify_finish( &operation,
2559 verify_mac, sizeof( verify_mac ) ) );
2560 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2561 PSA_ERROR_BAD_STATE );
2562 PSA_ASSERT( psa_mac_abort( &operation ) );
2563
2564 /* Call sign finish twice in a row. */
2565 PSA_ASSERT( psa_mac_sign_setup( &operation,
2566 handle, alg ) );
2567 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2568 PSA_ASSERT( psa_mac_sign_finish( &operation,
2569 sign_mac, sizeof( sign_mac ),
2570 &sign_mac_length ) );
2571 TEST_EQUAL( psa_mac_sign_finish( &operation,
2572 sign_mac, sizeof( sign_mac ),
2573 &sign_mac_length ),
2574 PSA_ERROR_BAD_STATE );
2575 PSA_ASSERT( psa_mac_abort( &operation ) );
2576
2577 /* Call verify finish twice in a row. */
2578 PSA_ASSERT( psa_mac_verify_setup( &operation,
2579 handle, alg ) );
2580 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2581 PSA_ASSERT( psa_mac_verify_finish( &operation,
2582 verify_mac, sizeof( verify_mac ) ) );
2583 TEST_EQUAL( psa_mac_verify_finish( &operation,
2584 verify_mac, sizeof( verify_mac ) ),
2585 PSA_ERROR_BAD_STATE );
2586 PSA_ASSERT( psa_mac_abort( &operation ) );
2587
2588 /* Setup sign but try verify. */
2589 PSA_ASSERT( psa_mac_sign_setup( &operation,
2590 handle, alg ) );
2591 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2592 TEST_EQUAL( psa_mac_verify_finish( &operation,
2593 verify_mac, sizeof( verify_mac ) ),
2594 PSA_ERROR_BAD_STATE );
2595 PSA_ASSERT( psa_mac_abort( &operation ) );
2596
2597 /* Setup verify but try sign. */
2598 PSA_ASSERT( psa_mac_verify_setup( &operation,
2599 handle, alg ) );
2600 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2601 TEST_EQUAL( psa_mac_sign_finish( &operation,
2602 sign_mac, sizeof( sign_mac ),
2603 &sign_mac_length ),
2604 PSA_ERROR_BAD_STATE );
2605 PSA_ASSERT( psa_mac_abort( &operation ) );
2606
2607exit:
2608 mbedtls_psa_crypto_free( );
2609}
2610/* END_CASE */
2611
2612/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002613void mac_sign( int key_type_arg,
2614 data_t *key,
2615 int alg_arg,
2616 data_t *input,
2617 data_t *expected_mac )
2618{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002619 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002620 psa_key_type_t key_type = key_type_arg;
2621 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002622 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002623 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002624 /* Leave a little extra room in the output buffer. At the end of the
2625 * test, we'll check that the implementation didn't overwrite onto
2626 * this extra room. */
2627 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2628 size_t mac_buffer_size =
2629 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2630 size_t mac_length = 0;
2631
2632 memset( actual_mac, '+', sizeof( actual_mac ) );
2633 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2634 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2635
Gilles Peskine8817f612018-12-18 00:18:46 +01002636 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002637
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002638 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002639 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002640 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002641
Gilles Peskine8817f612018-12-18 00:18:46 +01002642 PSA_ASSERT( psa_import_key( handle, key_type,
2643 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002644
2645 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002646 PSA_ASSERT( psa_mac_sign_setup( &operation,
2647 handle, alg ) );
2648 PSA_ASSERT( psa_mac_update( &operation,
2649 input->x, input->len ) );
2650 PSA_ASSERT( psa_mac_sign_finish( &operation,
2651 actual_mac, mac_buffer_size,
2652 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002653
2654 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002655 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2656 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002657
2658 /* Verify that the end of the buffer is untouched. */
2659 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2660 sizeof( actual_mac ) - mac_length ) );
2661
2662exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002663 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002664 mbedtls_psa_crypto_free( );
2665}
2666/* END_CASE */
2667
2668/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002669void mac_verify( int key_type_arg,
2670 data_t *key,
2671 int alg_arg,
2672 data_t *input,
2673 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002674{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002675 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002676 psa_key_type_t key_type = key_type_arg;
2677 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002678 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002679 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002680
Gilles Peskine69c12672018-06-28 00:07:19 +02002681 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2682
Gilles Peskine8817f612018-12-18 00:18:46 +01002683 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002684
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002685 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002686 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002687 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad16036df908f2018-04-02 08:34:15 -07002688
Gilles Peskine8817f612018-12-18 00:18:46 +01002689 PSA_ASSERT( psa_import_key( handle, key_type,
2690 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002691
Gilles Peskine8817f612018-12-18 00:18:46 +01002692 PSA_ASSERT( psa_mac_verify_setup( &operation,
2693 handle, alg ) );
2694 PSA_ASSERT( psa_destroy_key( handle ) );
2695 PSA_ASSERT( psa_mac_update( &operation,
2696 input->x, input->len ) );
2697 PSA_ASSERT( psa_mac_verify_finish( &operation,
2698 expected_mac->x,
2699 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002700
2701exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002702 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002703 mbedtls_psa_crypto_free( );
2704}
2705/* END_CASE */
2706
2707/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002708void cipher_operation_init( )
2709{
Jaeden Ameroab439972019-02-15 14:12:05 +00002710 const uint8_t input[1] = { 0 };
2711 unsigned char output[1] = { 0 };
2712 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002713 /* Test each valid way of initializing the object, except for `= {0}`, as
2714 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2715 * though it's OK by the C standard. We could test for this, but we'd need
2716 * to supress the Clang warning for the test. */
2717 psa_cipher_operation_t func = psa_cipher_operation_init( );
2718 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2719 psa_cipher_operation_t zero;
2720
2721 memset( &zero, 0, sizeof( zero ) );
2722
Jaeden Ameroab439972019-02-15 14:12:05 +00002723 /* A freshly-initialized cipher operation should not be usable. */
2724 TEST_EQUAL( psa_cipher_update( &func,
2725 input, sizeof( input ),
2726 output, sizeof( output ),
2727 &output_length ),
2728 PSA_ERROR_BAD_STATE );
2729 TEST_EQUAL( psa_cipher_update( &init,
2730 input, sizeof( input ),
2731 output, sizeof( output ),
2732 &output_length ),
2733 PSA_ERROR_BAD_STATE );
2734 TEST_EQUAL( psa_cipher_update( &zero,
2735 input, sizeof( input ),
2736 output, sizeof( output ),
2737 &output_length ),
2738 PSA_ERROR_BAD_STATE );
2739
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002740 /* A default cipher operation should be abortable without error. */
2741 PSA_ASSERT( psa_cipher_abort( &func ) );
2742 PSA_ASSERT( psa_cipher_abort( &init ) );
2743 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002744}
2745/* END_CASE */
2746
2747/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002748void cipher_setup( int key_type_arg,
2749 data_t *key,
2750 int alg_arg,
2751 int expected_status_arg )
2752{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002753 psa_key_type_t key_type = key_type_arg;
2754 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002755 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002756 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002757 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002758#if defined(KNOWN_SUPPORTED_MAC_ALG)
2759 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2760#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002761
Gilles Peskine8817f612018-12-18 00:18:46 +01002762 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002763
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002764 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2765 &operation, &status ) )
2766 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002767 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002768
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002769 /* The operation object should be reusable. */
2770#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2771 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2772 smoke_test_key_data,
2773 sizeof( smoke_test_key_data ),
2774 KNOWN_SUPPORTED_CIPHER_ALG,
2775 &operation, &status ) )
2776 goto exit;
2777 TEST_EQUAL( status, PSA_SUCCESS );
2778#endif
2779
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002780exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002781 mbedtls_psa_crypto_free( );
2782}
2783/* END_CASE */
2784
2785/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002786void cipher_bad_order( )
2787{
2788 psa_key_handle_t handle = 0;
2789 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2790 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
2791 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2792 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2793 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2794 const uint8_t key[] = {
2795 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2796 0xaa, 0xaa, 0xaa, 0xaa };
2797 const uint8_t text[] = {
2798 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2799 0xbb, 0xbb, 0xbb, 0xbb };
2800 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2801 size_t length = 0;
2802
2803 PSA_ASSERT( psa_crypto_init( ) );
2804 PSA_ASSERT( psa_allocate_key( &handle ) );
2805 psa_key_policy_set_usage( &policy,
2806 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
2807 alg );
2808 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2809 PSA_ASSERT( psa_import_key( handle, key_type,
2810 key, sizeof(key) ) );
2811
2812
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002813 /* Call encrypt setup twice in a row. */
2814 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2815 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2816 PSA_ERROR_BAD_STATE );
2817 PSA_ASSERT( psa_cipher_abort( &operation ) );
2818
2819 /* Call decrypt setup twice in a row. */
2820 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2821 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2822 PSA_ERROR_BAD_STATE );
2823 PSA_ASSERT( psa_cipher_abort( &operation ) );
2824
Jaeden Ameroab439972019-02-15 14:12:05 +00002825 /* Generate an IV without calling setup beforehand. */
2826 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2827 buffer, sizeof( buffer ),
2828 &length ),
2829 PSA_ERROR_BAD_STATE );
2830 PSA_ASSERT( psa_cipher_abort( &operation ) );
2831
2832 /* Generate an IV twice in a row. */
2833 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2834 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2835 buffer, sizeof( buffer ),
2836 &length ) );
2837 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2838 buffer, sizeof( buffer ),
2839 &length ),
2840 PSA_ERROR_BAD_STATE );
2841 PSA_ASSERT( psa_cipher_abort( &operation ) );
2842
2843 /* Generate an IV after it's already set. */
2844 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2845 PSA_ASSERT( psa_cipher_set_iv( &operation,
2846 iv, sizeof( iv ) ) );
2847 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2848 buffer, sizeof( buffer ),
2849 &length ),
2850 PSA_ERROR_BAD_STATE );
2851 PSA_ASSERT( psa_cipher_abort( &operation ) );
2852
2853 /* Set an IV without calling setup beforehand. */
2854 TEST_EQUAL( psa_cipher_set_iv( &operation,
2855 iv, sizeof( iv ) ),
2856 PSA_ERROR_BAD_STATE );
2857 PSA_ASSERT( psa_cipher_abort( &operation ) );
2858
2859 /* Set an IV after it's already set. */
2860 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2861 PSA_ASSERT( psa_cipher_set_iv( &operation,
2862 iv, sizeof( iv ) ) );
2863 TEST_EQUAL( psa_cipher_set_iv( &operation,
2864 iv, sizeof( iv ) ),
2865 PSA_ERROR_BAD_STATE );
2866 PSA_ASSERT( psa_cipher_abort( &operation ) );
2867
2868 /* Set an IV after it's already generated. */
2869 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2870 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2871 buffer, sizeof( buffer ),
2872 &length ) );
2873 TEST_EQUAL( psa_cipher_set_iv( &operation,
2874 iv, sizeof( iv ) ),
2875 PSA_ERROR_BAD_STATE );
2876 PSA_ASSERT( psa_cipher_abort( &operation ) );
2877
2878 /* Call update without calling setup beforehand. */
2879 TEST_EQUAL( psa_cipher_update( &operation,
2880 text, sizeof( text ),
2881 buffer, sizeof( buffer ),
2882 &length ),
2883 PSA_ERROR_BAD_STATE );
2884 PSA_ASSERT( psa_cipher_abort( &operation ) );
2885
2886 /* Call update without an IV where an IV is required. */
2887 TEST_EQUAL( psa_cipher_update( &operation,
2888 text, sizeof( text ),
2889 buffer, sizeof( buffer ),
2890 &length ),
2891 PSA_ERROR_BAD_STATE );
2892 PSA_ASSERT( psa_cipher_abort( &operation ) );
2893
2894 /* Call update after finish. */
2895 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2896 PSA_ASSERT( psa_cipher_set_iv( &operation,
2897 iv, sizeof( iv ) ) );
2898 PSA_ASSERT( psa_cipher_finish( &operation,
2899 buffer, sizeof( buffer ), &length ) );
2900 TEST_EQUAL( psa_cipher_update( &operation,
2901 text, sizeof( text ),
2902 buffer, sizeof( buffer ),
2903 &length ),
2904 PSA_ERROR_BAD_STATE );
2905 PSA_ASSERT( psa_cipher_abort( &operation ) );
2906
2907 /* Call finish without calling setup beforehand. */
2908 TEST_EQUAL( psa_cipher_finish( &operation,
2909 buffer, sizeof( buffer ), &length ),
2910 PSA_ERROR_BAD_STATE );
2911 PSA_ASSERT( psa_cipher_abort( &operation ) );
2912
2913 /* Call finish without an IV where an IV is required. */
2914 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2915 /* Not calling update means we are encrypting an empty buffer, which is OK
2916 * for cipher modes with padding. */
2917 TEST_EQUAL( psa_cipher_finish( &operation,
2918 buffer, sizeof( buffer ), &length ),
2919 PSA_ERROR_BAD_STATE );
2920 PSA_ASSERT( psa_cipher_abort( &operation ) );
2921
2922 /* Call finish twice in a row. */
2923 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2924 PSA_ASSERT( psa_cipher_set_iv( &operation,
2925 iv, sizeof( iv ) ) );
2926 PSA_ASSERT( psa_cipher_finish( &operation,
2927 buffer, sizeof( buffer ), &length ) );
2928 TEST_EQUAL( psa_cipher_finish( &operation,
2929 buffer, sizeof( buffer ), &length ),
2930 PSA_ERROR_BAD_STATE );
2931 PSA_ASSERT( psa_cipher_abort( &operation ) );
2932
2933exit:
2934 mbedtls_psa_crypto_free( );
2935}
2936/* END_CASE */
2937
2938/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002939void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002940 data_t *key,
2941 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002942 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002943{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002944 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002945 psa_status_t status;
2946 psa_key_type_t key_type = key_type_arg;
2947 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002948 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002949 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002950 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002951 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952 size_t output_buffer_size = 0;
2953 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002954 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002955 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002956 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002957
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002958 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2959 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002960
Gilles Peskine8817f612018-12-18 00:18:46 +01002961 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002962
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002963 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002964 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002965 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002966
Gilles Peskine8817f612018-12-18 00:18:46 +01002967 PSA_ASSERT( psa_import_key( handle, key_type,
2968 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002969
Gilles Peskine8817f612018-12-18 00:18:46 +01002970 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2971 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002972
Gilles Peskine8817f612018-12-18 00:18:46 +01002973 PSA_ASSERT( psa_cipher_set_iv( &operation,
2974 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002975 output_buffer_size = ( (size_t) input->len +
2976 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002977 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002978
Gilles Peskine8817f612018-12-18 00:18:46 +01002979 PSA_ASSERT( psa_cipher_update( &operation,
2980 input->x, input->len,
2981 output, output_buffer_size,
2982 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002983 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002984 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002985 output + total_output_length,
2986 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002987 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002988 total_output_length += function_output_length;
2989
Gilles Peskinefe11b722018-12-18 00:24:04 +01002990 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002991 if( expected_status == PSA_SUCCESS )
2992 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002993 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002994 ASSERT_COMPARE( expected_output->x, expected_output->len,
2995 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002996 }
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002997
Gilles Peskine50e586b2018-06-08 14:28:46 +02002998exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002999 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003000 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003001 mbedtls_psa_crypto_free( );
3002}
3003/* END_CASE */
3004
3005/* BEGIN_CASE */
3006void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003007 data_t *key,
3008 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003009 int first_part_size_arg,
3010 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003011 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003013 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003014 psa_key_type_t key_type = key_type_arg;
3015 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003016 size_t first_part_size = first_part_size_arg;
3017 size_t output1_length = output1_length_arg;
3018 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003019 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003020 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003021 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003022 size_t output_buffer_size = 0;
3023 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003024 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003025 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003026 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003027
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003028 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3029 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003030
Gilles Peskine8817f612018-12-18 00:18:46 +01003031 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003032
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003033 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003034 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003035 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003036
Gilles Peskine8817f612018-12-18 00:18:46 +01003037 PSA_ASSERT( psa_import_key( handle, key_type,
3038 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003039
Gilles Peskine8817f612018-12-18 00:18:46 +01003040 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3041 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003042
Gilles Peskine8817f612018-12-18 00:18:46 +01003043 PSA_ASSERT( psa_cipher_set_iv( &operation,
3044 iv, sizeof( iv ) ) );
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, input->x, first_part_size,
3051 output, output_buffer_size,
3052 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003053 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003054 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003055 PSA_ASSERT( psa_cipher_update( &operation,
3056 input->x + first_part_size,
3057 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003058 output + total_output_length,
3059 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003060 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003061 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003062 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003063 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003064 output + total_output_length,
3065 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003066 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003067 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003068 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003069
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003070 ASSERT_COMPARE( expected_output->x, expected_output->len,
3071 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003072
3073exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003074 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003075 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003076 mbedtls_psa_crypto_free( );
3077}
3078/* END_CASE */
3079
3080/* BEGIN_CASE */
3081void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003082 data_t *key,
3083 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003084 int first_part_size_arg,
3085 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003086 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003087{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003088 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003089
3090 psa_key_type_t key_type = key_type_arg;
3091 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003092 size_t first_part_size = first_part_size_arg;
3093 size_t output1_length = output1_length_arg;
3094 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003095 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003096 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003097 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003098 size_t output_buffer_size = 0;
3099 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003100 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003101 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003102 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003103
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003104 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3105 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003106
Gilles Peskine8817f612018-12-18 00:18:46 +01003107 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003108
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003109 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003110 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003111 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003112
Gilles Peskine8817f612018-12-18 00:18:46 +01003113 PSA_ASSERT( psa_import_key( handle, key_type,
3114 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003115
Gilles Peskine8817f612018-12-18 00:18:46 +01003116 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3117 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003118
Gilles Peskine8817f612018-12-18 00:18:46 +01003119 PSA_ASSERT( psa_cipher_set_iv( &operation,
3120 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003121
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003122 output_buffer_size = ( (size_t) input->len +
3123 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003124 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003125
Gilles Peskinee0866522019-02-19 19:44:00 +01003126 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003127 PSA_ASSERT( psa_cipher_update( &operation,
3128 input->x, first_part_size,
3129 output, output_buffer_size,
3130 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003131 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003132 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003133 PSA_ASSERT( psa_cipher_update( &operation,
3134 input->x + first_part_size,
3135 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003136 output + total_output_length,
3137 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003138 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003139 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003140 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003141 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003142 output + total_output_length,
3143 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003144 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003145 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003146 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003147
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003148 ASSERT_COMPARE( expected_output->x, expected_output->len,
3149 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003150
3151exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003152 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003153 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003154 mbedtls_psa_crypto_free( );
3155}
3156/* END_CASE */
3157
Gilles Peskine50e586b2018-06-08 14:28:46 +02003158/* BEGIN_CASE */
3159void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003160 data_t *key,
3161 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003162 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003163{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003164 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003165 psa_status_t status;
3166 psa_key_type_t key_type = key_type_arg;
3167 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003168 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003169 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003170 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003171 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003172 size_t output_buffer_size = 0;
3173 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003174 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003175 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003176 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003177
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003178 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3179 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003180
Gilles Peskine8817f612018-12-18 00:18:46 +01003181 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003182
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003183 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003184 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003185 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003186
Gilles Peskine8817f612018-12-18 00:18:46 +01003187 PSA_ASSERT( psa_import_key( handle, key_type,
3188 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003189
Gilles Peskine8817f612018-12-18 00:18:46 +01003190 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3191 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003192
Gilles Peskine8817f612018-12-18 00:18:46 +01003193 PSA_ASSERT( psa_cipher_set_iv( &operation,
3194 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003195
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003196 output_buffer_size = ( (size_t) input->len +
3197 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003198 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003199
Gilles Peskine8817f612018-12-18 00:18:46 +01003200 PSA_ASSERT( psa_cipher_update( &operation,
3201 input->x, input->len,
3202 output, output_buffer_size,
3203 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003204 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003205 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003206 output + total_output_length,
3207 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003208 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003209 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003210 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003211
3212 if( expected_status == PSA_SUCCESS )
3213 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003214 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003215 ASSERT_COMPARE( expected_output->x, expected_output->len,
3216 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003217 }
3218
Gilles Peskine50e586b2018-06-08 14:28:46 +02003219exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003220 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003221 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003222 mbedtls_psa_crypto_free( );
3223}
3224/* END_CASE */
3225
Gilles Peskine50e586b2018-06-08 14:28:46 +02003226/* BEGIN_CASE */
3227void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003228 data_t *key,
3229 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003230{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003231 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003232 psa_key_type_t key_type = key_type_arg;
3233 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003234 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003235 size_t iv_size = 16;
3236 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003237 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003238 size_t output1_size = 0;
3239 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003240 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003241 size_t output2_size = 0;
3242 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003243 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003244 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3245 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003246 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003247
Gilles Peskine8817f612018-12-18 00:18:46 +01003248 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003249
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003250 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003251 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003252 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003253
Gilles Peskine8817f612018-12-18 00:18:46 +01003254 PSA_ASSERT( psa_import_key( handle, key_type,
3255 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003256
Gilles Peskine8817f612018-12-18 00:18:46 +01003257 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3258 handle, alg ) );
3259 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3260 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003261
Gilles Peskine8817f612018-12-18 00:18:46 +01003262 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3263 iv, iv_size,
3264 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003265 output1_size = ( (size_t) input->len +
3266 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003267 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003268
Gilles Peskine8817f612018-12-18 00:18:46 +01003269 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3270 output1, output1_size,
3271 &output1_length ) );
3272 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003273 output1 + output1_length,
3274 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003275 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003276
Gilles Peskine048b7f02018-06-08 14:20:49 +02003277 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003278
Gilles Peskine8817f612018-12-18 00:18:46 +01003279 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003280
3281 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003282 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003283
Gilles Peskine8817f612018-12-18 00:18:46 +01003284 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3285 iv, iv_length ) );
3286 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3287 output2, output2_size,
3288 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003289 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003290 PSA_ASSERT( psa_cipher_finish( &operation2,
3291 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003292 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003293 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003294
Gilles Peskine048b7f02018-06-08 14:20:49 +02003295 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003296
Gilles Peskine8817f612018-12-18 00:18:46 +01003297 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003298
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003299 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003300
3301exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003302 mbedtls_free( output1 );
3303 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003304 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003305 mbedtls_psa_crypto_free( );
3306}
3307/* END_CASE */
3308
3309/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003310void cipher_verify_output_multipart( int alg_arg,
3311 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003312 data_t *key,
3313 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003314 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003315{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003316 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003317 psa_key_type_t key_type = key_type_arg;
3318 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003319 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003320 unsigned char iv[16] = {0};
3321 size_t iv_size = 16;
3322 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003323 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003324 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003325 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003326 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003327 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003328 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003329 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003330 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3331 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003332 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003333
Gilles Peskine8817f612018-12-18 00:18:46 +01003334 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003335
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003336 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003337 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003338 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003339
Gilles Peskine8817f612018-12-18 00:18:46 +01003340 PSA_ASSERT( psa_import_key( handle, key_type,
3341 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003342
Gilles Peskine8817f612018-12-18 00:18:46 +01003343 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3344 handle, alg ) );
3345 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3346 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003347
Gilles Peskine8817f612018-12-18 00:18:46 +01003348 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3349 iv, iv_size,
3350 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003351 output1_buffer_size = ( (size_t) input->len +
3352 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003353 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003354
Gilles Peskinee0866522019-02-19 19:44:00 +01003355 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003356
Gilles Peskine8817f612018-12-18 00:18:46 +01003357 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3358 output1, output1_buffer_size,
3359 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003360 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003361
Gilles Peskine8817f612018-12-18 00:18:46 +01003362 PSA_ASSERT( psa_cipher_update( &operation1,
3363 input->x + first_part_size,
3364 input->len - first_part_size,
3365 output1, output1_buffer_size,
3366 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003367 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003368
Gilles Peskine8817f612018-12-18 00:18:46 +01003369 PSA_ASSERT( psa_cipher_finish( &operation1,
3370 output1 + output1_length,
3371 output1_buffer_size - output1_length,
3372 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003373 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003374
Gilles Peskine8817f612018-12-18 00:18:46 +01003375 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003376
Gilles Peskine048b7f02018-06-08 14:20:49 +02003377 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003378 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003379
Gilles Peskine8817f612018-12-18 00:18:46 +01003380 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3381 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003382
Gilles Peskine8817f612018-12-18 00:18:46 +01003383 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3384 output2, output2_buffer_size,
3385 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003386 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003387
Gilles Peskine8817f612018-12-18 00:18:46 +01003388 PSA_ASSERT( psa_cipher_update( &operation2,
3389 output1 + first_part_size,
3390 output1_length - first_part_size,
3391 output2, output2_buffer_size,
3392 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003393 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003394
Gilles Peskine8817f612018-12-18 00:18:46 +01003395 PSA_ASSERT( psa_cipher_finish( &operation2,
3396 output2 + output2_length,
3397 output2_buffer_size - output2_length,
3398 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003399 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003400
Gilles Peskine8817f612018-12-18 00:18:46 +01003401 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003402
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003403 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003404
3405exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003406 mbedtls_free( output1 );
3407 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003408 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003409 mbedtls_psa_crypto_free( );
3410}
3411/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003412
Gilles Peskine20035e32018-02-03 22:44:14 +01003413/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003414void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003415 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003416 data_t *nonce,
3417 data_t *additional_data,
3418 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003419 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003420{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003421 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003422 psa_key_type_t key_type = key_type_arg;
3423 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003424 unsigned char *output_data = NULL;
3425 size_t output_size = 0;
3426 size_t output_length = 0;
3427 unsigned char *output_data2 = NULL;
3428 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003429 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003430 psa_status_t expected_result = expected_result_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003431 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003432
Gilles Peskine4abf7412018-06-18 16:35:34 +02003433 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003434 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435
Gilles Peskine8817f612018-12-18 00:18:46 +01003436 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003437
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003438 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003439 psa_key_policy_set_usage( &policy,
3440 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
3441 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003442 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003443
Gilles Peskine8817f612018-12-18 00:18:46 +01003444 PSA_ASSERT( psa_import_key( handle, key_type,
3445 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003446
Gilles Peskinefe11b722018-12-18 00:24:04 +01003447 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3448 nonce->x, nonce->len,
3449 additional_data->x,
3450 additional_data->len,
3451 input_data->x, input_data->len,
3452 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003453 &output_length ),
3454 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003455
3456 if( PSA_SUCCESS == expected_result )
3457 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003458 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003459
Gilles Peskinefe11b722018-12-18 00:24:04 +01003460 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3461 nonce->x, nonce->len,
3462 additional_data->x,
3463 additional_data->len,
3464 output_data, output_length,
3465 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003466 &output_length2 ),
3467 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003468
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003469 ASSERT_COMPARE( input_data->x, input_data->len,
3470 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003471 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003472
Gilles Peskinea1cac842018-06-11 19:33:02 +02003473exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003474 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003475 mbedtls_free( output_data );
3476 mbedtls_free( output_data2 );
3477 mbedtls_psa_crypto_free( );
3478}
3479/* END_CASE */
3480
3481/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003482void aead_encrypt( int key_type_arg, data_t *key_data,
3483 int alg_arg,
3484 data_t *nonce,
3485 data_t *additional_data,
3486 data_t *input_data,
3487 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003489 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003490 psa_key_type_t key_type = key_type_arg;
3491 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003492 unsigned char *output_data = NULL;
3493 size_t output_size = 0;
3494 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003495 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003496 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003497
Gilles Peskine4abf7412018-06-18 16:35:34 +02003498 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003499 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003500
Gilles Peskine8817f612018-12-18 00:18:46 +01003501 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003502
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003503 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003504 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003505 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003506
Gilles Peskine8817f612018-12-18 00:18:46 +01003507 PSA_ASSERT( psa_import_key( handle, key_type,
3508 key_data->x,
3509 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003510
Gilles Peskine8817f612018-12-18 00:18:46 +01003511 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3512 nonce->x, nonce->len,
3513 additional_data->x, additional_data->len,
3514 input_data->x, input_data->len,
3515 output_data, output_size,
3516 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003517
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003518 ASSERT_COMPARE( expected_result->x, expected_result->len,
3519 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003520
Gilles Peskinea1cac842018-06-11 19:33:02 +02003521exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003522 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003523 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003524 mbedtls_psa_crypto_free( );
3525}
3526/* END_CASE */
3527
3528/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003529void aead_decrypt( int key_type_arg, data_t *key_data,
3530 int alg_arg,
3531 data_t *nonce,
3532 data_t *additional_data,
3533 data_t *input_data,
3534 data_t *expected_data,
3535 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003536{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003537 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003538 psa_key_type_t key_type = key_type_arg;
3539 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003540 unsigned char *output_data = NULL;
3541 size_t output_size = 0;
3542 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003543 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003544 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003545 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003546
Gilles Peskine4abf7412018-06-18 16:35:34 +02003547 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003548 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003549
Gilles Peskine8817f612018-12-18 00:18:46 +01003550 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003551
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003552 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003553 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003554 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003555
Gilles Peskine8817f612018-12-18 00:18:46 +01003556 PSA_ASSERT( psa_import_key( handle, key_type,
3557 key_data->x,
3558 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003559
Gilles Peskinefe11b722018-12-18 00:24:04 +01003560 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3561 nonce->x, nonce->len,
3562 additional_data->x,
3563 additional_data->len,
3564 input_data->x, input_data->len,
3565 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003566 &output_length ),
3567 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003568
Gilles Peskine2d277862018-06-18 15:41:12 +02003569 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003570 ASSERT_COMPARE( expected_data->x, expected_data->len,
3571 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003572
Gilles Peskinea1cac842018-06-11 19:33:02 +02003573exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003574 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003575 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003576 mbedtls_psa_crypto_free( );
3577}
3578/* END_CASE */
3579
3580/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003581void signature_size( int type_arg,
3582 int bits,
3583 int alg_arg,
3584 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003585{
3586 psa_key_type_t type = type_arg;
3587 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003588 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003589 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003590exit:
3591 ;
3592}
3593/* END_CASE */
3594
3595/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003596void sign_deterministic( int key_type_arg, data_t *key_data,
3597 int alg_arg, data_t *input_data,
3598 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003599{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003600 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003601 psa_key_type_t key_type = key_type_arg;
3602 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003603 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003604 unsigned char *signature = NULL;
3605 size_t signature_size;
3606 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003607 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003608
Gilles Peskine8817f612018-12-18 00:18:46 +01003609 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003610
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003611 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003612 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003613 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003614
Gilles Peskine8817f612018-12-18 00:18:46 +01003615 PSA_ASSERT( psa_import_key( handle, key_type,
3616 key_data->x,
3617 key_data->len ) );
3618 PSA_ASSERT( psa_get_key_information( handle,
3619 NULL,
3620 &key_bits ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003621
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003622 /* Allocate a buffer which has the size advertized by the
3623 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003624 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3625 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003626 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003627 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003628 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003629
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003630 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003631 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3632 input_data->x, input_data->len,
3633 signature, signature_size,
3634 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003635 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003636 ASSERT_COMPARE( output_data->x, output_data->len,
3637 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003638
3639exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003640 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003641 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003642 mbedtls_psa_crypto_free( );
3643}
3644/* END_CASE */
3645
3646/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003647void sign_fail( int key_type_arg, data_t *key_data,
3648 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003649 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003650{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003651 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003652 psa_key_type_t key_type = key_type_arg;
3653 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003654 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003655 psa_status_t actual_status;
3656 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003657 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003658 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003659 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003660
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003661 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003662
Gilles Peskine8817f612018-12-18 00:18:46 +01003663 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003664
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003665 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003666 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003667 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003668
Gilles Peskine8817f612018-12-18 00:18:46 +01003669 PSA_ASSERT( psa_import_key( handle, key_type,
3670 key_data->x,
3671 key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003672
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003673 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003674 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003675 signature, signature_size,
3676 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003677 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003678 /* The value of *signature_length is unspecified on error, but
3679 * whatever it is, it should be less than signature_size, so that
3680 * if the caller tries to read *signature_length bytes without
3681 * checking the error code then they don't overflow a buffer. */
3682 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003683
3684exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003685 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003686 mbedtls_free( signature );
3687 mbedtls_psa_crypto_free( );
3688}
3689/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003690
3691/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003692void sign_verify( int key_type_arg, data_t *key_data,
3693 int alg_arg, data_t *input_data )
3694{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003695 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003696 psa_key_type_t key_type = key_type_arg;
3697 psa_algorithm_t alg = alg_arg;
3698 size_t key_bits;
3699 unsigned char *signature = NULL;
3700 size_t signature_size;
3701 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003702 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003703
Gilles Peskine8817f612018-12-18 00:18:46 +01003704 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003705
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003706 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003707 psa_key_policy_set_usage( &policy,
3708 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
3709 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003710 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003711
Gilles Peskine8817f612018-12-18 00:18:46 +01003712 PSA_ASSERT( psa_import_key( handle, key_type,
3713 key_data->x,
3714 key_data->len ) );
3715 PSA_ASSERT( psa_get_key_information( handle,
3716 NULL,
3717 &key_bits ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003718
3719 /* Allocate a buffer which has the size advertized by the
3720 * library. */
3721 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3722 key_bits, alg );
3723 TEST_ASSERT( signature_size != 0 );
3724 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003725 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003726
3727 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003728 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3729 input_data->x, input_data->len,
3730 signature, signature_size,
3731 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003732 /* Check that the signature length looks sensible. */
3733 TEST_ASSERT( signature_length <= signature_size );
3734 TEST_ASSERT( signature_length > 0 );
3735
3736 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003737 PSA_ASSERT( psa_asymmetric_verify(
3738 handle, alg,
3739 input_data->x, input_data->len,
3740 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003741
3742 if( input_data->len != 0 )
3743 {
3744 /* Flip a bit in the input and verify that the signature is now
3745 * detected as invalid. Flip a bit at the beginning, not at the end,
3746 * because ECDSA may ignore the last few bits of the input. */
3747 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003748 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3749 input_data->x, input_data->len,
3750 signature, signature_length ),
3751 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003752 }
3753
3754exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003755 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003756 mbedtls_free( signature );
3757 mbedtls_psa_crypto_free( );
3758}
3759/* END_CASE */
3760
3761/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003762void asymmetric_verify( int key_type_arg, data_t *key_data,
3763 int alg_arg, data_t *hash_data,
3764 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003765{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003766 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003767 psa_key_type_t key_type = key_type_arg;
3768 psa_algorithm_t alg = alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003769 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003770
Gilles Peskine69c12672018-06-28 00:07:19 +02003771 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3772
Gilles Peskine8817f612018-12-18 00:18:46 +01003773 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003774
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003775 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003776 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003777 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
itayzafrir5c753392018-05-08 11:18:38 +03003778
Gilles Peskine8817f612018-12-18 00:18:46 +01003779 PSA_ASSERT( psa_import_key( handle, key_type,
3780 key_data->x,
3781 key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003782
Gilles Peskine8817f612018-12-18 00:18:46 +01003783 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3784 hash_data->x, hash_data->len,
3785 signature_data->x,
3786 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003787exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003788 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003789 mbedtls_psa_crypto_free( );
3790}
3791/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003792
3793/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003794void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3795 int alg_arg, data_t *hash_data,
3796 data_t *signature_data,
3797 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003798{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003799 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003800 psa_key_type_t key_type = key_type_arg;
3801 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003802 psa_status_t actual_status;
3803 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003804 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003805
Gilles Peskine8817f612018-12-18 00:18:46 +01003806 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003807
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003808 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003809 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003810 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003811
Gilles Peskine8817f612018-12-18 00:18:46 +01003812 PSA_ASSERT( psa_import_key( handle, key_type,
3813 key_data->x,
3814 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003815
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003816 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003817 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003818 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003819 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003820
Gilles Peskinefe11b722018-12-18 00:24:04 +01003821 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003822
3823exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003824 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003825 mbedtls_psa_crypto_free( );
3826}
3827/* END_CASE */
3828
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003829/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003830void asymmetric_encrypt( int key_type_arg,
3831 data_t *key_data,
3832 int alg_arg,
3833 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003834 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003835 int expected_output_length_arg,
3836 int expected_status_arg )
3837{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003838 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003839 psa_key_type_t key_type = key_type_arg;
3840 psa_algorithm_t alg = alg_arg;
3841 size_t expected_output_length = expected_output_length_arg;
3842 size_t key_bits;
3843 unsigned char *output = NULL;
3844 size_t output_size;
3845 size_t output_length = ~0;
3846 psa_status_t actual_status;
3847 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003848 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003849
Gilles Peskine8817f612018-12-18 00:18:46 +01003850 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003851
Gilles Peskine656896e2018-06-29 19:12:28 +02003852 /* Import the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003853 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003854 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003855 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
3856 PSA_ASSERT( psa_import_key( handle, key_type,
3857 key_data->x,
3858 key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003859
3860 /* Determine the maximum output length */
Gilles Peskine8817f612018-12-18 00:18:46 +01003861 PSA_ASSERT( psa_get_key_information( handle,
3862 NULL,
3863 &key_bits ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003864 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003865 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003866
3867 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003868 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003869 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003870 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003871 output, output_size,
3872 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003873 TEST_EQUAL( actual_status, expected_status );
3874 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003875
Gilles Peskine68428122018-06-30 18:42:41 +02003876 /* If the label is empty, the test framework puts a non-null pointer
3877 * in label->x. Test that a null pointer works as well. */
3878 if( label->len == 0 )
3879 {
3880 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003881 if( output_size != 0 )
3882 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003883 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003884 input_data->x, input_data->len,
3885 NULL, label->len,
3886 output, output_size,
3887 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003888 TEST_EQUAL( actual_status, expected_status );
3889 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003890 }
3891
Gilles Peskine656896e2018-06-29 19:12:28 +02003892exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003893 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003894 mbedtls_free( output );
3895 mbedtls_psa_crypto_free( );
3896}
3897/* END_CASE */
3898
3899/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003900void asymmetric_encrypt_decrypt( int key_type_arg,
3901 data_t *key_data,
3902 int alg_arg,
3903 data_t *input_data,
3904 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003905{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003906 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003907 psa_key_type_t key_type = key_type_arg;
3908 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003909 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003910 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003911 size_t output_size;
3912 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003913 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003914 size_t output2_size;
3915 size_t output2_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003916 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003917
Gilles Peskine8817f612018-12-18 00:18:46 +01003918 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003919
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003920 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003921 psa_key_policy_set_usage( &policy,
3922 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003923 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003924 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003925
Gilles Peskine8817f612018-12-18 00:18:46 +01003926 PSA_ASSERT( psa_import_key( handle, key_type,
3927 key_data->x,
3928 key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003929
3930 /* Determine the maximum ciphertext length */
Gilles Peskine8817f612018-12-18 00:18:46 +01003931 PSA_ASSERT( psa_get_key_information( handle,
3932 NULL,
3933 &key_bits ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003934 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003935 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003936 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003937 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003938
Gilles Peskineeebd7382018-06-08 18:11:54 +02003939 /* We test encryption by checking that encrypt-then-decrypt gives back
3940 * the original plaintext because of the non-optional random
3941 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003942 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3943 input_data->x, input_data->len,
3944 label->x, label->len,
3945 output, output_size,
3946 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003947 /* We don't know what ciphertext length to expect, but check that
3948 * it looks sensible. */
3949 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003950
Gilles Peskine8817f612018-12-18 00:18:46 +01003951 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3952 output, output_length,
3953 label->x, label->len,
3954 output2, output2_size,
3955 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003956 ASSERT_COMPARE( input_data->x, input_data->len,
3957 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003958
3959exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003960 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003961 mbedtls_free( output );
3962 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003963 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003964}
3965/* END_CASE */
3966
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003967/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003968void asymmetric_decrypt( int key_type_arg,
3969 data_t *key_data,
3970 int alg_arg,
3971 data_t *input_data,
3972 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003973 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003974{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003975 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003976 psa_key_type_t key_type = key_type_arg;
3977 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003978 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003979 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003980 size_t output_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003981 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003982
Jaeden Amero412654a2019-02-06 12:57:46 +00003983 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003984 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003985
Gilles Peskine8817f612018-12-18 00:18:46 +01003986 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003987
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003988 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003989 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003990 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003991
Gilles Peskine8817f612018-12-18 00:18:46 +01003992 PSA_ASSERT( psa_import_key( handle, key_type,
3993 key_data->x,
3994 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003995
Gilles Peskine8817f612018-12-18 00:18:46 +01003996 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3997 input_data->x, input_data->len,
3998 label->x, label->len,
3999 output,
4000 output_size,
4001 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004002 ASSERT_COMPARE( expected_data->x, expected_data->len,
4003 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004004
Gilles Peskine68428122018-06-30 18:42:41 +02004005 /* If the label is empty, the test framework puts a non-null pointer
4006 * in label->x. Test that a null pointer works as well. */
4007 if( label->len == 0 )
4008 {
4009 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004010 if( output_size != 0 )
4011 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004012 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4013 input_data->x, input_data->len,
4014 NULL, label->len,
4015 output,
4016 output_size,
4017 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004018 ASSERT_COMPARE( expected_data->x, expected_data->len,
4019 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004020 }
4021
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004022exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004023 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004024 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004025 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004026}
4027/* END_CASE */
4028
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004029/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004030void asymmetric_decrypt_fail( int key_type_arg,
4031 data_t *key_data,
4032 int alg_arg,
4033 data_t *input_data,
4034 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00004035 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02004036 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004037{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004038 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004039 psa_key_type_t key_type = key_type_arg;
4040 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004041 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004042 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004043 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004044 psa_status_t actual_status;
4045 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00004046 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004047
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004048 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004049
Gilles Peskine8817f612018-12-18 00:18:46 +01004050 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004051
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004052 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02004053 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004054 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004055
Gilles Peskine8817f612018-12-18 00:18:46 +01004056 PSA_ASSERT( psa_import_key( handle, key_type,
4057 key_data->x,
4058 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004059
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004060 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004061 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004062 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004063 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004064 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004065 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004066 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004067
Gilles Peskine68428122018-06-30 18:42:41 +02004068 /* If the label is empty, the test framework puts a non-null pointer
4069 * in label->x. Test that a null pointer works as well. */
4070 if( label->len == 0 )
4071 {
4072 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004073 if( output_size != 0 )
4074 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004075 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004076 input_data->x, input_data->len,
4077 NULL, label->len,
4078 output, output_size,
4079 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004080 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004081 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004082 }
4083
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004084exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004085 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004086 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004087 mbedtls_psa_crypto_free( );
4088}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004089/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004090
4091/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00004092void crypto_generator_init( )
4093{
4094 /* Test each valid way of initializing the object, except for `= {0}`, as
4095 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4096 * though it's OK by the C standard. We could test for this, but we'd need
4097 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004098 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004099 psa_crypto_generator_t func = psa_crypto_generator_init( );
4100 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
4101 psa_crypto_generator_t zero;
4102
4103 memset( &zero, 0, sizeof( zero ) );
4104
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004105 /* A default generator should not be able to report its capacity. */
4106 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
4107 PSA_ERROR_BAD_STATE );
4108 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
4109 PSA_ERROR_BAD_STATE );
4110 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
4111 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004112
4113 /* A default generator should be abortable without error. */
4114 PSA_ASSERT( psa_generator_abort(&func) );
4115 PSA_ASSERT( psa_generator_abort(&init) );
4116 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004117}
4118/* END_CASE */
4119
4120/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004121void derive_setup( int key_type_arg,
4122 data_t *key_data,
4123 int alg_arg,
4124 data_t *salt,
4125 data_t *label,
4126 int requested_capacity_arg,
4127 int expected_status_arg )
4128{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004129 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004130 size_t key_type = key_type_arg;
4131 psa_algorithm_t alg = alg_arg;
4132 size_t requested_capacity = requested_capacity_arg;
4133 psa_status_t expected_status = expected_status_arg;
4134 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004135 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004136
Gilles Peskine8817f612018-12-18 00:18:46 +01004137 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004138
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004139 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004140 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004141 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004142
Gilles Peskine8817f612018-12-18 00:18:46 +01004143 PSA_ASSERT( psa_import_key( handle, key_type,
4144 key_data->x,
4145 key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004146
Gilles Peskinefe11b722018-12-18 00:24:04 +01004147 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4148 salt->x, salt->len,
4149 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004150 requested_capacity ),
4151 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004152
4153exit:
4154 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004155 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004156 mbedtls_psa_crypto_free( );
4157}
4158/* END_CASE */
4159
4160/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004161void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004162{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004163 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004164 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004165 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004166 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004167 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004168 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004169 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4170 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4171 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Jaeden Amero70261c52019-01-04 11:47:20 +00004172 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004173
Gilles Peskine8817f612018-12-18 00:18:46 +01004174 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004175
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004176 PSA_ASSERT( psa_allocate_key( &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004177 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004178 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004179
Gilles Peskine8817f612018-12-18 00:18:46 +01004180 PSA_ASSERT( psa_import_key( handle, key_type,
4181 key_data,
4182 sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004183
4184 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004185 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4186 NULL, 0,
4187 NULL, 0,
4188 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004189
4190 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004191 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4192 NULL, 0,
4193 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004194 capacity ),
4195 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004196
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004197 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004198
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004199 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004200 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004201
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004202exit:
4203 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004204 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004205 mbedtls_psa_crypto_free( );
4206}
4207/* END_CASE */
4208
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004209/* BEGIN_CASE */
4210void test_derive_invalid_generator_tests( )
4211{
4212 uint8_t output_buffer[16];
4213 size_t buffer_size = 16;
4214 size_t capacity = 0;
4215 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4216
Nir Sonnenschein50789302018-10-31 12:16:38 +02004217 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004218 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004219
4220 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004221 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004222
Gilles Peskine8817f612018-12-18 00:18:46 +01004223 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004224
Nir Sonnenschein50789302018-10-31 12:16:38 +02004225 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004226 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004227
Nir Sonnenschein50789302018-10-31 12:16:38 +02004228 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004229 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004230
4231exit:
4232 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004233}
4234/* END_CASE */
4235
4236/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004237void derive_output( int alg_arg,
4238 data_t *key_data,
4239 data_t *salt,
4240 data_t *label,
4241 int requested_capacity_arg,
4242 data_t *expected_output1,
4243 data_t *expected_output2 )
4244{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004245 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004246 psa_algorithm_t alg = alg_arg;
4247 size_t requested_capacity = requested_capacity_arg;
4248 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4249 uint8_t *expected_outputs[2] =
4250 {expected_output1->x, expected_output2->x};
4251 size_t output_sizes[2] =
4252 {expected_output1->len, expected_output2->len};
4253 size_t output_buffer_size = 0;
4254 uint8_t *output_buffer = NULL;
4255 size_t expected_capacity;
4256 size_t current_capacity;
Jaeden Amero70261c52019-01-04 11:47:20 +00004257 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004258 psa_status_t status;
4259 unsigned i;
4260
4261 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4262 {
4263 if( output_sizes[i] > output_buffer_size )
4264 output_buffer_size = output_sizes[i];
4265 if( output_sizes[i] == 0 )
4266 expected_outputs[i] = NULL;
4267 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004268 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004269 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004270
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004271 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004272 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004273 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004274
Gilles Peskine8817f612018-12-18 00:18:46 +01004275 PSA_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
4276 key_data->x,
4277 key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004278
4279 /* Extraction phase. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004280 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4281 salt->x, salt->len,
4282 label->x, label->len,
4283 requested_capacity ) );
4284 PSA_ASSERT( psa_get_generator_capacity( &generator,
4285 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004286 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004287 expected_capacity = requested_capacity;
4288
4289 /* Expansion phase. */
4290 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4291 {
4292 /* Read some bytes. */
4293 status = psa_generator_read( &generator,
4294 output_buffer, output_sizes[i] );
4295 if( expected_capacity == 0 && output_sizes[i] == 0 )
4296 {
4297 /* Reading 0 bytes when 0 bytes are available can go either way. */
4298 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004299 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004300 continue;
4301 }
4302 else if( expected_capacity == 0 ||
4303 output_sizes[i] > expected_capacity )
4304 {
4305 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004306 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004307 expected_capacity = 0;
4308 continue;
4309 }
4310 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004311 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004312 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004313 ASSERT_COMPARE( output_buffer, output_sizes[i],
4314 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004315 /* Check the generator status. */
4316 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004317 PSA_ASSERT( psa_get_generator_capacity( &generator,
4318 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004319 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004320 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004321 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004322
4323exit:
4324 mbedtls_free( output_buffer );
4325 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004326 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004327 mbedtls_psa_crypto_free( );
4328}
4329/* END_CASE */
4330
4331/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004332void derive_full( int alg_arg,
4333 data_t *key_data,
4334 data_t *salt,
4335 data_t *label,
4336 int requested_capacity_arg )
4337{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004338 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004339 psa_algorithm_t alg = alg_arg;
4340 size_t requested_capacity = requested_capacity_arg;
4341 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4342 unsigned char output_buffer[16];
4343 size_t expected_capacity = requested_capacity;
4344 size_t current_capacity;
Jaeden Amero70261c52019-01-04 11:47:20 +00004345 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004346
Gilles Peskine8817f612018-12-18 00:18:46 +01004347 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004348
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004349 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004350 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004351 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004352
Gilles Peskine8817f612018-12-18 00:18:46 +01004353 PSA_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
4354 key_data->x,
4355 key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004356
4357 /* Extraction phase. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004358 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4359 salt->x, salt->len,
4360 label->x, label->len,
4361 requested_capacity ) );
4362 PSA_ASSERT( psa_get_generator_capacity( &generator,
4363 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004364 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004365
4366 /* Expansion phase. */
4367 while( current_capacity > 0 )
4368 {
4369 size_t read_size = sizeof( output_buffer );
4370 if( read_size > current_capacity )
4371 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004372 PSA_ASSERT( psa_generator_read( &generator,
4373 output_buffer,
4374 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004375 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004376 PSA_ASSERT( psa_get_generator_capacity( &generator,
4377 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004378 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004379 }
4380
4381 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004382 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004383 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004384
Gilles Peskine8817f612018-12-18 00:18:46 +01004385 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004386
4387exit:
4388 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004389 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004390 mbedtls_psa_crypto_free( );
4391}
4392/* END_CASE */
4393
4394/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004395void derive_key_exercise( int alg_arg,
4396 data_t *key_data,
4397 data_t *salt,
4398 data_t *label,
4399 int derived_type_arg,
4400 int derived_bits_arg,
4401 int derived_usage_arg,
4402 int derived_alg_arg )
4403{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004404 psa_key_handle_t base_handle = 0;
4405 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004406 psa_algorithm_t alg = alg_arg;
4407 psa_key_type_t derived_type = derived_type_arg;
4408 size_t derived_bits = derived_bits_arg;
4409 psa_key_usage_t derived_usage = derived_usage_arg;
4410 psa_algorithm_t derived_alg = derived_alg_arg;
4411 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4412 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004413 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004414 psa_key_type_t got_type;
4415 size_t got_bits;
4416
Gilles Peskine8817f612018-12-18 00:18:46 +01004417 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004418
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004419 PSA_ASSERT( psa_allocate_key( &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004420 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004421 PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) );
4422 PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
4423 key_data->x,
4424 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004425
4426 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004427 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4428 salt->x, salt->len,
4429 label->x, label->len,
4430 capacity ) );
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004431 PSA_ASSERT( psa_allocate_key( &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004432 psa_key_policy_set_usage( &policy, derived_usage, derived_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004433 PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
4434 PSA_ASSERT( psa_generator_import_key( derived_handle,
4435 derived_type,
4436 derived_bits,
4437 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004438
4439 /* Test the key information */
Gilles Peskine8817f612018-12-18 00:18:46 +01004440 PSA_ASSERT( psa_get_key_information( derived_handle,
4441 &got_type,
4442 &got_bits ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004443 TEST_EQUAL( got_type, derived_type );
4444 TEST_EQUAL( got_bits, derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004445
4446 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004447 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004448 goto exit;
4449
4450exit:
4451 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004452 psa_destroy_key( base_handle );
4453 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004454 mbedtls_psa_crypto_free( );
4455}
4456/* END_CASE */
4457
4458/* BEGIN_CASE */
4459void derive_key_export( int alg_arg,
4460 data_t *key_data,
4461 data_t *salt,
4462 data_t *label,
4463 int bytes1_arg,
4464 int bytes2_arg )
4465{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004466 psa_key_handle_t base_handle = 0;
4467 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004468 psa_algorithm_t alg = alg_arg;
4469 size_t bytes1 = bytes1_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004470 size_t derived_bits = PSA_BYTES_TO_BITS( bytes1 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004471 size_t bytes2 = bytes2_arg;
4472 size_t capacity = bytes1 + bytes2;
4473 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004474 uint8_t *output_buffer = NULL;
4475 uint8_t *export_buffer = NULL;
Jaeden Amero70261c52019-01-04 11:47:20 +00004476 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004477 size_t length;
4478
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004479 ASSERT_ALLOC( output_buffer, capacity );
4480 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004481 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004482
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004483 PSA_ASSERT( psa_allocate_key( &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004484 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004485 PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) );
4486 PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
4487 key_data->x,
4488 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004489
4490 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004491 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4492 salt->x, salt->len,
4493 label->x, label->len,
4494 capacity ) );
4495 PSA_ASSERT( psa_generator_read( &generator,
4496 output_buffer,
4497 capacity ) );
4498 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004499
4500 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004501 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4502 salt->x, salt->len,
4503 label->x, label->len,
4504 capacity ) );
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004505 PSA_ASSERT( psa_allocate_key( &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004506 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004507 PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
4508 PSA_ASSERT( psa_generator_import_key( derived_handle,
4509 PSA_KEY_TYPE_RAW_DATA,
4510 derived_bits,
4511 &generator ) );
4512 PSA_ASSERT( psa_export_key( derived_handle,
4513 export_buffer, bytes1,
4514 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004515 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004516 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004517 PSA_ASSERT( psa_allocate_key( &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004518 PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
4519 PSA_ASSERT( psa_generator_import_key( derived_handle,
4520 PSA_KEY_TYPE_RAW_DATA,
4521 PSA_BYTES_TO_BITS( bytes2 ),
4522 &generator ) );
4523 PSA_ASSERT( psa_export_key( derived_handle,
4524 export_buffer + bytes1, bytes2,
4525 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004526 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004527
4528 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004529 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4530 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004531
4532exit:
4533 mbedtls_free( output_buffer );
4534 mbedtls_free( export_buffer );
4535 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004536 psa_destroy_key( base_handle );
4537 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004538 mbedtls_psa_crypto_free( );
4539}
4540/* END_CASE */
4541
4542/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004543void key_agreement_setup( int alg_arg,
4544 int our_key_type_arg, data_t *our_key_data,
4545 data_t *peer_key_data,
4546 int expected_status_arg )
4547{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004548 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004549 psa_algorithm_t alg = alg_arg;
4550 psa_key_type_t our_key_type = our_key_type_arg;
4551 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004552 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004553
Gilles Peskine8817f612018-12-18 00:18:46 +01004554 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004555
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004556 PSA_ASSERT( psa_allocate_key( &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004557 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004558 PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
4559 PSA_ASSERT( psa_import_key( our_key, our_key_type,
4560 our_key_data->x,
4561 our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004562
Gilles Peskinefe11b722018-12-18 00:24:04 +01004563 TEST_EQUAL( psa_key_agreement( &generator,
4564 our_key,
4565 peer_key_data->x, peer_key_data->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004566 alg ),
4567 expected_status_arg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004568
4569exit:
4570 psa_generator_abort( &generator );
4571 psa_destroy_key( our_key );
4572 mbedtls_psa_crypto_free( );
4573}
4574/* END_CASE */
4575
4576/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004577void key_agreement_capacity( int alg_arg,
4578 int our_key_type_arg, data_t *our_key_data,
4579 data_t *peer_key_data,
4580 int expected_capacity_arg )
4581{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004582 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004583 psa_algorithm_t alg = alg_arg;
4584 psa_key_type_t our_key_type = our_key_type_arg;
4585 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004586 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004587 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004588 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004589
Gilles Peskine8817f612018-12-18 00:18:46 +01004590 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004591
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004592 PSA_ASSERT( psa_allocate_key( &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004593 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004594 PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
4595 PSA_ASSERT( psa_import_key( our_key, our_key_type,
4596 our_key_data->x,
4597 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004598
Gilles Peskine8817f612018-12-18 00:18:46 +01004599 PSA_ASSERT( psa_key_agreement( &generator,
4600 our_key,
4601 peer_key_data->x, peer_key_data->len,
4602 alg ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004603
Gilles Peskinebf491972018-10-25 22:36:12 +02004604 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004605 PSA_ASSERT( psa_get_generator_capacity(
4606 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004607 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004608
Gilles Peskinebf491972018-10-25 22:36:12 +02004609 /* Test the actual capacity by reading the output. */
4610 while( actual_capacity > sizeof( output ) )
4611 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004612 PSA_ASSERT( psa_generator_read( &generator,
4613 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004614 actual_capacity -= sizeof( output );
4615 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004616 PSA_ASSERT( psa_generator_read( &generator,
4617 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004618 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004619 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004620
Gilles Peskine59685592018-09-18 12:11:34 +02004621exit:
4622 psa_generator_abort( &generator );
4623 psa_destroy_key( our_key );
4624 mbedtls_psa_crypto_free( );
4625}
4626/* END_CASE */
4627
4628/* BEGIN_CASE */
4629void key_agreement_output( int alg_arg,
4630 int our_key_type_arg, data_t *our_key_data,
4631 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004632 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004633{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004634 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004635 psa_algorithm_t alg = alg_arg;
4636 psa_key_type_t our_key_type = our_key_type_arg;
4637 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004638 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004639 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004640
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004641 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4642 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004643
Gilles Peskine8817f612018-12-18 00:18:46 +01004644 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004645
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004646 PSA_ASSERT( psa_allocate_key( &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004647 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004648 PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
4649 PSA_ASSERT( psa_import_key( our_key, our_key_type,
4650 our_key_data->x,
4651 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004652
Gilles Peskine8817f612018-12-18 00:18:46 +01004653 PSA_ASSERT( psa_key_agreement( &generator,
4654 our_key,
4655 peer_key_data->x, peer_key_data->len,
4656 alg ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004657
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004658 PSA_ASSERT( psa_generator_read( &generator,
4659 actual_output,
4660 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004661 ASSERT_COMPARE( actual_output, expected_output1->len,
4662 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004663 if( expected_output2->len != 0 )
4664 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004665 PSA_ASSERT( psa_generator_read( &generator,
4666 actual_output,
4667 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004668 ASSERT_COMPARE( actual_output, expected_output2->len,
4669 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004670 }
Gilles Peskine59685592018-09-18 12:11:34 +02004671
4672exit:
4673 psa_generator_abort( &generator );
4674 psa_destroy_key( our_key );
4675 mbedtls_psa_crypto_free( );
4676 mbedtls_free( actual_output );
4677}
4678/* END_CASE */
4679
4680/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004681void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004682{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004683 size_t bytes = bytes_arg;
4684 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004685 unsigned char *output = NULL;
4686 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004687 size_t i;
4688 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004689
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004690 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4691 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004692 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004693
Gilles Peskine8817f612018-12-18 00:18:46 +01004694 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004695
Gilles Peskinea50d7392018-06-21 10:22:13 +02004696 /* Run several times, to ensure that every output byte will be
4697 * nonzero at least once with overwhelming probability
4698 * (2^(-8*number_of_runs)). */
4699 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004700 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004701 if( bytes != 0 )
4702 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004703 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004704
4705 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004706 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4707 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004708
4709 for( i = 0; i < bytes; i++ )
4710 {
4711 if( output[i] != 0 )
4712 ++changed[i];
4713 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004714 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004715
4716 /* Check that every byte was changed to nonzero at least once. This
4717 * validates that psa_generate_random is overwriting every byte of
4718 * the output buffer. */
4719 for( i = 0; i < bytes; i++ )
4720 {
4721 TEST_ASSERT( changed[i] != 0 );
4722 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004723
4724exit:
4725 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004726 mbedtls_free( output );
4727 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004728}
4729/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004730
4731/* BEGIN_CASE */
4732void generate_key( int type_arg,
4733 int bits_arg,
4734 int usage_arg,
4735 int alg_arg,
4736 int expected_status_arg )
4737{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004738 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004739 psa_key_type_t type = type_arg;
4740 psa_key_usage_t usage = usage_arg;
4741 size_t bits = bits_arg;
4742 psa_algorithm_t alg = alg_arg;
4743 psa_status_t expected_status = expected_status_arg;
4744 psa_key_type_t got_type;
4745 size_t got_bits;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004746 psa_status_t expected_info_status =
David Saadab4ecc272019-02-14 13:48:10 +02004747 expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
Jaeden Amero70261c52019-01-04 11:47:20 +00004748 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004749
Gilles Peskine8817f612018-12-18 00:18:46 +01004750 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004751
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004752 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004753 psa_key_policy_set_usage( &policy, usage, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004754 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004755
4756 /* Generate a key */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004757 TEST_EQUAL( psa_generate_key( handle, type, bits, NULL, 0 ),
4758 expected_status );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004759
4760 /* Test the key information */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004761 TEST_EQUAL( psa_get_key_information( handle, &got_type, &got_bits ),
4762 expected_info_status );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004763 if( expected_info_status != PSA_SUCCESS )
4764 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01004765 TEST_EQUAL( got_type, type );
4766 TEST_EQUAL( got_bits, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004767
Gilles Peskine818ca122018-06-20 18:16:48 +02004768 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004769 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004770 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004771
4772exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004773 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004774 mbedtls_psa_crypto_free( );
4775}
4776/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004777
Darryl Greend49a4992018-06-18 17:27:26 +01004778/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
4779void persistent_key_load_key_from_storage( data_t *data, int type_arg,
4780 int bits, int usage_arg,
Darryl Green0c6575a2018-11-07 16:05:30 +00004781 int alg_arg, int generation_method,
4782 int export_status )
Darryl Greend49a4992018-06-18 17:27:26 +01004783{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004784 psa_key_handle_t handle = 0;
4785 psa_key_handle_t base_key;
Darryl Greend49a4992018-06-18 17:27:26 +01004786 psa_key_type_t type = (psa_key_type_t) type_arg;
4787 psa_key_type_t type_get;
4788 size_t bits_get;
Jaeden Amero70261c52019-01-04 11:47:20 +00004789 psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT;
4790 psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004791 psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg;
4792 psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00004793 psa_key_policy_t base_policy_set = PSA_KEY_POLICY_INIT;
Darryl Green0c6575a2018-11-07 16:05:30 +00004794 psa_algorithm_t base_policy_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
4795 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004796 unsigned char *first_export = NULL;
4797 unsigned char *second_export = NULL;
4798 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4799 size_t first_exported_length;
4800 size_t second_exported_length;
4801
4802 ASSERT_ALLOC( first_export, export_size );
4803 ASSERT_ALLOC( second_export, export_size );
4804
Gilles Peskine8817f612018-12-18 00:18:46 +01004805 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004806
Gilles Peskine8817f612018-12-18 00:18:46 +01004807 PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
Gilles Peskine8817f612018-12-18 00:18:46 +01004808 &handle ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004809 psa_key_policy_set_usage( &policy_set, policy_usage,
4810 policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004811 PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004812
Darryl Green0c6575a2018-11-07 16:05:30 +00004813 switch( generation_method )
4814 {
4815 case IMPORT_KEY:
4816 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01004817 PSA_ASSERT( psa_import_key( handle, type,
4818 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004819 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004820
Darryl Green0c6575a2018-11-07 16:05:30 +00004821 case GENERATE_KEY:
4822 /* Generate a key */
Gilles Peskine8817f612018-12-18 00:18:46 +01004823 PSA_ASSERT( psa_generate_key( handle, type, bits,
4824 NULL, 0 ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004825 break;
4826
4827 case DERIVE_KEY:
4828 /* Create base key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004829 PSA_ASSERT( psa_allocate_key( &base_key ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004830 psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE,
4831 base_policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004832 PSA_ASSERT( psa_set_key_policy(
4833 base_key, &base_policy_set ) );
4834 PSA_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
4835 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004836 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004837 PSA_ASSERT( psa_key_derivation( &generator, base_key,
4838 base_policy_alg,
4839 NULL, 0, NULL, 0,
4840 export_size ) );
4841 PSA_ASSERT( psa_generator_import_key(
4842 handle, PSA_KEY_TYPE_RAW_DATA,
4843 bits, &generator ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004844 break;
4845 }
Darryl Greend49a4992018-06-18 17:27:26 +01004846
4847 /* Export the key */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004848 TEST_EQUAL( psa_export_key( handle,
4849 first_export, export_size,
4850 &first_exported_length ),
4851 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004852
4853 /* Shutdown and restart */
4854 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004855 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004856
Darryl Greend49a4992018-06-18 17:27:26 +01004857 /* Check key slot still contains key data */
Gilles Peskine8817f612018-12-18 00:18:46 +01004858 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
4859 &handle ) );
4860 PSA_ASSERT( psa_get_key_information(
4861 handle, &type_get, &bits_get ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004862 TEST_EQUAL( type_get, type );
4863 TEST_EQUAL( bits_get, (size_t) bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004864
Gilles Peskine8817f612018-12-18 00:18:46 +01004865 PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004866 TEST_EQUAL( psa_key_policy_get_usage( &policy_get ), policy_usage );
4867 TEST_EQUAL( psa_key_policy_get_algorithm( &policy_get ), policy_alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004868
4869 /* Export the key again */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004870 TEST_EQUAL( psa_export_key( handle,
4871 second_export, export_size,
4872 &second_exported_length ),
4873 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004874
Darryl Green0c6575a2018-11-07 16:05:30 +00004875 if( export_status == PSA_SUCCESS )
4876 {
4877 ASSERT_COMPARE( first_export, first_exported_length,
4878 second_export, second_exported_length );
Darryl Greend49a4992018-06-18 17:27:26 +01004879
Darryl Green0c6575a2018-11-07 16:05:30 +00004880 switch( generation_method )
4881 {
4882 case IMPORT_KEY:
4883 ASSERT_COMPARE( data->x, data->len,
4884 first_export, first_exported_length );
4885 break;
4886 default:
4887 break;
4888 }
4889 }
4890
4891 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004892 if( ! exercise_key( handle, policy_usage, policy_alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004893 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004894
4895exit:
4896 mbedtls_free( first_export );
4897 mbedtls_free( second_export );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004898 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004899 mbedtls_psa_crypto_free();
4900}
4901/* END_CASE */