blob: 4cec1188135090d11f994183a325ff89257455cd [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 Peskinea4261682018-12-03 11:34:01 +01001058void import_twice( int alg_arg, int usage_arg,
1059 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,
1136 int alg_arg,
1137 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001138 int expected_bits,
1139 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001140 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001141 int canonical_input )
1142{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001143 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001144 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001145 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001146 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001147 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001148 unsigned char *exported = NULL;
1149 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001150 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001151 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001152 size_t reexported_length;
1153 psa_key_type_t got_type;
1154 size_t got_bits;
Jaeden Amero70261c52019-01-04 11:47:20 +00001155 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001156
Moran Pekercb088e72018-07-17 17:36:59 +03001157 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001158 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001159 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001160 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001161 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001162
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001163 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02001164 psa_key_policy_set_usage( &policy, usage_arg, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001165 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001166
Gilles Peskinef812dcf2018-12-18 00:33:25 +01001167 TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
David Saadab4ecc272019-02-14 13:48:10 +02001168 PSA_ERROR_DOES_NOT_EXIST );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001169
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001170 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001171 PSA_ASSERT( psa_import_key( handle, type,
1172 data->x, data->len ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001173
1174 /* Test the key information */
Gilles Peskine8817f612018-12-18 00:18:46 +01001175 PSA_ASSERT( psa_get_key_information( handle,
1176 &got_type,
1177 &got_bits ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001178 TEST_EQUAL( got_type, type );
1179 TEST_EQUAL( got_bits, (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001180
1181 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001182 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001183 exported, export_size,
1184 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001185 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001186
1187 /* The exported length must be set by psa_export_key() to a value between 0
1188 * and export_size. On errors, the exported length must be 0. */
1189 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1190 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1191 TEST_ASSERT( exported_length <= export_size );
1192
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001193 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001194 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001195 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001196 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001197 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001198 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001199 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001200
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001201 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001202 goto exit;
1203
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001204 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001205 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001206 else
1207 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001208 psa_key_handle_t handle2;
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001209 PSA_ASSERT( psa_allocate_key( &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001210 PSA_ASSERT( psa_set_key_policy( handle2, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001211
Gilles Peskine8817f612018-12-18 00:18:46 +01001212 PSA_ASSERT( psa_import_key( handle2, type,
1213 exported,
1214 exported_length ) );
1215 PSA_ASSERT( psa_export_key( handle2,
1216 reexported,
1217 export_size,
1218 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001219 ASSERT_COMPARE( exported, exported_length,
1220 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001221 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001222 }
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001223 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, got_bits ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001224
1225destroy:
1226 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001227 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01001228 TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
1229 PSA_ERROR_INVALID_HANDLE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001230
1231exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001232 mbedtls_free( exported );
1233 mbedtls_free( reexported );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001234 mbedtls_psa_crypto_free( );
1235}
1236/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001237
Moran Pekerf709f4a2018-06-06 17:26:04 +03001238/* BEGIN_CASE */
Moran Peker28a38e62018-11-07 16:18:24 +02001239void import_key_nonempty_slot( )
1240{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001241 psa_key_handle_t handle = 0;
Moran Peker28a38e62018-11-07 16:18:24 +02001242 psa_key_type_t type = PSA_KEY_TYPE_RAW_DATA;
1243 psa_status_t status;
1244 const uint8_t data[] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
Gilles Peskine8817f612018-12-18 00:18:46 +01001245 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker28a38e62018-11-07 16:18:24 +02001246
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001247 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001248
Moran Peker28a38e62018-11-07 16:18:24 +02001249 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001250 PSA_ASSERT( psa_import_key( handle, type,
1251 data, sizeof( data ) ) );
Moran Peker28a38e62018-11-07 16:18:24 +02001252
1253 /* Import the key again */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001254 status = psa_import_key( handle, type, data, sizeof( data ) );
David Saadab4ecc272019-02-14 13:48:10 +02001255 TEST_EQUAL( status, PSA_ERROR_ALREADY_EXISTS );
Moran Peker28a38e62018-11-07 16:18:24 +02001256
1257exit:
1258 mbedtls_psa_crypto_free( );
1259}
1260/* END_CASE */
1261
1262/* BEGIN_CASE */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001263void export_invalid_handle( int handle, int expected_export_status_arg )
Moran Peker28a38e62018-11-07 16:18:24 +02001264{
1265 psa_status_t status;
1266 unsigned char *exported = NULL;
1267 size_t export_size = 0;
1268 size_t exported_length = INVALID_EXPORT_LENGTH;
1269 psa_status_t expected_export_status = expected_export_status_arg;
1270
Gilles Peskine8817f612018-12-18 00:18:46 +01001271 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker28a38e62018-11-07 16:18:24 +02001272
1273 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001274 status = psa_export_key( (psa_key_handle_t) handle,
Moran Peker28a38e62018-11-07 16:18:24 +02001275 exported, export_size,
1276 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001277 TEST_EQUAL( status, expected_export_status );
Moran Peker28a38e62018-11-07 16:18:24 +02001278
1279exit:
1280 mbedtls_psa_crypto_free( );
1281}
1282/* END_CASE */
1283
1284/* BEGIN_CASE */
Moran Peker34550092018-11-07 16:19:34 +02001285void export_with_no_key_activity( )
1286{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001287 psa_key_handle_t handle = 0;
Moran Peker34550092018-11-07 16:19:34 +02001288 psa_algorithm_t alg = PSA_ALG_CTR;
1289 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +00001290 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Peker34550092018-11-07 16:19:34 +02001291 unsigned char *exported = NULL;
1292 size_t export_size = 0;
1293 size_t exported_length = INVALID_EXPORT_LENGTH;
1294
Gilles Peskine8817f612018-12-18 00:18:46 +01001295 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker34550092018-11-07 16:19:34 +02001296
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001297 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Peker34550092018-11-07 16:19:34 +02001298 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001299 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Peker34550092018-11-07 16:19:34 +02001300
1301 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001302 status = psa_export_key( handle,
Moran Peker34550092018-11-07 16:19:34 +02001303 exported, export_size,
1304 &exported_length );
David Saadab4ecc272019-02-14 13:48:10 +02001305 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Peker34550092018-11-07 16:19:34 +02001306
1307exit:
1308 mbedtls_psa_crypto_free( );
1309}
1310/* END_CASE */
1311
1312/* BEGIN_CASE */
Moran Pekerce500072018-11-07 16:20:07 +02001313void cipher_with_no_key_activity( )
1314{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001315 psa_key_handle_t handle = 0;
Moran Pekerce500072018-11-07 16:20:07 +02001316 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +00001317 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001318 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Moran Pekerce500072018-11-07 16:20:07 +02001319 int exercise_alg = PSA_ALG_CTR;
1320
Gilles Peskine8817f612018-12-18 00:18:46 +01001321 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerce500072018-11-07 16:20:07 +02001322
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001323 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekerce500072018-11-07 16:20:07 +02001324 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, exercise_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001325 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekerce500072018-11-07 16:20:07 +02001326
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001327 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
David Saadab4ecc272019-02-14 13:48:10 +02001328 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Pekerce500072018-11-07 16:20:07 +02001329
1330exit:
1331 psa_cipher_abort( &operation );
1332 mbedtls_psa_crypto_free( );
1333}
1334/* END_CASE */
1335
1336/* BEGIN_CASE */
Moran Peker34550092018-11-07 16:19:34 +02001337void export_after_import_failure( data_t *data, int type_arg,
1338 int expected_import_status_arg )
1339{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001340 psa_key_handle_t handle = 0;
Moran Peker34550092018-11-07 16:19:34 +02001341 psa_key_type_t type = type_arg;
1342 psa_status_t status;
1343 unsigned char *exported = NULL;
1344 size_t export_size = 0;
1345 psa_status_t expected_import_status = expected_import_status_arg;
1346 size_t exported_length = INVALID_EXPORT_LENGTH;
1347
Gilles Peskine8817f612018-12-18 00:18:46 +01001348 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker34550092018-11-07 16:19:34 +02001349
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001350 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001351
Moran Peker34550092018-11-07 16:19:34 +02001352 /* Import the key - expect failure */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001353 status = psa_import_key( handle, type,
Gilles Peskine0f915f12018-12-17 23:35:42 +01001354 data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001355 TEST_EQUAL( status, expected_import_status );
Moran Peker34550092018-11-07 16:19:34 +02001356
1357 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001358 status = psa_export_key( handle,
Moran Peker34550092018-11-07 16:19:34 +02001359 exported, export_size,
1360 &exported_length );
David Saadab4ecc272019-02-14 13:48:10 +02001361 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Peker34550092018-11-07 16:19:34 +02001362
1363exit:
1364 mbedtls_psa_crypto_free( );
1365}
1366/* END_CASE */
1367
1368/* BEGIN_CASE */
Moran Pekerce500072018-11-07 16:20:07 +02001369void cipher_after_import_failure( data_t *data, int type_arg,
1370 int expected_import_status_arg )
1371{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001372 psa_key_handle_t handle = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001373 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Moran Pekerce500072018-11-07 16:20:07 +02001374 psa_key_type_t type = type_arg;
1375 psa_status_t status;
1376 psa_status_t expected_import_status = expected_import_status_arg;
1377 int exercise_alg = PSA_ALG_CTR;
1378
Gilles Peskine8817f612018-12-18 00:18:46 +01001379 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerce500072018-11-07 16:20:07 +02001380
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001381 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001382
Moran Pekerce500072018-11-07 16:20:07 +02001383 /* Import the key - expect failure */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001384 status = psa_import_key( handle, type,
Gilles Peskine0f915f12018-12-17 23:35:42 +01001385 data->x, data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001386 TEST_EQUAL( status, expected_import_status );
Moran Pekerce500072018-11-07 16:20:07 +02001387
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001388 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
David Saadab4ecc272019-02-14 13:48:10 +02001389 TEST_EQUAL( status, PSA_ERROR_DOES_NOT_EXIST );
Moran Pekerce500072018-11-07 16:20:07 +02001390
1391exit:
1392 psa_cipher_abort( &operation );
1393 mbedtls_psa_crypto_free( );
1394}
1395/* END_CASE */
1396
1397/* BEGIN_CASE */
Moran Peker34550092018-11-07 16:19:34 +02001398void export_after_destroy_key( data_t *data, int type_arg )
1399{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001400 psa_key_handle_t handle = 0;
Moran Peker34550092018-11-07 16:19:34 +02001401 psa_key_type_t type = type_arg;
1402 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +00001403 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Peker34550092018-11-07 16:19:34 +02001404 psa_algorithm_t alg = PSA_ALG_CTR;
1405 unsigned char *exported = NULL;
1406 size_t export_size = 0;
1407 size_t exported_length = INVALID_EXPORT_LENGTH;
1408
Gilles Peskine8817f612018-12-18 00:18:46 +01001409 PSA_ASSERT( psa_crypto_init( ) );
Moran Peker34550092018-11-07 16:19:34 +02001410
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001411 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Peker34550092018-11-07 16:19:34 +02001412 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001413 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Peker34550092018-11-07 16:19:34 +02001414 export_size = (ptrdiff_t) data->len;
1415 ASSERT_ALLOC( exported, export_size );
1416
1417 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001418 PSA_ASSERT( psa_import_key( handle, type,
1419 data->x, data->len ) );
Moran Peker34550092018-11-07 16:19:34 +02001420
Gilles Peskine8817f612018-12-18 00:18:46 +01001421 PSA_ASSERT( psa_export_key( handle, exported, export_size,
1422 &exported_length ) );
Moran Peker34550092018-11-07 16:19:34 +02001423
1424 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001425 PSA_ASSERT( psa_destroy_key( handle ) );
Moran Peker34550092018-11-07 16:19:34 +02001426
1427 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001428 status = psa_export_key( handle, exported, export_size,
Moran Peker34550092018-11-07 16:19:34 +02001429 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001430 TEST_EQUAL( status, PSA_ERROR_INVALID_HANDLE );
Moran Peker34550092018-11-07 16:19:34 +02001431
1432exit:
1433 mbedtls_free( exported );
1434 mbedtls_psa_crypto_free( );
1435}
1436/* END_CASE */
1437
1438/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001439void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001440 int type_arg,
1441 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001442 int export_size_delta,
1443 int expected_export_status_arg,
1444 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001445{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001446 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001447 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001448 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001449 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001450 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001451 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001452 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001453 size_t exported_length = INVALID_EXPORT_LENGTH;
Jaeden Amero70261c52019-01-04 11:47:20 +00001454 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001455
Gilles Peskine8817f612018-12-18 00:18:46 +01001456 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001457
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001458 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02001459 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001460 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001461
1462 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001463 PSA_ASSERT( psa_import_key( handle, type,
1464 data->x, data->len ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001465
Gilles Peskine49c25912018-10-29 15:15:31 +01001466 /* Export the public key */
1467 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001468 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001469 exported, export_size,
1470 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001471 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001472 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001473 {
1474 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1475 size_t bits;
Gilles Peskine8817f612018-12-18 00:18:46 +01001476 PSA_ASSERT( psa_get_key_information( handle, NULL, &bits ) );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001477 TEST_ASSERT( expected_public_key->len <=
1478 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001479 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1480 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001481 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001482
1483exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001484 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001485 psa_destroy_key( handle );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001486 mbedtls_psa_crypto_free( );
1487}
1488/* END_CASE */
1489
Gilles Peskine20035e32018-02-03 22:44:14 +01001490/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001491void import_and_exercise_key( data_t *data,
1492 int type_arg,
1493 int bits_arg,
1494 int alg_arg )
1495{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001496 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001497 psa_key_type_t type = type_arg;
1498 size_t bits = bits_arg;
1499 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001500 psa_key_usage_t usage = usage_to_exercise( type, alg );
Jaeden Amero70261c52019-01-04 11:47:20 +00001501 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001502 psa_key_type_t got_type;
1503 size_t got_bits;
1504 psa_status_t status;
1505
Gilles Peskine8817f612018-12-18 00:18:46 +01001506 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001507
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001508 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001509 psa_key_policy_set_usage( &policy, usage, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001510 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001511
1512 /* Import the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001513 status = psa_import_key( handle, type, data->x, data->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01001514 PSA_ASSERT( status );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001515
1516 /* Test the key information */
Gilles Peskine8817f612018-12-18 00:18:46 +01001517 PSA_ASSERT( psa_get_key_information( handle,
1518 &got_type,
1519 &got_bits ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001520 TEST_EQUAL( got_type, type );
1521 TEST_EQUAL( got_bits, bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001522
1523 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001524 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001525 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001526
1527exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001528 psa_destroy_key( handle );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001529 mbedtls_psa_crypto_free( );
1530}
1531/* END_CASE */
1532
1533/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001534void key_policy( int usage_arg, int alg_arg )
1535{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001536 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001537 psa_algorithm_t alg = alg_arg;
1538 psa_key_usage_t usage = usage_arg;
1539 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1540 unsigned char key[32] = {0};
Jaeden Amero70261c52019-01-04 11:47:20 +00001541 psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT;
1542 psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001543
1544 memset( key, 0x2a, sizeof( key ) );
1545
Gilles Peskine8817f612018-12-18 00:18:46 +01001546 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001547
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001548 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001549 psa_key_policy_set_usage( &policy_set, usage, alg );
1550
Gilles Peskinefe11b722018-12-18 00:24:04 +01001551 TEST_EQUAL( psa_key_policy_get_usage( &policy_set ), usage );
1552 TEST_EQUAL( psa_key_policy_get_algorithm( &policy_set ), alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001553 PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001554
Gilles Peskine8817f612018-12-18 00:18:46 +01001555 PSA_ASSERT( psa_import_key( handle, key_type,
1556 key, sizeof( key ) ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001557
Gilles Peskine8817f612018-12-18 00:18:46 +01001558 PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001559
Gilles Peskinefe11b722018-12-18 00:24:04 +01001560 TEST_EQUAL( policy_get.usage, policy_set.usage );
1561 TEST_EQUAL( policy_get.alg, policy_set.alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001562
1563exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001564 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001565 mbedtls_psa_crypto_free( );
1566}
1567/* END_CASE */
1568
1569/* BEGIN_CASE */
Jaeden Amero70261c52019-01-04 11:47:20 +00001570void key_policy_init( )
1571{
1572 /* Test each valid way of initializing the object, except for `= {0}`, as
1573 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1574 * though it's OK by the C standard. We could test for this, but we'd need
1575 * to supress the Clang warning for the test. */
1576 psa_key_policy_t func = psa_key_policy_init( );
1577 psa_key_policy_t init = PSA_KEY_POLICY_INIT;
1578 psa_key_policy_t zero;
1579
1580 memset( &zero, 0, sizeof( zero ) );
1581
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001582 /* A default key policy should not permit any usage. */
1583 TEST_EQUAL( psa_key_policy_get_usage( &func ), 0 );
1584 TEST_EQUAL( psa_key_policy_get_usage( &init ), 0 );
1585 TEST_EQUAL( psa_key_policy_get_usage( &zero ), 0 );
1586
1587 /* A default key policy should not permit any algorithm. */
1588 TEST_EQUAL( psa_key_policy_get_algorithm( &func ), 0 );
1589 TEST_EQUAL( psa_key_policy_get_algorithm( &init ), 0 );
1590 TEST_EQUAL( psa_key_policy_get_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001591}
1592/* END_CASE */
1593
1594/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001595void mac_key_policy( int policy_usage,
1596 int policy_alg,
1597 int key_type,
1598 data_t *key_data,
1599 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001600{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001601 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001602 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001603 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001604 psa_status_t status;
1605 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001606
Gilles Peskine8817f612018-12-18 00:18:46 +01001607 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001608
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001609 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001610 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001611 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001612
Gilles Peskine8817f612018-12-18 00:18:46 +01001613 PSA_ASSERT( psa_import_key( handle, key_type,
1614 key_data->x, key_data->len ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001615
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001616 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001617 if( policy_alg == exercise_alg &&
1618 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001619 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001620 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001621 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001622 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001623
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001624 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001625 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001626 if( policy_alg == exercise_alg &&
1627 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001628 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001629 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001630 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001631
1632exit:
1633 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001634 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001635 mbedtls_psa_crypto_free( );
1636}
1637/* END_CASE */
1638
1639/* BEGIN_CASE */
1640void cipher_key_policy( int policy_usage,
1641 int policy_alg,
1642 int key_type,
1643 data_t *key_data,
1644 int exercise_alg )
1645{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001646 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001647 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001648 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001649 psa_status_t status;
1650
Gilles Peskine8817f612018-12-18 00:18:46 +01001651 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001652
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001653 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001654 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001655 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001656
Gilles Peskine8817f612018-12-18 00:18:46 +01001657 PSA_ASSERT( psa_import_key( handle, key_type,
1658 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001659
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001660 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001661 if( policy_alg == exercise_alg &&
1662 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001663 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001664 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001665 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001666 psa_cipher_abort( &operation );
1667
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001668 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001669 if( policy_alg == exercise_alg &&
1670 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001671 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001672 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001673 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001674
1675exit:
1676 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001677 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001678 mbedtls_psa_crypto_free( );
1679}
1680/* END_CASE */
1681
1682/* BEGIN_CASE */
1683void aead_key_policy( int policy_usage,
1684 int policy_alg,
1685 int key_type,
1686 data_t *key_data,
1687 int nonce_length_arg,
1688 int tag_length_arg,
1689 int exercise_alg )
1690{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001691 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001692 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001693 psa_status_t status;
1694 unsigned char nonce[16] = {0};
1695 size_t nonce_length = nonce_length_arg;
1696 unsigned char tag[16];
1697 size_t tag_length = tag_length_arg;
1698 size_t output_length;
1699
1700 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1701 TEST_ASSERT( tag_length <= sizeof( tag ) );
1702
Gilles Peskine8817f612018-12-18 00:18:46 +01001703 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001704
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001705 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001706 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001707 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001708
Gilles Peskine8817f612018-12-18 00:18:46 +01001709 PSA_ASSERT( psa_import_key( handle, key_type,
1710 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001711
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001712 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001713 nonce, nonce_length,
1714 NULL, 0,
1715 NULL, 0,
1716 tag, tag_length,
1717 &output_length );
1718 if( policy_alg == exercise_alg &&
1719 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001720 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001721 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001722 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001723
1724 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001725 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001726 nonce, nonce_length,
1727 NULL, 0,
1728 tag, tag_length,
1729 NULL, 0,
1730 &output_length );
1731 if( policy_alg == exercise_alg &&
1732 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001733 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001734 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001735 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001736
1737exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001738 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001739 mbedtls_psa_crypto_free( );
1740}
1741/* END_CASE */
1742
1743/* BEGIN_CASE */
1744void asymmetric_encryption_key_policy( int policy_usage,
1745 int policy_alg,
1746 int key_type,
1747 data_t *key_data,
1748 int exercise_alg )
1749{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001750 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001751 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001752 psa_status_t status;
1753 size_t key_bits;
1754 size_t buffer_length;
1755 unsigned char *buffer = NULL;
1756 size_t output_length;
1757
Gilles Peskine8817f612018-12-18 00:18:46 +01001758 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001759
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001760 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001761 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001762 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001763
Gilles Peskine8817f612018-12-18 00:18:46 +01001764 PSA_ASSERT( psa_import_key( handle, key_type,
1765 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001766
Gilles Peskine8817f612018-12-18 00:18:46 +01001767 PSA_ASSERT( psa_get_key_information( handle,
1768 NULL,
1769 &key_bits ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001770 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1771 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001772 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001773
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001774 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001775 NULL, 0,
1776 NULL, 0,
1777 buffer, buffer_length,
1778 &output_length );
1779 if( policy_alg == exercise_alg &&
1780 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001781 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001782 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001783 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001784
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001785 if( buffer_length != 0 )
1786 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001787 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001788 buffer, buffer_length,
1789 NULL, 0,
1790 buffer, buffer_length,
1791 &output_length );
1792 if( policy_alg == exercise_alg &&
1793 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001794 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001795 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001796 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001797
1798exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001799 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001800 mbedtls_psa_crypto_free( );
1801 mbedtls_free( buffer );
1802}
1803/* END_CASE */
1804
1805/* BEGIN_CASE */
1806void asymmetric_signature_key_policy( int policy_usage,
1807 int policy_alg,
1808 int key_type,
1809 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001810 int exercise_alg,
1811 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001812{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001813 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001814 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001815 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001816 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1817 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1818 * compatible with the policy and `payload_length_arg` is supposed to be
1819 * a valid input length to sign. If `payload_length_arg <= 0`,
1820 * `exercise_alg` is supposed to be forbidden by the policy. */
1821 int compatible_alg = payload_length_arg > 0;
1822 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001823 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1824 size_t signature_length;
1825
Gilles Peskine8817f612018-12-18 00:18:46 +01001826 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001827
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001828 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001829 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001830 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001831
Gilles Peskine8817f612018-12-18 00:18:46 +01001832 PSA_ASSERT( psa_import_key( handle, key_type,
1833 key_data->x, key_data->len ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001834
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001835 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001836 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001837 signature, sizeof( signature ),
1838 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001839 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001840 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001841 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001842 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001843
1844 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001845 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001846 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001847 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001848 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001849 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001850 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001851 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001852
1853exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001854 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001855 mbedtls_psa_crypto_free( );
1856}
1857/* END_CASE */
1858
1859/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001860void derive_key_policy( int policy_usage,
1861 int policy_alg,
1862 int key_type,
1863 data_t *key_data,
1864 int exercise_alg )
1865{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001866 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001867 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001868 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1869 psa_status_t status;
1870
Gilles Peskine8817f612018-12-18 00:18:46 +01001871 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001872
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001873 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001874 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001875 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001876
Gilles Peskine8817f612018-12-18 00:18:46 +01001877 PSA_ASSERT( psa_import_key( handle, key_type,
1878 key_data->x, key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001879
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001880 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001881 exercise_alg,
1882 NULL, 0,
1883 NULL, 0,
1884 1 );
1885 if( policy_alg == exercise_alg &&
1886 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001887 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001888 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001889 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001890
1891exit:
1892 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001893 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001894 mbedtls_psa_crypto_free( );
1895}
1896/* END_CASE */
1897
1898/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001899void agreement_key_policy( int policy_usage,
1900 int policy_alg,
1901 int key_type_arg,
1902 data_t *key_data,
1903 int exercise_alg )
1904{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001905 psa_key_handle_t handle = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +00001906 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001907 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001908 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1909 psa_status_t status;
1910
Gilles Peskine8817f612018-12-18 00:18:46 +01001911 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001912
Gilles Peskined40c1fb2019-01-19 12:20:52 +01001913 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001914 psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01001915 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001916
Gilles Peskine8817f612018-12-18 00:18:46 +01001917 PSA_ASSERT( psa_import_key( handle, key_type,
1918 key_data->x, key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001919
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001920 status = key_agreement_with_self( &generator, handle, exercise_alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001921
Gilles Peskine01d718c2018-09-18 12:01:02 +02001922 if( policy_alg == exercise_alg &&
1923 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001924 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001925 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001926 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001927
1928exit:
1929 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001930 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001931 mbedtls_psa_crypto_free( );
1932}
1933/* END_CASE */
1934
1935/* BEGIN_CASE */
Gilles Peskine57ab7212019-01-28 13:03:09 +01001936void copy_key_policy( int source_usage_arg, int source_alg_arg,
1937 int type_arg, data_t *material,
1938 int target_usage_arg, int target_alg_arg,
1939 int constraint_usage_arg, int constraint_alg_arg,
1940 int expected_usage_arg, int expected_alg_arg )
1941{
1942 psa_key_usage_t source_usage = source_usage_arg;
1943 psa_algorithm_t source_alg = source_alg_arg;
1944 psa_key_handle_t source_handle = 0;
1945 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
1946 psa_key_type_t source_type = type_arg;
1947 size_t source_bits;
1948 psa_key_usage_t target_usage = target_usage_arg;
1949 psa_algorithm_t target_alg = target_alg_arg;
1950 psa_key_handle_t target_handle = 0;
1951 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
1952 psa_key_type_t target_type;
1953 size_t target_bits;
1954 psa_key_usage_t constraint_usage = constraint_usage_arg;
1955 psa_algorithm_t constraint_alg = constraint_alg_arg;
1956 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
1957 psa_key_policy_t *p_constraint = NULL;
1958 psa_key_usage_t expected_usage = expected_usage_arg;
1959 psa_algorithm_t expected_alg = expected_alg_arg;
1960 uint8_t *export_buffer = NULL;
1961
1962 if( constraint_usage_arg != -1 )
1963 {
1964 p_constraint = &constraint;
1965 psa_key_policy_set_usage( p_constraint,
1966 constraint_usage, constraint_alg );
1967 }
1968
1969 PSA_ASSERT( psa_crypto_init( ) );
1970
1971 /* Populate the source slot. */
1972 PSA_ASSERT( psa_allocate_key( &source_handle ) );
1973 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
1974 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
1975 PSA_ASSERT( psa_import_key( source_handle, source_type,
1976 material->x, material->len ) );
1977 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
1978
1979 /* Prepare the target slot. */
1980 PSA_ASSERT( psa_allocate_key( &target_handle ) );
1981 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
1982 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
1983 target_policy = psa_key_policy_init();
1984
1985 /* Copy the key. */
1986 PSA_ASSERT( psa_copy_key( source_handle, target_handle, p_constraint ) );
1987
1988 /* Destroy the source to ensure that this doesn't affect the target. */
1989 PSA_ASSERT( psa_destroy_key( source_handle ) );
1990
1991 /* Test that the target slot has the expected content and policy. */
1992 PSA_ASSERT( psa_get_key_information( target_handle,
1993 &target_type, &target_bits ) );
1994 TEST_EQUAL( source_type, target_type );
1995 TEST_EQUAL( source_bits, target_bits );
1996 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
1997 TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
1998 TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
1999 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2000 {
2001 size_t length;
2002 ASSERT_ALLOC( export_buffer, material->len );
2003 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2004 material->len, &length ) );
2005 ASSERT_COMPARE( material->x, material->len,
2006 export_buffer, length );
2007 }
2008 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2009 goto exit;
2010
2011 PSA_ASSERT( psa_close_key( target_handle ) );
2012
2013exit:
2014 mbedtls_psa_crypto_free( );
2015 mbedtls_free( export_buffer );
2016}
2017/* END_CASE */
2018
2019/* BEGIN_CASE */
2020void copy_fail( int source_usage_arg, int source_alg_arg,
2021 int type_arg, data_t *material,
2022 int target_usage_arg, int target_alg_arg,
2023 int constraint_usage_arg, int constraint_alg_arg,
2024 int expected_status_arg )
2025{
2026 /* Test copy failure into an empty slot. There is a test for copy failure
2027 * into an occupied slot in
2028 * test_suite_psa_crypto_slot_management.function. */
2029
2030 psa_key_usage_t source_usage = source_usage_arg;
2031 psa_algorithm_t source_alg = source_alg_arg;
2032 psa_key_handle_t source_handle = 0;
2033 psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
2034 psa_key_type_t source_type = type_arg;
2035 size_t source_bits;
2036 psa_key_usage_t target_usage = target_usage_arg;
2037 psa_algorithm_t target_alg = target_alg_arg;
2038 psa_key_handle_t target_handle = 0;
2039 psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
2040 psa_key_type_t target_type;
2041 size_t target_bits;
2042 psa_key_usage_t constraint_usage = constraint_usage_arg;
2043 psa_algorithm_t constraint_alg = constraint_alg_arg;
2044 psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
2045 psa_key_policy_t *p_constraint = NULL;
2046 psa_status_t expected_status = expected_status_arg;
2047
2048 if( constraint_usage_arg != -1 )
2049 {
2050 p_constraint = &constraint;
2051 psa_key_policy_set_usage( p_constraint,
2052 constraint_usage, constraint_alg );
2053 }
2054
2055 PSA_ASSERT( psa_crypto_init( ) );
2056
2057 /* Populate the source slot. */
2058 PSA_ASSERT( psa_allocate_key( &source_handle ) );
2059 psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
2060 PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
2061 PSA_ASSERT( psa_import_key( source_handle, source_type,
2062 material->x, material->len ) );
2063 PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
2064
2065 /* Prepare the target slot. */
2066 PSA_ASSERT( psa_allocate_key( &target_handle ) );
2067 psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
2068 PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
2069 target_policy = psa_key_policy_init();
2070
2071 /* Copy the key. */
2072 TEST_EQUAL( psa_copy_key( source_handle, target_handle, p_constraint ),
2073 expected_status );
2074
2075 /* Test that the target slot is unaffected. */
2076 TEST_EQUAL( psa_get_key_information( target_handle,
2077 &target_type, &target_bits ),
David Saadab4ecc272019-02-14 13:48:10 +02002078 PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002079 PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
2080 TEST_EQUAL( target_usage, psa_key_policy_get_usage( &target_policy ) );
2081 TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &target_policy ) );
2082
2083exit:
2084 mbedtls_psa_crypto_free( );
2085}
2086/* END_CASE */
2087
2088/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002089void hash_operation_init( )
2090{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002091 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002092 /* Test each valid way of initializing the object, except for `= {0}`, as
2093 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2094 * though it's OK by the C standard. We could test for this, but we'd need
2095 * to supress the Clang warning for the test. */
2096 psa_hash_operation_t func = psa_hash_operation_init( );
2097 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2098 psa_hash_operation_t zero;
2099
2100 memset( &zero, 0, sizeof( zero ) );
2101
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002102 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002103 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2104 PSA_ERROR_BAD_STATE );
2105 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2106 PSA_ERROR_BAD_STATE );
2107 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2108 PSA_ERROR_BAD_STATE );
2109
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002110 /* A default hash operation should be abortable without error. */
2111 PSA_ASSERT( psa_hash_abort( &func ) );
2112 PSA_ASSERT( psa_hash_abort( &init ) );
2113 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002114}
2115/* END_CASE */
2116
2117/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002118void hash_setup( int alg_arg,
2119 int expected_status_arg )
2120{
2121 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002122 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002123 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002124 psa_status_t status;
2125
Gilles Peskine8817f612018-12-18 00:18:46 +01002126 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002127
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002128 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002129 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002130
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002131 /* Whether setup succeeded or failed, abort must succeed. */
2132 PSA_ASSERT( psa_hash_abort( &operation ) );
2133
2134 /* If setup failed, reproduce the failure, so as to
2135 * test the resulting state of the operation object. */
2136 if( status != PSA_SUCCESS )
2137 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2138
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002139 /* Now the operation object should be reusable. */
2140#if defined(KNOWN_SUPPORTED_HASH_ALG)
2141 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2142 PSA_ASSERT( psa_hash_abort( &operation ) );
2143#endif
2144
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002145exit:
2146 mbedtls_psa_crypto_free( );
2147}
2148/* END_CASE */
2149
2150/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002151void hash_bad_order( )
2152{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002153 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002154 unsigned char input[] = "";
2155 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002156 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002157 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2158 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2159 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002160 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002161 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002162 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002163
Gilles Peskine8817f612018-12-18 00:18:46 +01002164 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002165
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002166 /* Call setup twice in a row. */
2167 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2168 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2169 PSA_ERROR_BAD_STATE );
2170 PSA_ASSERT( psa_hash_abort( &operation ) );
2171
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002172 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002173 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002174 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002175 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002176
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002177 /* Call update after finish. */
2178 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2179 PSA_ASSERT( psa_hash_finish( &operation,
2180 hash, sizeof( hash ), &hash_len ) );
2181 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002182 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002183 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002184
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002185 /* Call verify without calling setup beforehand. */
2186 TEST_EQUAL( psa_hash_verify( &operation,
2187 valid_hash, sizeof( valid_hash ) ),
2188 PSA_ERROR_BAD_STATE );
2189 PSA_ASSERT( psa_hash_abort( &operation ) );
2190
2191 /* Call verify after finish. */
2192 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2193 PSA_ASSERT( psa_hash_finish( &operation,
2194 hash, sizeof( hash ), &hash_len ) );
2195 TEST_EQUAL( psa_hash_verify( &operation,
2196 valid_hash, sizeof( valid_hash ) ),
2197 PSA_ERROR_BAD_STATE );
2198 PSA_ASSERT( psa_hash_abort( &operation ) );
2199
2200 /* Call verify twice in a row. */
2201 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2202 PSA_ASSERT( psa_hash_verify( &operation,
2203 valid_hash, sizeof( valid_hash ) ) );
2204 TEST_EQUAL( psa_hash_verify( &operation,
2205 valid_hash, sizeof( valid_hash ) ),
2206 PSA_ERROR_BAD_STATE );
2207 PSA_ASSERT( psa_hash_abort( &operation ) );
2208
2209 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002210 TEST_EQUAL( psa_hash_finish( &operation,
2211 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002212 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002213 PSA_ASSERT( psa_hash_abort( &operation ) );
2214
2215 /* Call finish twice in a row. */
2216 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2217 PSA_ASSERT( psa_hash_finish( &operation,
2218 hash, sizeof( hash ), &hash_len ) );
2219 TEST_EQUAL( psa_hash_finish( &operation,
2220 hash, sizeof( hash ), &hash_len ),
2221 PSA_ERROR_BAD_STATE );
2222 PSA_ASSERT( psa_hash_abort( &operation ) );
2223
2224 /* Call finish after calling verify. */
2225 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2226 PSA_ASSERT( psa_hash_verify( &operation,
2227 valid_hash, sizeof( valid_hash ) ) );
2228 TEST_EQUAL( psa_hash_finish( &operation,
2229 hash, sizeof( hash ), &hash_len ),
2230 PSA_ERROR_BAD_STATE );
2231 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002232
2233exit:
2234 mbedtls_psa_crypto_free( );
2235}
2236/* END_CASE */
2237
itayzafrir27e69452018-11-01 14:26:34 +02002238/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2239void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002240{
2241 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002242 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2243 * appended to it */
2244 unsigned char hash[] = {
2245 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2246 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2247 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002248 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002249 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002250
Gilles Peskine8817f612018-12-18 00:18:46 +01002251 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002252
itayzafrir27e69452018-11-01 14:26:34 +02002253 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002254 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002255 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002256 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002257
itayzafrir27e69452018-11-01 14:26:34 +02002258 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002259 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002260 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002261 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002262
itayzafrir27e69452018-11-01 14:26:34 +02002263 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002264 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002265 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002266 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002267
itayzafrirec93d302018-10-18 18:01:10 +03002268exit:
2269 mbedtls_psa_crypto_free( );
2270}
2271/* END_CASE */
2272
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002273/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2274void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002275{
2276 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002277 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002278 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002279 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002280 size_t hash_len;
2281
Gilles Peskine8817f612018-12-18 00:18:46 +01002282 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002283
itayzafrir58028322018-10-25 10:22:01 +03002284 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002285 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002286 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002287 hash, expected_size - 1, &hash_len ),
2288 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002289
2290exit:
2291 mbedtls_psa_crypto_free( );
2292}
2293/* END_CASE */
2294
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002295/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2296void hash_clone_source_state( )
2297{
2298 psa_algorithm_t alg = PSA_ALG_SHA_256;
2299 unsigned char hash[PSA_HASH_MAX_SIZE];
2300 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2301 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2302 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2303 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2304 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2305 size_t hash_len;
2306
2307 PSA_ASSERT( psa_crypto_init( ) );
2308 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2309
2310 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2311 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2312 PSA_ASSERT( psa_hash_finish( &op_finished,
2313 hash, sizeof( hash ), &hash_len ) );
2314 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2315 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2316
2317 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2318 PSA_ERROR_BAD_STATE );
2319
2320 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2321 PSA_ASSERT( psa_hash_finish( &op_init,
2322 hash, sizeof( hash ), &hash_len ) );
2323 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2324 PSA_ASSERT( psa_hash_finish( &op_finished,
2325 hash, sizeof( hash ), &hash_len ) );
2326 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2327 PSA_ASSERT( psa_hash_finish( &op_aborted,
2328 hash, sizeof( hash ), &hash_len ) );
2329
2330exit:
2331 psa_hash_abort( &op_source );
2332 psa_hash_abort( &op_init );
2333 psa_hash_abort( &op_setup );
2334 psa_hash_abort( &op_finished );
2335 psa_hash_abort( &op_aborted );
2336 mbedtls_psa_crypto_free( );
2337}
2338/* END_CASE */
2339
2340/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2341void hash_clone_target_state( )
2342{
2343 psa_algorithm_t alg = PSA_ALG_SHA_256;
2344 unsigned char hash[PSA_HASH_MAX_SIZE];
2345 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2346 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2347 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2348 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2349 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2350 size_t hash_len;
2351
2352 PSA_ASSERT( psa_crypto_init( ) );
2353
2354 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2355 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2356 PSA_ASSERT( psa_hash_finish( &op_finished,
2357 hash, sizeof( hash ), &hash_len ) );
2358 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2359 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2360
2361 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2362 PSA_ASSERT( psa_hash_finish( &op_target,
2363 hash, sizeof( hash ), &hash_len ) );
2364
2365 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2366 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2367 PSA_ERROR_BAD_STATE );
2368 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2369 PSA_ERROR_BAD_STATE );
2370
2371exit:
2372 psa_hash_abort( &op_target );
2373 psa_hash_abort( &op_init );
2374 psa_hash_abort( &op_setup );
2375 psa_hash_abort( &op_finished );
2376 psa_hash_abort( &op_aborted );
2377 mbedtls_psa_crypto_free( );
2378}
2379/* END_CASE */
2380
itayzafrir58028322018-10-25 10:22:01 +03002381/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002382void mac_operation_init( )
2383{
Jaeden Amero252ef282019-02-15 14:05:35 +00002384 const uint8_t input[1] = { 0 };
2385
Jaeden Amero769ce272019-01-04 11:48:03 +00002386 /* Test each valid way of initializing the object, except for `= {0}`, as
2387 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2388 * though it's OK by the C standard. We could test for this, but we'd need
2389 * to supress the Clang warning for the test. */
2390 psa_mac_operation_t func = psa_mac_operation_init( );
2391 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2392 psa_mac_operation_t zero;
2393
2394 memset( &zero, 0, sizeof( zero ) );
2395
Jaeden Amero252ef282019-02-15 14:05:35 +00002396 /* A freshly-initialized MAC operation should not be usable. */
2397 TEST_EQUAL( psa_mac_update( &func,
2398 input, sizeof( input ) ),
2399 PSA_ERROR_BAD_STATE );
2400 TEST_EQUAL( psa_mac_update( &init,
2401 input, sizeof( input ) ),
2402 PSA_ERROR_BAD_STATE );
2403 TEST_EQUAL( psa_mac_update( &zero,
2404 input, sizeof( input ) ),
2405 PSA_ERROR_BAD_STATE );
2406
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002407 /* A default MAC operation should be abortable without error. */
2408 PSA_ASSERT( psa_mac_abort( &func ) );
2409 PSA_ASSERT( psa_mac_abort( &init ) );
2410 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002411}
2412/* END_CASE */
2413
2414/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002415void mac_setup( int key_type_arg,
2416 data_t *key,
2417 int alg_arg,
2418 int expected_status_arg )
2419{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002420 psa_key_type_t key_type = key_type_arg;
2421 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002422 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002423 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002424 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2425#if defined(KNOWN_SUPPORTED_MAC_ALG)
2426 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2427#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002428
Gilles Peskine8817f612018-12-18 00:18:46 +01002429 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002430
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002431 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2432 &operation, &status ) )
2433 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002434 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002435
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002436 /* The operation object should be reusable. */
2437#if defined(KNOWN_SUPPORTED_MAC_ALG)
2438 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2439 smoke_test_key_data,
2440 sizeof( smoke_test_key_data ),
2441 KNOWN_SUPPORTED_MAC_ALG,
2442 &operation, &status ) )
2443 goto exit;
2444 TEST_EQUAL( status, PSA_SUCCESS );
2445#endif
2446
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002447exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002448 mbedtls_psa_crypto_free( );
2449}
2450/* END_CASE */
2451
2452/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002453void mac_bad_order( )
2454{
2455 psa_key_handle_t handle = 0;
2456 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2457 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2458 const uint8_t key[] = {
2459 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2460 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2461 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
2462 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2463 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2464 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2465 size_t sign_mac_length = 0;
2466 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2467 const uint8_t verify_mac[] = {
2468 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2469 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2470 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2471
2472 PSA_ASSERT( psa_crypto_init( ) );
2473 PSA_ASSERT( psa_allocate_key( &handle ) );
2474 psa_key_policy_set_usage( &policy,
2475 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
2476 alg );
2477 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2478
2479 PSA_ASSERT( psa_import_key( handle, key_type,
2480 key, sizeof(key) ) );
2481
2482 /* Call update without calling setup beforehand. */
2483 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2484 PSA_ERROR_BAD_STATE );
2485 PSA_ASSERT( psa_mac_abort( &operation ) );
2486
2487 /* Call sign finish without calling setup beforehand. */
2488 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2489 &sign_mac_length),
2490 PSA_ERROR_BAD_STATE );
2491 PSA_ASSERT( psa_mac_abort( &operation ) );
2492
2493 /* Call verify finish without calling setup beforehand. */
2494 TEST_EQUAL( psa_mac_verify_finish( &operation,
2495 verify_mac, sizeof( verify_mac ) ),
2496 PSA_ERROR_BAD_STATE );
2497 PSA_ASSERT( psa_mac_abort( &operation ) );
2498
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002499 /* Call setup twice in a row. */
2500 PSA_ASSERT( psa_mac_sign_setup( &operation,
2501 handle, alg ) );
2502 TEST_EQUAL( psa_mac_sign_setup( &operation,
2503 handle, alg ),
2504 PSA_ERROR_BAD_STATE );
2505 PSA_ASSERT( psa_mac_abort( &operation ) );
2506
Jaeden Amero252ef282019-02-15 14:05:35 +00002507 /* Call update after sign finish. */
2508 PSA_ASSERT( psa_mac_sign_setup( &operation,
2509 handle, alg ) );
2510 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2511 PSA_ASSERT( psa_mac_sign_finish( &operation,
2512 sign_mac, sizeof( sign_mac ),
2513 &sign_mac_length ) );
2514 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2515 PSA_ERROR_BAD_STATE );
2516 PSA_ASSERT( psa_mac_abort( &operation ) );
2517
2518 /* Call update after verify finish. */
2519 PSA_ASSERT( psa_mac_verify_setup( &operation,
2520 handle, alg ) );
2521 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2522 PSA_ASSERT( psa_mac_verify_finish( &operation,
2523 verify_mac, sizeof( verify_mac ) ) );
2524 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2525 PSA_ERROR_BAD_STATE );
2526 PSA_ASSERT( psa_mac_abort( &operation ) );
2527
2528 /* Call sign finish twice in a row. */
2529 PSA_ASSERT( psa_mac_sign_setup( &operation,
2530 handle, alg ) );
2531 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2532 PSA_ASSERT( psa_mac_sign_finish( &operation,
2533 sign_mac, sizeof( sign_mac ),
2534 &sign_mac_length ) );
2535 TEST_EQUAL( psa_mac_sign_finish( &operation,
2536 sign_mac, sizeof( sign_mac ),
2537 &sign_mac_length ),
2538 PSA_ERROR_BAD_STATE );
2539 PSA_ASSERT( psa_mac_abort( &operation ) );
2540
2541 /* Call verify finish twice in a row. */
2542 PSA_ASSERT( psa_mac_verify_setup( &operation,
2543 handle, alg ) );
2544 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2545 PSA_ASSERT( psa_mac_verify_finish( &operation,
2546 verify_mac, sizeof( verify_mac ) ) );
2547 TEST_EQUAL( psa_mac_verify_finish( &operation,
2548 verify_mac, sizeof( verify_mac ) ),
2549 PSA_ERROR_BAD_STATE );
2550 PSA_ASSERT( psa_mac_abort( &operation ) );
2551
2552 /* Setup sign but try verify. */
2553 PSA_ASSERT( psa_mac_sign_setup( &operation,
2554 handle, alg ) );
2555 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2556 TEST_EQUAL( psa_mac_verify_finish( &operation,
2557 verify_mac, sizeof( verify_mac ) ),
2558 PSA_ERROR_BAD_STATE );
2559 PSA_ASSERT( psa_mac_abort( &operation ) );
2560
2561 /* Setup verify but try sign. */
2562 PSA_ASSERT( psa_mac_verify_setup( &operation,
2563 handle, alg ) );
2564 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2565 TEST_EQUAL( psa_mac_sign_finish( &operation,
2566 sign_mac, sizeof( sign_mac ),
2567 &sign_mac_length ),
2568 PSA_ERROR_BAD_STATE );
2569 PSA_ASSERT( psa_mac_abort( &operation ) );
2570
2571exit:
2572 mbedtls_psa_crypto_free( );
2573}
2574/* END_CASE */
2575
2576/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002577void mac_sign( int key_type_arg,
2578 data_t *key,
2579 int alg_arg,
2580 data_t *input,
2581 data_t *expected_mac )
2582{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002583 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002584 psa_key_type_t key_type = key_type_arg;
2585 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002586 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002587 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002588 /* Leave a little extra room in the output buffer. At the end of the
2589 * test, we'll check that the implementation didn't overwrite onto
2590 * this extra room. */
2591 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2592 size_t mac_buffer_size =
2593 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2594 size_t mac_length = 0;
2595
2596 memset( actual_mac, '+', sizeof( actual_mac ) );
2597 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2598 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2599
Gilles Peskine8817f612018-12-18 00:18:46 +01002600 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002601
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002602 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002603 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002604 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002605
Gilles Peskine8817f612018-12-18 00:18:46 +01002606 PSA_ASSERT( psa_import_key( handle, key_type,
2607 key->x, key->len ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002608
2609 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002610 PSA_ASSERT( psa_mac_sign_setup( &operation,
2611 handle, alg ) );
2612 PSA_ASSERT( psa_mac_update( &operation,
2613 input->x, input->len ) );
2614 PSA_ASSERT( psa_mac_sign_finish( &operation,
2615 actual_mac, mac_buffer_size,
2616 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002617
2618 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002619 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2620 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002621
2622 /* Verify that the end of the buffer is untouched. */
2623 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2624 sizeof( actual_mac ) - mac_length ) );
2625
2626exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002627 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002628 mbedtls_psa_crypto_free( );
2629}
2630/* END_CASE */
2631
2632/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002633void mac_verify( int key_type_arg,
2634 data_t *key,
2635 int alg_arg,
2636 data_t *input,
2637 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002638{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002639 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002640 psa_key_type_t key_type = key_type_arg;
2641 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002642 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002643 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002644
Gilles Peskine69c12672018-06-28 00:07:19 +02002645 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2646
Gilles Peskine8817f612018-12-18 00:18:46 +01002647 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002648
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002649 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002650 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002651 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad16036df908f2018-04-02 08:34:15 -07002652
Gilles Peskine8817f612018-12-18 00:18:46 +01002653 PSA_ASSERT( psa_import_key( handle, key_type,
2654 key->x, key->len ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002655
Gilles Peskine8817f612018-12-18 00:18:46 +01002656 PSA_ASSERT( psa_mac_verify_setup( &operation,
2657 handle, alg ) );
2658 PSA_ASSERT( psa_destroy_key( handle ) );
2659 PSA_ASSERT( psa_mac_update( &operation,
2660 input->x, input->len ) );
2661 PSA_ASSERT( psa_mac_verify_finish( &operation,
2662 expected_mac->x,
2663 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002664
2665exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002666 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002667 mbedtls_psa_crypto_free( );
2668}
2669/* END_CASE */
2670
2671/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002672void cipher_operation_init( )
2673{
Jaeden Ameroab439972019-02-15 14:12:05 +00002674 const uint8_t input[1] = { 0 };
2675 unsigned char output[1] = { 0 };
2676 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002677 /* Test each valid way of initializing the object, except for `= {0}`, as
2678 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2679 * though it's OK by the C standard. We could test for this, but we'd need
2680 * to supress the Clang warning for the test. */
2681 psa_cipher_operation_t func = psa_cipher_operation_init( );
2682 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2683 psa_cipher_operation_t zero;
2684
2685 memset( &zero, 0, sizeof( zero ) );
2686
Jaeden Ameroab439972019-02-15 14:12:05 +00002687 /* A freshly-initialized cipher operation should not be usable. */
2688 TEST_EQUAL( psa_cipher_update( &func,
2689 input, sizeof( input ),
2690 output, sizeof( output ),
2691 &output_length ),
2692 PSA_ERROR_BAD_STATE );
2693 TEST_EQUAL( psa_cipher_update( &init,
2694 input, sizeof( input ),
2695 output, sizeof( output ),
2696 &output_length ),
2697 PSA_ERROR_BAD_STATE );
2698 TEST_EQUAL( psa_cipher_update( &zero,
2699 input, sizeof( input ),
2700 output, sizeof( output ),
2701 &output_length ),
2702 PSA_ERROR_BAD_STATE );
2703
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002704 /* A default cipher operation should be abortable without error. */
2705 PSA_ASSERT( psa_cipher_abort( &func ) );
2706 PSA_ASSERT( psa_cipher_abort( &init ) );
2707 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002708}
2709/* END_CASE */
2710
2711/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002712void cipher_setup( int key_type_arg,
2713 data_t *key,
2714 int alg_arg,
2715 int expected_status_arg )
2716{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002717 psa_key_type_t key_type = key_type_arg;
2718 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002719 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002720 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002721 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002722#if defined(KNOWN_SUPPORTED_MAC_ALG)
2723 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2724#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002725
Gilles Peskine8817f612018-12-18 00:18:46 +01002726 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002727
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002728 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2729 &operation, &status ) )
2730 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002731 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002732
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002733 /* The operation object should be reusable. */
2734#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2735 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2736 smoke_test_key_data,
2737 sizeof( smoke_test_key_data ),
2738 KNOWN_SUPPORTED_CIPHER_ALG,
2739 &operation, &status ) )
2740 goto exit;
2741 TEST_EQUAL( status, PSA_SUCCESS );
2742#endif
2743
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002744exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002745 mbedtls_psa_crypto_free( );
2746}
2747/* END_CASE */
2748
2749/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002750void cipher_bad_order( )
2751{
2752 psa_key_handle_t handle = 0;
2753 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2754 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
2755 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2756 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2757 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2758 const uint8_t key[] = {
2759 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2760 0xaa, 0xaa, 0xaa, 0xaa };
2761 const uint8_t text[] = {
2762 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2763 0xbb, 0xbb, 0xbb, 0xbb };
2764 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2765 size_t length = 0;
2766
2767 PSA_ASSERT( psa_crypto_init( ) );
2768 PSA_ASSERT( psa_allocate_key( &handle ) );
2769 psa_key_policy_set_usage( &policy,
2770 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
2771 alg );
2772 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2773 PSA_ASSERT( psa_import_key( handle, key_type,
2774 key, sizeof(key) ) );
2775
2776
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002777 /* Call encrypt setup twice in a row. */
2778 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2779 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2780 PSA_ERROR_BAD_STATE );
2781 PSA_ASSERT( psa_cipher_abort( &operation ) );
2782
2783 /* Call decrypt setup twice in a row. */
2784 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2785 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2786 PSA_ERROR_BAD_STATE );
2787 PSA_ASSERT( psa_cipher_abort( &operation ) );
2788
Jaeden Ameroab439972019-02-15 14:12:05 +00002789 /* Generate an IV without calling setup beforehand. */
2790 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2791 buffer, sizeof( buffer ),
2792 &length ),
2793 PSA_ERROR_BAD_STATE );
2794 PSA_ASSERT( psa_cipher_abort( &operation ) );
2795
2796 /* Generate an IV twice in a row. */
2797 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2798 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2799 buffer, sizeof( buffer ),
2800 &length ) );
2801 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2802 buffer, sizeof( buffer ),
2803 &length ),
2804 PSA_ERROR_BAD_STATE );
2805 PSA_ASSERT( psa_cipher_abort( &operation ) );
2806
2807 /* Generate an IV after it's already set. */
2808 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2809 PSA_ASSERT( psa_cipher_set_iv( &operation,
2810 iv, sizeof( iv ) ) );
2811 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2812 buffer, sizeof( buffer ),
2813 &length ),
2814 PSA_ERROR_BAD_STATE );
2815 PSA_ASSERT( psa_cipher_abort( &operation ) );
2816
2817 /* Set an IV without calling setup beforehand. */
2818 TEST_EQUAL( psa_cipher_set_iv( &operation,
2819 iv, sizeof( iv ) ),
2820 PSA_ERROR_BAD_STATE );
2821 PSA_ASSERT( psa_cipher_abort( &operation ) );
2822
2823 /* Set an IV after it's already set. */
2824 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2825 PSA_ASSERT( psa_cipher_set_iv( &operation,
2826 iv, sizeof( iv ) ) );
2827 TEST_EQUAL( psa_cipher_set_iv( &operation,
2828 iv, sizeof( iv ) ),
2829 PSA_ERROR_BAD_STATE );
2830 PSA_ASSERT( psa_cipher_abort( &operation ) );
2831
2832 /* Set an IV after it's already generated. */
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_set_iv( &operation,
2838 iv, sizeof( iv ) ),
2839 PSA_ERROR_BAD_STATE );
2840 PSA_ASSERT( psa_cipher_abort( &operation ) );
2841
2842 /* Call update without calling setup beforehand. */
2843 TEST_EQUAL( psa_cipher_update( &operation,
2844 text, sizeof( text ),
2845 buffer, sizeof( buffer ),
2846 &length ),
2847 PSA_ERROR_BAD_STATE );
2848 PSA_ASSERT( psa_cipher_abort( &operation ) );
2849
2850 /* Call update without an IV where an IV is required. */
2851 TEST_EQUAL( psa_cipher_update( &operation,
2852 text, sizeof( text ),
2853 buffer, sizeof( buffer ),
2854 &length ),
2855 PSA_ERROR_BAD_STATE );
2856 PSA_ASSERT( psa_cipher_abort( &operation ) );
2857
2858 /* Call update after finish. */
2859 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2860 PSA_ASSERT( psa_cipher_set_iv( &operation,
2861 iv, sizeof( iv ) ) );
2862 PSA_ASSERT( psa_cipher_finish( &operation,
2863 buffer, sizeof( buffer ), &length ) );
2864 TEST_EQUAL( psa_cipher_update( &operation,
2865 text, sizeof( text ),
2866 buffer, sizeof( buffer ),
2867 &length ),
2868 PSA_ERROR_BAD_STATE );
2869 PSA_ASSERT( psa_cipher_abort( &operation ) );
2870
2871 /* Call finish without calling setup beforehand. */
2872 TEST_EQUAL( psa_cipher_finish( &operation,
2873 buffer, sizeof( buffer ), &length ),
2874 PSA_ERROR_BAD_STATE );
2875 PSA_ASSERT( psa_cipher_abort( &operation ) );
2876
2877 /* Call finish without an IV where an IV is required. */
2878 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2879 /* Not calling update means we are encrypting an empty buffer, which is OK
2880 * for cipher modes with padding. */
2881 TEST_EQUAL( psa_cipher_finish( &operation,
2882 buffer, sizeof( buffer ), &length ),
2883 PSA_ERROR_BAD_STATE );
2884 PSA_ASSERT( psa_cipher_abort( &operation ) );
2885
2886 /* Call finish twice in a row. */
2887 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2888 PSA_ASSERT( psa_cipher_set_iv( &operation,
2889 iv, sizeof( iv ) ) );
2890 PSA_ASSERT( psa_cipher_finish( &operation,
2891 buffer, sizeof( buffer ), &length ) );
2892 TEST_EQUAL( psa_cipher_finish( &operation,
2893 buffer, sizeof( buffer ), &length ),
2894 PSA_ERROR_BAD_STATE );
2895 PSA_ASSERT( psa_cipher_abort( &operation ) );
2896
2897exit:
2898 mbedtls_psa_crypto_free( );
2899}
2900/* END_CASE */
2901
2902/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002903void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002904 data_t *key,
2905 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002906 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002907{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002908 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002909 psa_status_t status;
2910 psa_key_type_t key_type = key_type_arg;
2911 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002912 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002913 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002914 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002915 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002916 size_t output_buffer_size = 0;
2917 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002918 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002919 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002920 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002921
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002922 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2923 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924
Gilles Peskine8817f612018-12-18 00:18:46 +01002925 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002926
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002927 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002928 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002929 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03002930
Gilles Peskine8817f612018-12-18 00:18:46 +01002931 PSA_ASSERT( psa_import_key( handle, key_type,
2932 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002933
Gilles Peskine8817f612018-12-18 00:18:46 +01002934 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2935 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002936
Gilles Peskine8817f612018-12-18 00:18:46 +01002937 PSA_ASSERT( psa_cipher_set_iv( &operation,
2938 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002939 output_buffer_size = ( (size_t) input->len +
2940 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002941 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002942
Gilles Peskine8817f612018-12-18 00:18:46 +01002943 PSA_ASSERT( psa_cipher_update( &operation,
2944 input->x, input->len,
2945 output, output_buffer_size,
2946 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002947 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002948 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002949 output + total_output_length,
2950 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002951 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002952 total_output_length += function_output_length;
2953
Gilles Peskinefe11b722018-12-18 00:24:04 +01002954 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002955 if( expected_status == PSA_SUCCESS )
2956 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002957 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002958 ASSERT_COMPARE( expected_output->x, expected_output->len,
2959 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002960 }
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002961
Gilles Peskine50e586b2018-06-08 14:28:46 +02002962exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002963 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002964 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002965 mbedtls_psa_crypto_free( );
2966}
2967/* END_CASE */
2968
2969/* BEGIN_CASE */
2970void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002971 data_t *key,
2972 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002973 int first_part_size_arg,
2974 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002975 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002976{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002977 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002978 psa_key_type_t key_type = key_type_arg;
2979 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002980 size_t first_part_size = first_part_size_arg;
2981 size_t output1_length = output1_length_arg;
2982 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002983 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002984 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03002985 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002986 size_t output_buffer_size = 0;
2987 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002988 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002989 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00002990 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002991
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002992 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2993 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002994
Gilles Peskine8817f612018-12-18 00:18:46 +01002995 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002996
Gilles Peskined40c1fb2019-01-19 12:20:52 +01002997 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03002998 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01002999 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003000
Gilles Peskine8817f612018-12-18 00:18:46 +01003001 PSA_ASSERT( psa_import_key( handle, key_type,
3002 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003003
Gilles Peskine8817f612018-12-18 00:18:46 +01003004 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3005 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003006
Gilles Peskine8817f612018-12-18 00:18:46 +01003007 PSA_ASSERT( psa_cipher_set_iv( &operation,
3008 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003009 output_buffer_size = ( (size_t) input->len +
3010 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003011 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012
Gilles Peskinee0866522019-02-19 19:44:00 +01003013 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003014 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3015 output, output_buffer_size,
3016 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003017 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003018 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003019 PSA_ASSERT( psa_cipher_update( &operation,
3020 input->x + first_part_size,
3021 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003022 output + total_output_length,
3023 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003024 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003025 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003026 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003027 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003028 output + total_output_length,
3029 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003030 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003031 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003032 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003033
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003034 ASSERT_COMPARE( expected_output->x, expected_output->len,
3035 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003036
3037exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003038 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003039 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003040 mbedtls_psa_crypto_free( );
3041}
3042/* END_CASE */
3043
3044/* BEGIN_CASE */
3045void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003046 data_t *key,
3047 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003048 int first_part_size_arg,
3049 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003050 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003051{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003052 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003053
3054 psa_key_type_t key_type = key_type_arg;
3055 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003056 size_t first_part_size = first_part_size_arg;
3057 size_t output1_length = output1_length_arg;
3058 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003059 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003060 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003061 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003062 size_t output_buffer_size = 0;
3063 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003064 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003065 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003066 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003067
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003068 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3069 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003070
Gilles Peskine8817f612018-12-18 00:18:46 +01003071 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003072
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003073 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003074 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003075 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003076
Gilles Peskine8817f612018-12-18 00:18:46 +01003077 PSA_ASSERT( psa_import_key( handle, key_type,
3078 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003079
Gilles Peskine8817f612018-12-18 00:18:46 +01003080 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3081 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003082
Gilles Peskine8817f612018-12-18 00:18:46 +01003083 PSA_ASSERT( psa_cipher_set_iv( &operation,
3084 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003085
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003086 output_buffer_size = ( (size_t) input->len +
3087 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003088 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003089
Gilles Peskinee0866522019-02-19 19:44:00 +01003090 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003091 PSA_ASSERT( psa_cipher_update( &operation,
3092 input->x, first_part_size,
3093 output, output_buffer_size,
3094 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003095 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003096 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003097 PSA_ASSERT( psa_cipher_update( &operation,
3098 input->x + first_part_size,
3099 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003100 output + total_output_length,
3101 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003102 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003103 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003104 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003105 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003106 output + total_output_length,
3107 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003108 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003109 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003110 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003111
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003112 ASSERT_COMPARE( expected_output->x, expected_output->len,
3113 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003114
3115exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003116 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003117 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003118 mbedtls_psa_crypto_free( );
3119}
3120/* END_CASE */
3121
Gilles Peskine50e586b2018-06-08 14:28:46 +02003122/* BEGIN_CASE */
3123void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003124 data_t *key,
3125 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003126 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003127{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003128 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003129 psa_status_t status;
3130 psa_key_type_t key_type = key_type_arg;
3131 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003132 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003133 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003134 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003135 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003136 size_t output_buffer_size = 0;
3137 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003138 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003139 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003140 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003141
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003142 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3143 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003144
Gilles Peskine8817f612018-12-18 00:18:46 +01003145 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003146
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003147 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003148 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003149 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003150
Gilles Peskine8817f612018-12-18 00:18:46 +01003151 PSA_ASSERT( psa_import_key( handle, key_type,
3152 key->x, key->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003153
Gilles Peskine8817f612018-12-18 00:18:46 +01003154 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3155 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003156
Gilles Peskine8817f612018-12-18 00:18:46 +01003157 PSA_ASSERT( psa_cipher_set_iv( &operation,
3158 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003159
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003160 output_buffer_size = ( (size_t) input->len +
3161 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003162 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003163
Gilles Peskine8817f612018-12-18 00:18:46 +01003164 PSA_ASSERT( psa_cipher_update( &operation,
3165 input->x, input->len,
3166 output, output_buffer_size,
3167 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003168 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003169 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003170 output + total_output_length,
3171 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003172 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003173 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003174 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003175
3176 if( expected_status == PSA_SUCCESS )
3177 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003178 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003179 ASSERT_COMPARE( expected_output->x, expected_output->len,
3180 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003181 }
3182
Gilles Peskine50e586b2018-06-08 14:28:46 +02003183exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003184 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003185 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003186 mbedtls_psa_crypto_free( );
3187}
3188/* END_CASE */
3189
Gilles Peskine50e586b2018-06-08 14:28:46 +02003190/* BEGIN_CASE */
3191void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003192 data_t *key,
3193 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003194{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003195 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003196 psa_key_type_t key_type = key_type_arg;
3197 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003198 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003199 size_t iv_size = 16;
3200 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003201 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003202 size_t output1_size = 0;
3203 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003204 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003205 size_t output2_size = 0;
3206 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003207 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003208 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3209 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003210 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003211
Gilles Peskine8817f612018-12-18 00:18:46 +01003212 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003213
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003214 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003215 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003216 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003217
Gilles Peskine8817f612018-12-18 00:18:46 +01003218 PSA_ASSERT( psa_import_key( handle, key_type,
3219 key->x, key->len ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003220
Gilles Peskine8817f612018-12-18 00:18:46 +01003221 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3222 handle, alg ) );
3223 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3224 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003225
Gilles Peskine8817f612018-12-18 00:18:46 +01003226 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3227 iv, iv_size,
3228 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003229 output1_size = ( (size_t) input->len +
3230 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003231 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003232
Gilles Peskine8817f612018-12-18 00:18:46 +01003233 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3234 output1, output1_size,
3235 &output1_length ) );
3236 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003237 output1 + output1_length,
3238 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003239 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003240
Gilles Peskine048b7f02018-06-08 14:20:49 +02003241 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003242
Gilles Peskine8817f612018-12-18 00:18:46 +01003243 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003244
3245 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003246 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003247
Gilles Peskine8817f612018-12-18 00:18:46 +01003248 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3249 iv, iv_length ) );
3250 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3251 output2, output2_size,
3252 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003253 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003254 PSA_ASSERT( psa_cipher_finish( &operation2,
3255 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003256 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003257 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003258
Gilles Peskine048b7f02018-06-08 14:20:49 +02003259 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003260
Gilles Peskine8817f612018-12-18 00:18:46 +01003261 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003262
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003263 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003264
3265exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003266 mbedtls_free( output1 );
3267 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003268 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003269 mbedtls_psa_crypto_free( );
3270}
3271/* END_CASE */
3272
3273/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003274void cipher_verify_output_multipart( int alg_arg,
3275 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003276 data_t *key,
3277 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003278 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003279{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003280 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003281 psa_key_type_t key_type = key_type_arg;
3282 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003283 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003284 unsigned char iv[16] = {0};
3285 size_t iv_size = 16;
3286 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003287 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003288 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003289 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003290 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003291 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003292 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003293 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003294 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3295 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00003296 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003297
Gilles Peskine8817f612018-12-18 00:18:46 +01003298 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003299
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003300 PSA_ASSERT( psa_allocate_key( &handle ) );
Moran Pekered346952018-07-05 15:22:45 +03003301 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003302 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Moran Pekered346952018-07-05 15:22:45 +03003303
Gilles Peskine8817f612018-12-18 00:18:46 +01003304 PSA_ASSERT( psa_import_key( handle, key_type,
3305 key->x, key->len ) );
Moran Pekerded84402018-06-06 16:36:50 +03003306
Gilles Peskine8817f612018-12-18 00:18:46 +01003307 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3308 handle, alg ) );
3309 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3310 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003311
Gilles Peskine8817f612018-12-18 00:18:46 +01003312 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3313 iv, iv_size,
3314 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003315 output1_buffer_size = ( (size_t) input->len +
3316 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003317 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003318
Gilles Peskinee0866522019-02-19 19:44:00 +01003319 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003320
Gilles Peskine8817f612018-12-18 00:18:46 +01003321 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3322 output1, output1_buffer_size,
3323 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003324 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003325
Gilles Peskine8817f612018-12-18 00:18:46 +01003326 PSA_ASSERT( psa_cipher_update( &operation1,
3327 input->x + first_part_size,
3328 input->len - first_part_size,
3329 output1, output1_buffer_size,
3330 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003331 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003332
Gilles Peskine8817f612018-12-18 00:18:46 +01003333 PSA_ASSERT( psa_cipher_finish( &operation1,
3334 output1 + output1_length,
3335 output1_buffer_size - output1_length,
3336 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003337 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003338
Gilles Peskine8817f612018-12-18 00:18:46 +01003339 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003340
Gilles Peskine048b7f02018-06-08 14:20:49 +02003341 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003342 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003343
Gilles Peskine8817f612018-12-18 00:18:46 +01003344 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3345 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003346
Gilles Peskine8817f612018-12-18 00:18:46 +01003347 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3348 output2, output2_buffer_size,
3349 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003350 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003351
Gilles Peskine8817f612018-12-18 00:18:46 +01003352 PSA_ASSERT( psa_cipher_update( &operation2,
3353 output1 + first_part_size,
3354 output1_length - first_part_size,
3355 output2, output2_buffer_size,
3356 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003357 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003358
Gilles Peskine8817f612018-12-18 00:18:46 +01003359 PSA_ASSERT( psa_cipher_finish( &operation2,
3360 output2 + output2_length,
3361 output2_buffer_size - output2_length,
3362 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003363 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003364
Gilles Peskine8817f612018-12-18 00:18:46 +01003365 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003366
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003367 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003368
3369exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003370 mbedtls_free( output1 );
3371 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003372 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003373 mbedtls_psa_crypto_free( );
3374}
3375/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003376
Gilles Peskine20035e32018-02-03 22:44:14 +01003377/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003378void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003379 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003380 data_t *nonce,
3381 data_t *additional_data,
3382 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003383 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003384{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003385 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003386 psa_key_type_t key_type = key_type_arg;
3387 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003388 unsigned char *output_data = NULL;
3389 size_t output_size = 0;
3390 size_t output_length = 0;
3391 unsigned char *output_data2 = NULL;
3392 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003393 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003394 psa_status_t expected_result = expected_result_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003395 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003396
Gilles Peskine4abf7412018-06-18 16:35:34 +02003397 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003398 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003399
Gilles Peskine8817f612018-12-18 00:18:46 +01003400 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003401
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003402 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003403 psa_key_policy_set_usage( &policy,
3404 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
3405 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003406 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003407
Gilles Peskine8817f612018-12-18 00:18:46 +01003408 PSA_ASSERT( psa_import_key( handle, key_type,
3409 key_data->x, key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003410
Gilles Peskinefe11b722018-12-18 00:24:04 +01003411 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3412 nonce->x, nonce->len,
3413 additional_data->x,
3414 additional_data->len,
3415 input_data->x, input_data->len,
3416 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003417 &output_length ),
3418 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003419
3420 if( PSA_SUCCESS == expected_result )
3421 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003422 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003423
Gilles Peskinefe11b722018-12-18 00:24:04 +01003424 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3425 nonce->x, nonce->len,
3426 additional_data->x,
3427 additional_data->len,
3428 output_data, output_length,
3429 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003430 &output_length2 ),
3431 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003432
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003433 ASSERT_COMPARE( input_data->x, input_data->len,
3434 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003436
Gilles Peskinea1cac842018-06-11 19:33:02 +02003437exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003438 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003439 mbedtls_free( output_data );
3440 mbedtls_free( output_data2 );
3441 mbedtls_psa_crypto_free( );
3442}
3443/* END_CASE */
3444
3445/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003446void aead_encrypt( int key_type_arg, data_t *key_data,
3447 int alg_arg,
3448 data_t *nonce,
3449 data_t *additional_data,
3450 data_t *input_data,
3451 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003452{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003453 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003454 psa_key_type_t key_type = key_type_arg;
3455 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003456 unsigned char *output_data = NULL;
3457 size_t output_size = 0;
3458 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003459 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003460 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003461
Gilles Peskine4abf7412018-06-18 16:35:34 +02003462 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003463 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003464
Gilles Peskine8817f612018-12-18 00:18:46 +01003465 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003466
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003467 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003468 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003469 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003470
Gilles Peskine8817f612018-12-18 00:18:46 +01003471 PSA_ASSERT( psa_import_key( handle, key_type,
3472 key_data->x,
3473 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003474
Gilles Peskine8817f612018-12-18 00:18:46 +01003475 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3476 nonce->x, nonce->len,
3477 additional_data->x, additional_data->len,
3478 input_data->x, input_data->len,
3479 output_data, output_size,
3480 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003481
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003482 ASSERT_COMPARE( expected_result->x, expected_result->len,
3483 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003484
Gilles Peskinea1cac842018-06-11 19:33:02 +02003485exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003486 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003487 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003488 mbedtls_psa_crypto_free( );
3489}
3490/* END_CASE */
3491
3492/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003493void aead_decrypt( int key_type_arg, data_t *key_data,
3494 int alg_arg,
3495 data_t *nonce,
3496 data_t *additional_data,
3497 data_t *input_data,
3498 data_t *expected_data,
3499 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003500{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003501 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003502 psa_key_type_t key_type = key_type_arg;
3503 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003504 unsigned char *output_data = NULL;
3505 size_t output_size = 0;
3506 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003507 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +00003508 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003509 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003510
Gilles Peskine4abf7412018-06-18 16:35:34 +02003511 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003512 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003513
Gilles Peskine8817f612018-12-18 00:18:46 +01003514 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003515
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003516 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003517 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003518 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003519
Gilles Peskine8817f612018-12-18 00:18:46 +01003520 PSA_ASSERT( psa_import_key( handle, key_type,
3521 key_data->x,
3522 key_data->len ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003523
Gilles Peskinefe11b722018-12-18 00:24:04 +01003524 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3525 nonce->x, nonce->len,
3526 additional_data->x,
3527 additional_data->len,
3528 input_data->x, input_data->len,
3529 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003530 &output_length ),
3531 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003532
Gilles Peskine2d277862018-06-18 15:41:12 +02003533 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003534 ASSERT_COMPARE( expected_data->x, expected_data->len,
3535 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003536
Gilles Peskinea1cac842018-06-11 19:33:02 +02003537exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003538 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003539 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003540 mbedtls_psa_crypto_free( );
3541}
3542/* END_CASE */
3543
3544/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003545void signature_size( int type_arg,
3546 int bits,
3547 int alg_arg,
3548 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003549{
3550 psa_key_type_t type = type_arg;
3551 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003552 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003553 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003554exit:
3555 ;
3556}
3557/* END_CASE */
3558
3559/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003560void sign_deterministic( int key_type_arg, data_t *key_data,
3561 int alg_arg, data_t *input_data,
3562 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003563{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003564 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003565 psa_key_type_t key_type = key_type_arg;
3566 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003567 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003568 unsigned char *signature = NULL;
3569 size_t signature_size;
3570 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003571 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003572
Gilles Peskine8817f612018-12-18 00:18:46 +01003573 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003574
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003575 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003576 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003577 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003578
Gilles Peskine8817f612018-12-18 00:18:46 +01003579 PSA_ASSERT( psa_import_key( handle, key_type,
3580 key_data->x,
3581 key_data->len ) );
3582 PSA_ASSERT( psa_get_key_information( handle,
3583 NULL,
3584 &key_bits ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003585
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003586 /* Allocate a buffer which has the size advertized by the
3587 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003588 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3589 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003590 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003591 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003592 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003593
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003594 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003595 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3596 input_data->x, input_data->len,
3597 signature, signature_size,
3598 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003599 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003600 ASSERT_COMPARE( output_data->x, output_data->len,
3601 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003602
3603exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003604 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003605 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003606 mbedtls_psa_crypto_free( );
3607}
3608/* END_CASE */
3609
3610/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003611void sign_fail( int key_type_arg, data_t *key_data,
3612 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003613 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003614{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003615 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003616 psa_key_type_t key_type = key_type_arg;
3617 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003618 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003619 psa_status_t actual_status;
3620 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003621 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003622 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003623 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003624
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003625 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003626
Gilles Peskine8817f612018-12-18 00:18:46 +01003627 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003628
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003629 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003630 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003631 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003632
Gilles Peskine8817f612018-12-18 00:18:46 +01003633 PSA_ASSERT( psa_import_key( handle, key_type,
3634 key_data->x,
3635 key_data->len ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003636
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003637 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003638 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003639 signature, signature_size,
3640 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003641 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003642 /* The value of *signature_length is unspecified on error, but
3643 * whatever it is, it should be less than signature_size, so that
3644 * if the caller tries to read *signature_length bytes without
3645 * checking the error code then they don't overflow a buffer. */
3646 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003647
3648exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003649 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003650 mbedtls_free( signature );
3651 mbedtls_psa_crypto_free( );
3652}
3653/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003654
3655/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003656void sign_verify( int key_type_arg, data_t *key_data,
3657 int alg_arg, data_t *input_data )
3658{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003659 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003660 psa_key_type_t key_type = key_type_arg;
3661 psa_algorithm_t alg = alg_arg;
3662 size_t key_bits;
3663 unsigned char *signature = NULL;
3664 size_t signature_size;
3665 size_t signature_length = 0xdeadbeef;
Jaeden Amero70261c52019-01-04 11:47:20 +00003666 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003667
Gilles Peskine8817f612018-12-18 00:18:46 +01003668 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003669
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003670 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003671 psa_key_policy_set_usage( &policy,
3672 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
3673 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003674 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003675
Gilles Peskine8817f612018-12-18 00:18:46 +01003676 PSA_ASSERT( psa_import_key( handle, key_type,
3677 key_data->x,
3678 key_data->len ) );
3679 PSA_ASSERT( psa_get_key_information( handle,
3680 NULL,
3681 &key_bits ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003682
3683 /* Allocate a buffer which has the size advertized by the
3684 * library. */
3685 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3686 key_bits, alg );
3687 TEST_ASSERT( signature_size != 0 );
3688 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003689 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003690
3691 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003692 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3693 input_data->x, input_data->len,
3694 signature, signature_size,
3695 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003696 /* Check that the signature length looks sensible. */
3697 TEST_ASSERT( signature_length <= signature_size );
3698 TEST_ASSERT( signature_length > 0 );
3699
3700 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003701 PSA_ASSERT( psa_asymmetric_verify(
3702 handle, alg,
3703 input_data->x, input_data->len,
3704 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003705
3706 if( input_data->len != 0 )
3707 {
3708 /* Flip a bit in the input and verify that the signature is now
3709 * detected as invalid. Flip a bit at the beginning, not at the end,
3710 * because ECDSA may ignore the last few bits of the input. */
3711 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003712 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3713 input_data->x, input_data->len,
3714 signature, signature_length ),
3715 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003716 }
3717
3718exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003719 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003720 mbedtls_free( signature );
3721 mbedtls_psa_crypto_free( );
3722}
3723/* END_CASE */
3724
3725/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003726void asymmetric_verify( int key_type_arg, data_t *key_data,
3727 int alg_arg, data_t *hash_data,
3728 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003729{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003730 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003731 psa_key_type_t key_type = key_type_arg;
3732 psa_algorithm_t alg = alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003733 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003734
Gilles Peskine69c12672018-06-28 00:07:19 +02003735 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3736
Gilles Peskine8817f612018-12-18 00:18:46 +01003737 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003738
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003739 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003740 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003741 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
itayzafrir5c753392018-05-08 11:18:38 +03003742
Gilles Peskine8817f612018-12-18 00:18:46 +01003743 PSA_ASSERT( psa_import_key( handle, key_type,
3744 key_data->x,
3745 key_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003746
Gilles Peskine8817f612018-12-18 00:18:46 +01003747 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3748 hash_data->x, hash_data->len,
3749 signature_data->x,
3750 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003751exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003752 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003753 mbedtls_psa_crypto_free( );
3754}
3755/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003756
3757/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003758void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3759 int alg_arg, data_t *hash_data,
3760 data_t *signature_data,
3761 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003762{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003763 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003764 psa_key_type_t key_type = key_type_arg;
3765 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003766 psa_status_t actual_status;
3767 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003768 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003769
Gilles Peskine8817f612018-12-18 00:18:46 +01003770 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003771
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003772 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003773 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003774 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003775
Gilles Peskine8817f612018-12-18 00:18:46 +01003776 PSA_ASSERT( psa_import_key( handle, key_type,
3777 key_data->x,
3778 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003779
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003780 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003781 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003782 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003783 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003784
Gilles Peskinefe11b722018-12-18 00:24:04 +01003785 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003786
3787exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003788 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003789 mbedtls_psa_crypto_free( );
3790}
3791/* END_CASE */
3792
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003793/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003794void asymmetric_encrypt( int key_type_arg,
3795 data_t *key_data,
3796 int alg_arg,
3797 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003798 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003799 int expected_output_length_arg,
3800 int expected_status_arg )
3801{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003802 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003803 psa_key_type_t key_type = key_type_arg;
3804 psa_algorithm_t alg = alg_arg;
3805 size_t expected_output_length = expected_output_length_arg;
3806 size_t key_bits;
3807 unsigned char *output = NULL;
3808 size_t output_size;
3809 size_t output_length = ~0;
3810 psa_status_t actual_status;
3811 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00003812 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003813
Gilles Peskine8817f612018-12-18 00:18:46 +01003814 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003815
Gilles Peskine656896e2018-06-29 19:12:28 +02003816 /* Import the key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003817 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003818 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003819 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
3820 PSA_ASSERT( psa_import_key( handle, key_type,
3821 key_data->x,
3822 key_data->len ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003823
3824 /* Determine the maximum output length */
Gilles Peskine8817f612018-12-18 00:18:46 +01003825 PSA_ASSERT( psa_get_key_information( handle,
3826 NULL,
3827 &key_bits ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003828 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003829 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003830
3831 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003832 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003833 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003834 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003835 output, output_size,
3836 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003837 TEST_EQUAL( actual_status, expected_status );
3838 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003839
Gilles Peskine68428122018-06-30 18:42:41 +02003840 /* If the label is empty, the test framework puts a non-null pointer
3841 * in label->x. Test that a null pointer works as well. */
3842 if( label->len == 0 )
3843 {
3844 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003845 if( output_size != 0 )
3846 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003847 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003848 input_data->x, input_data->len,
3849 NULL, label->len,
3850 output, output_size,
3851 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003852 TEST_EQUAL( actual_status, expected_status );
3853 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003854 }
3855
Gilles Peskine656896e2018-06-29 19:12:28 +02003856exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003857 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003858 mbedtls_free( output );
3859 mbedtls_psa_crypto_free( );
3860}
3861/* END_CASE */
3862
3863/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003864void asymmetric_encrypt_decrypt( int key_type_arg,
3865 data_t *key_data,
3866 int alg_arg,
3867 data_t *input_data,
3868 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003869{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003870 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003871 psa_key_type_t key_type = key_type_arg;
3872 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003873 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003874 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003875 size_t output_size;
3876 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003877 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003878 size_t output2_size;
3879 size_t output2_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003880 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003881
Gilles Peskine8817f612018-12-18 00:18:46 +01003882 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003883
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003884 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003885 psa_key_policy_set_usage( &policy,
3886 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003887 alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003888 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003889
Gilles Peskine8817f612018-12-18 00:18:46 +01003890 PSA_ASSERT( psa_import_key( handle, key_type,
3891 key_data->x,
3892 key_data->len ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003893
3894 /* Determine the maximum ciphertext length */
Gilles Peskine8817f612018-12-18 00:18:46 +01003895 PSA_ASSERT( psa_get_key_information( handle,
3896 NULL,
3897 &key_bits ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003898 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003899 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003900 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003901 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003902
Gilles Peskineeebd7382018-06-08 18:11:54 +02003903 /* We test encryption by checking that encrypt-then-decrypt gives back
3904 * the original plaintext because of the non-optional random
3905 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003906 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3907 input_data->x, input_data->len,
3908 label->x, label->len,
3909 output, output_size,
3910 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003911 /* We don't know what ciphertext length to expect, but check that
3912 * it looks sensible. */
3913 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003914
Gilles Peskine8817f612018-12-18 00:18:46 +01003915 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3916 output, output_length,
3917 label->x, label->len,
3918 output2, output2_size,
3919 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003920 ASSERT_COMPARE( input_data->x, input_data->len,
3921 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003922
3923exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003924 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003925 mbedtls_free( output );
3926 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003927 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003928}
3929/* END_CASE */
3930
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003931/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003932void asymmetric_decrypt( int key_type_arg,
3933 data_t *key_data,
3934 int alg_arg,
3935 data_t *input_data,
3936 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003937 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003938{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003939 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003940 psa_key_type_t key_type = key_type_arg;
3941 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003942 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003943 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003944 size_t output_length = ~0;
Jaeden Amero70261c52019-01-04 11:47:20 +00003945 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003946
Jaeden Amero412654a2019-02-06 12:57:46 +00003947 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003948 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003949
Gilles Peskine8817f612018-12-18 00:18:46 +01003950 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003951
Gilles Peskined40c1fb2019-01-19 12:20:52 +01003952 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003953 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01003954 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003955
Gilles Peskine8817f612018-12-18 00:18:46 +01003956 PSA_ASSERT( psa_import_key( handle, key_type,
3957 key_data->x,
3958 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003959
Gilles Peskine8817f612018-12-18 00:18:46 +01003960 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3961 input_data->x, input_data->len,
3962 label->x, label->len,
3963 output,
3964 output_size,
3965 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003966 ASSERT_COMPARE( expected_data->x, expected_data->len,
3967 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003968
Gilles Peskine68428122018-06-30 18:42:41 +02003969 /* If the label is empty, the test framework puts a non-null pointer
3970 * in label->x. Test that a null pointer works as well. */
3971 if( label->len == 0 )
3972 {
3973 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003974 if( output_size != 0 )
3975 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003976 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3977 input_data->x, input_data->len,
3978 NULL, label->len,
3979 output,
3980 output_size,
3981 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003982 ASSERT_COMPARE( expected_data->x, expected_data->len,
3983 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003984 }
3985
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003986exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003987 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003988 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003989 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003990}
3991/* END_CASE */
3992
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003993/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003994void asymmetric_decrypt_fail( int key_type_arg,
3995 data_t *key_data,
3996 int alg_arg,
3997 data_t *input_data,
3998 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003999 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02004000 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004001{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004002 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004003 psa_key_type_t key_type = key_type_arg;
4004 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004005 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004006 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004007 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004008 psa_status_t actual_status;
4009 psa_status_t expected_status = expected_status_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00004010 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004011
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004012 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004013
Gilles Peskine8817f612018-12-18 00:18:46 +01004014 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004015
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004016 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02004017 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004018 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004019
Gilles Peskine8817f612018-12-18 00:18:46 +01004020 PSA_ASSERT( psa_import_key( handle, key_type,
4021 key_data->x,
4022 key_data->len ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004023
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004024 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004025 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004026 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004027 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004028 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004029 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004030 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004031
Gilles Peskine68428122018-06-30 18:42:41 +02004032 /* If the label is empty, the test framework puts a non-null pointer
4033 * in label->x. Test that a null pointer works as well. */
4034 if( label->len == 0 )
4035 {
4036 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004037 if( output_size != 0 )
4038 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004039 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004040 input_data->x, input_data->len,
4041 NULL, label->len,
4042 output, output_size,
4043 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004044 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004045 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004046 }
4047
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004048exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004049 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004050 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004051 mbedtls_psa_crypto_free( );
4052}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004053/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004054
4055/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00004056void crypto_generator_init( )
4057{
4058 /* Test each valid way of initializing the object, except for `= {0}`, as
4059 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4060 * though it's OK by the C standard. We could test for this, but we'd need
4061 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004062 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004063 psa_crypto_generator_t func = psa_crypto_generator_init( );
4064 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
4065 psa_crypto_generator_t zero;
4066
4067 memset( &zero, 0, sizeof( zero ) );
4068
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004069 /* A default generator should not be able to report its capacity. */
4070 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
4071 PSA_ERROR_BAD_STATE );
4072 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
4073 PSA_ERROR_BAD_STATE );
4074 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
4075 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004076
4077 /* A default generator should be abortable without error. */
4078 PSA_ASSERT( psa_generator_abort(&func) );
4079 PSA_ASSERT( psa_generator_abort(&init) );
4080 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004081}
4082/* END_CASE */
4083
4084/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004085void derive_setup( int key_type_arg,
4086 data_t *key_data,
4087 int alg_arg,
4088 data_t *salt,
4089 data_t *label,
4090 int requested_capacity_arg,
4091 int expected_status_arg )
4092{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004093 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004094 size_t key_type = key_type_arg;
4095 psa_algorithm_t alg = alg_arg;
4096 size_t requested_capacity = requested_capacity_arg;
4097 psa_status_t expected_status = expected_status_arg;
4098 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004099 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004100
Gilles Peskine8817f612018-12-18 00:18:46 +01004101 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004102
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004103 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004104 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004105 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004106
Gilles Peskine8817f612018-12-18 00:18:46 +01004107 PSA_ASSERT( psa_import_key( handle, key_type,
4108 key_data->x,
4109 key_data->len ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004110
Gilles Peskinefe11b722018-12-18 00:24:04 +01004111 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4112 salt->x, salt->len,
4113 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004114 requested_capacity ),
4115 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004116
4117exit:
4118 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004119 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004120 mbedtls_psa_crypto_free( );
4121}
4122/* END_CASE */
4123
4124/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004125void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004126{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004127 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004128 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004129 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004130 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004131 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004132 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004133 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4134 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4135 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Jaeden Amero70261c52019-01-04 11:47:20 +00004136 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004137
Gilles Peskine8817f612018-12-18 00:18:46 +01004138 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004139
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004140 PSA_ASSERT( psa_allocate_key( &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004141 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004142 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004143
Gilles Peskine8817f612018-12-18 00:18:46 +01004144 PSA_ASSERT( psa_import_key( handle, key_type,
4145 key_data,
4146 sizeof( key_data ) ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004147
4148 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004149 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4150 NULL, 0,
4151 NULL, 0,
4152 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004153
4154 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004155 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4156 NULL, 0,
4157 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004158 capacity ),
4159 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004160
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004161 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004162
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004163 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004164 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004165
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004166exit:
4167 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004168 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004169 mbedtls_psa_crypto_free( );
4170}
4171/* END_CASE */
4172
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004173/* BEGIN_CASE */
4174void test_derive_invalid_generator_tests( )
4175{
4176 uint8_t output_buffer[16];
4177 size_t buffer_size = 16;
4178 size_t capacity = 0;
4179 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4180
Nir Sonnenschein50789302018-10-31 12:16:38 +02004181 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004182 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004183
4184 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004185 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004186
Gilles Peskine8817f612018-12-18 00:18:46 +01004187 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004188
Nir Sonnenschein50789302018-10-31 12:16:38 +02004189 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004190 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004191
Nir Sonnenschein50789302018-10-31 12:16:38 +02004192 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004193 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004194
4195exit:
4196 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004197}
4198/* END_CASE */
4199
4200/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004201void derive_output( int alg_arg,
4202 data_t *key_data,
4203 data_t *salt,
4204 data_t *label,
4205 int requested_capacity_arg,
4206 data_t *expected_output1,
4207 data_t *expected_output2 )
4208{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004209 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004210 psa_algorithm_t alg = alg_arg;
4211 size_t requested_capacity = requested_capacity_arg;
4212 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4213 uint8_t *expected_outputs[2] =
4214 {expected_output1->x, expected_output2->x};
4215 size_t output_sizes[2] =
4216 {expected_output1->len, expected_output2->len};
4217 size_t output_buffer_size = 0;
4218 uint8_t *output_buffer = NULL;
4219 size_t expected_capacity;
4220 size_t current_capacity;
Jaeden Amero70261c52019-01-04 11:47:20 +00004221 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004222 psa_status_t status;
4223 unsigned i;
4224
4225 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4226 {
4227 if( output_sizes[i] > output_buffer_size )
4228 output_buffer_size = output_sizes[i];
4229 if( output_sizes[i] == 0 )
4230 expected_outputs[i] = NULL;
4231 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004232 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004233 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004234
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004235 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004236 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004237 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004238
Gilles Peskine8817f612018-12-18 00:18:46 +01004239 PSA_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
4240 key_data->x,
4241 key_data->len ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004242
4243 /* Extraction phase. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004244 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4245 salt->x, salt->len,
4246 label->x, label->len,
4247 requested_capacity ) );
4248 PSA_ASSERT( psa_get_generator_capacity( &generator,
4249 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004250 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004251 expected_capacity = requested_capacity;
4252
4253 /* Expansion phase. */
4254 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4255 {
4256 /* Read some bytes. */
4257 status = psa_generator_read( &generator,
4258 output_buffer, output_sizes[i] );
4259 if( expected_capacity == 0 && output_sizes[i] == 0 )
4260 {
4261 /* Reading 0 bytes when 0 bytes are available can go either way. */
4262 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004263 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004264 continue;
4265 }
4266 else if( expected_capacity == 0 ||
4267 output_sizes[i] > expected_capacity )
4268 {
4269 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004270 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004271 expected_capacity = 0;
4272 continue;
4273 }
4274 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004275 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004276 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004277 ASSERT_COMPARE( output_buffer, output_sizes[i],
4278 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004279 /* Check the generator status. */
4280 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004281 PSA_ASSERT( psa_get_generator_capacity( &generator,
4282 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004283 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004284 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004285 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004286
4287exit:
4288 mbedtls_free( output_buffer );
4289 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004290 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004291 mbedtls_psa_crypto_free( );
4292}
4293/* END_CASE */
4294
4295/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004296void derive_full( int alg_arg,
4297 data_t *key_data,
4298 data_t *salt,
4299 data_t *label,
4300 int requested_capacity_arg )
4301{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004302 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004303 psa_algorithm_t alg = alg_arg;
4304 size_t requested_capacity = requested_capacity_arg;
4305 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4306 unsigned char output_buffer[16];
4307 size_t expected_capacity = requested_capacity;
4308 size_t current_capacity;
Jaeden Amero70261c52019-01-04 11:47:20 +00004309 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004310
Gilles Peskine8817f612018-12-18 00:18:46 +01004311 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004312
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004313 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004314 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004315 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004316
Gilles Peskine8817f612018-12-18 00:18:46 +01004317 PSA_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
4318 key_data->x,
4319 key_data->len ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004320
4321 /* Extraction phase. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004322 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4323 salt->x, salt->len,
4324 label->x, label->len,
4325 requested_capacity ) );
4326 PSA_ASSERT( psa_get_generator_capacity( &generator,
4327 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004328 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004329
4330 /* Expansion phase. */
4331 while( current_capacity > 0 )
4332 {
4333 size_t read_size = sizeof( output_buffer );
4334 if( read_size > current_capacity )
4335 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004336 PSA_ASSERT( psa_generator_read( &generator,
4337 output_buffer,
4338 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004339 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004340 PSA_ASSERT( psa_get_generator_capacity( &generator,
4341 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004342 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004343 }
4344
4345 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004346 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004347 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004348
Gilles Peskine8817f612018-12-18 00:18:46 +01004349 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004350
4351exit:
4352 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004353 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004354 mbedtls_psa_crypto_free( );
4355}
4356/* END_CASE */
4357
4358/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004359void derive_key_exercise( int alg_arg,
4360 data_t *key_data,
4361 data_t *salt,
4362 data_t *label,
4363 int derived_type_arg,
4364 int derived_bits_arg,
4365 int derived_usage_arg,
4366 int derived_alg_arg )
4367{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004368 psa_key_handle_t base_handle = 0;
4369 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004370 psa_algorithm_t alg = alg_arg;
4371 psa_key_type_t derived_type = derived_type_arg;
4372 size_t derived_bits = derived_bits_arg;
4373 psa_key_usage_t derived_usage = derived_usage_arg;
4374 psa_algorithm_t derived_alg = derived_alg_arg;
4375 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4376 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004377 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004378 psa_key_type_t got_type;
4379 size_t got_bits;
4380
Gilles Peskine8817f612018-12-18 00:18:46 +01004381 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004382
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004383 PSA_ASSERT( psa_allocate_key( &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004384 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004385 PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) );
4386 PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
4387 key_data->x,
4388 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004389
4390 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004391 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4392 salt->x, salt->len,
4393 label->x, label->len,
4394 capacity ) );
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004395 PSA_ASSERT( psa_allocate_key( &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004396 psa_key_policy_set_usage( &policy, derived_usage, derived_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004397 PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
4398 PSA_ASSERT( psa_generator_import_key( derived_handle,
4399 derived_type,
4400 derived_bits,
4401 &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004402
4403 /* Test the key information */
Gilles Peskine8817f612018-12-18 00:18:46 +01004404 PSA_ASSERT( psa_get_key_information( derived_handle,
4405 &got_type,
4406 &got_bits ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004407 TEST_EQUAL( got_type, derived_type );
4408 TEST_EQUAL( got_bits, derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004409
4410 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004411 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004412 goto exit;
4413
4414exit:
4415 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004416 psa_destroy_key( base_handle );
4417 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004418 mbedtls_psa_crypto_free( );
4419}
4420/* END_CASE */
4421
4422/* BEGIN_CASE */
4423void derive_key_export( int alg_arg,
4424 data_t *key_data,
4425 data_t *salt,
4426 data_t *label,
4427 int bytes1_arg,
4428 int bytes2_arg )
4429{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004430 psa_key_handle_t base_handle = 0;
4431 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004432 psa_algorithm_t alg = alg_arg;
4433 size_t bytes1 = bytes1_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004434 size_t derived_bits = PSA_BYTES_TO_BITS( bytes1 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004435 size_t bytes2 = bytes2_arg;
4436 size_t capacity = bytes1 + bytes2;
4437 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004438 uint8_t *output_buffer = NULL;
4439 uint8_t *export_buffer = NULL;
Jaeden Amero70261c52019-01-04 11:47:20 +00004440 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004441 size_t length;
4442
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004443 ASSERT_ALLOC( output_buffer, capacity );
4444 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004445 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004446
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004447 PSA_ASSERT( psa_allocate_key( &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004448 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004449 PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) );
4450 PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
4451 key_data->x,
4452 key_data->len ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004453
4454 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004455 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4456 salt->x, salt->len,
4457 label->x, label->len,
4458 capacity ) );
4459 PSA_ASSERT( psa_generator_read( &generator,
4460 output_buffer,
4461 capacity ) );
4462 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004463
4464 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004465 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4466 salt->x, salt->len,
4467 label->x, label->len,
4468 capacity ) );
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004469 PSA_ASSERT( psa_allocate_key( &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004470 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004471 PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
4472 PSA_ASSERT( psa_generator_import_key( derived_handle,
4473 PSA_KEY_TYPE_RAW_DATA,
4474 derived_bits,
4475 &generator ) );
4476 PSA_ASSERT( psa_export_key( derived_handle,
4477 export_buffer, bytes1,
4478 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004479 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004480 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004481 PSA_ASSERT( psa_allocate_key( &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004482 PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
4483 PSA_ASSERT( psa_generator_import_key( derived_handle,
4484 PSA_KEY_TYPE_RAW_DATA,
4485 PSA_BYTES_TO_BITS( bytes2 ),
4486 &generator ) );
4487 PSA_ASSERT( psa_export_key( derived_handle,
4488 export_buffer + bytes1, bytes2,
4489 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004490 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004491
4492 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004493 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4494 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004495
4496exit:
4497 mbedtls_free( output_buffer );
4498 mbedtls_free( export_buffer );
4499 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004500 psa_destroy_key( base_handle );
4501 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004502 mbedtls_psa_crypto_free( );
4503}
4504/* END_CASE */
4505
4506/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004507void key_agreement_setup( int alg_arg,
4508 int our_key_type_arg, data_t *our_key_data,
4509 data_t *peer_key_data,
4510 int expected_status_arg )
4511{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004512 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004513 psa_algorithm_t alg = alg_arg;
4514 psa_key_type_t our_key_type = our_key_type_arg;
4515 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004516 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004517
Gilles Peskine8817f612018-12-18 00:18:46 +01004518 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004519
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004520 PSA_ASSERT( psa_allocate_key( &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004521 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004522 PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
4523 PSA_ASSERT( psa_import_key( our_key, our_key_type,
4524 our_key_data->x,
4525 our_key_data->len ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004526
Gilles Peskinefe11b722018-12-18 00:24:04 +01004527 TEST_EQUAL( psa_key_agreement( &generator,
4528 our_key,
4529 peer_key_data->x, peer_key_data->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004530 alg ),
4531 expected_status_arg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004532
4533exit:
4534 psa_generator_abort( &generator );
4535 psa_destroy_key( our_key );
4536 mbedtls_psa_crypto_free( );
4537}
4538/* END_CASE */
4539
4540/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004541void key_agreement_capacity( int alg_arg,
4542 int our_key_type_arg, data_t *our_key_data,
4543 data_t *peer_key_data,
4544 int expected_capacity_arg )
4545{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004546 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004547 psa_algorithm_t alg = alg_arg;
4548 psa_key_type_t our_key_type = our_key_type_arg;
4549 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004550 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004551 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004552 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004553
Gilles Peskine8817f612018-12-18 00:18:46 +01004554 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004555
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004556 PSA_ASSERT( psa_allocate_key( &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +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 Peskine59685592018-09-18 12:11:34 +02004562
Gilles Peskine8817f612018-12-18 00:18:46 +01004563 PSA_ASSERT( psa_key_agreement( &generator,
4564 our_key,
4565 peer_key_data->x, peer_key_data->len,
4566 alg ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004567
Gilles Peskinebf491972018-10-25 22:36:12 +02004568 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004569 PSA_ASSERT( psa_get_generator_capacity(
4570 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004571 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004572
Gilles Peskinebf491972018-10-25 22:36:12 +02004573 /* Test the actual capacity by reading the output. */
4574 while( actual_capacity > sizeof( output ) )
4575 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004576 PSA_ASSERT( psa_generator_read( &generator,
4577 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004578 actual_capacity -= sizeof( output );
4579 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004580 PSA_ASSERT( psa_generator_read( &generator,
4581 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004582 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004583 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004584
Gilles Peskine59685592018-09-18 12:11:34 +02004585exit:
4586 psa_generator_abort( &generator );
4587 psa_destroy_key( our_key );
4588 mbedtls_psa_crypto_free( );
4589}
4590/* END_CASE */
4591
4592/* BEGIN_CASE */
4593void key_agreement_output( int alg_arg,
4594 int our_key_type_arg, data_t *our_key_data,
4595 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004596 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004597{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004598 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004599 psa_algorithm_t alg = alg_arg;
4600 psa_key_type_t our_key_type = our_key_type_arg;
4601 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Jaeden Amero70261c52019-01-04 11:47:20 +00004602 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004603 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004604
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004605 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4606 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004607
Gilles Peskine8817f612018-12-18 00:18:46 +01004608 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004609
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004610 PSA_ASSERT( psa_allocate_key( &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004611 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004612 PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
4613 PSA_ASSERT( psa_import_key( our_key, our_key_type,
4614 our_key_data->x,
4615 our_key_data->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004616
Gilles Peskine8817f612018-12-18 00:18:46 +01004617 PSA_ASSERT( psa_key_agreement( &generator,
4618 our_key,
4619 peer_key_data->x, peer_key_data->len,
4620 alg ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004621
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004622 PSA_ASSERT( psa_generator_read( &generator,
4623 actual_output,
4624 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004625 ASSERT_COMPARE( actual_output, expected_output1->len,
4626 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004627 if( expected_output2->len != 0 )
4628 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004629 PSA_ASSERT( psa_generator_read( &generator,
4630 actual_output,
4631 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004632 ASSERT_COMPARE( actual_output, expected_output2->len,
4633 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004634 }
Gilles Peskine59685592018-09-18 12:11:34 +02004635
4636exit:
4637 psa_generator_abort( &generator );
4638 psa_destroy_key( our_key );
4639 mbedtls_psa_crypto_free( );
4640 mbedtls_free( actual_output );
4641}
4642/* END_CASE */
4643
4644/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004645void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004646{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004647 size_t bytes = bytes_arg;
4648 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004649 unsigned char *output = NULL;
4650 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004651 size_t i;
4652 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004653
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004654 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4655 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004656 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004657
Gilles Peskine8817f612018-12-18 00:18:46 +01004658 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004659
Gilles Peskinea50d7392018-06-21 10:22:13 +02004660 /* Run several times, to ensure that every output byte will be
4661 * nonzero at least once with overwhelming probability
4662 * (2^(-8*number_of_runs)). */
4663 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004664 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004665 if( bytes != 0 )
4666 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004667 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004668
4669 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004670 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4671 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004672
4673 for( i = 0; i < bytes; i++ )
4674 {
4675 if( output[i] != 0 )
4676 ++changed[i];
4677 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004678 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004679
4680 /* Check that every byte was changed to nonzero at least once. This
4681 * validates that psa_generate_random is overwriting every byte of
4682 * the output buffer. */
4683 for( i = 0; i < bytes; i++ )
4684 {
4685 TEST_ASSERT( changed[i] != 0 );
4686 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004687
4688exit:
4689 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004690 mbedtls_free( output );
4691 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004692}
4693/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004694
4695/* BEGIN_CASE */
4696void generate_key( int type_arg,
4697 int bits_arg,
4698 int usage_arg,
4699 int alg_arg,
4700 int expected_status_arg )
4701{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004702 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004703 psa_key_type_t type = type_arg;
4704 psa_key_usage_t usage = usage_arg;
4705 size_t bits = bits_arg;
4706 psa_algorithm_t alg = alg_arg;
4707 psa_status_t expected_status = expected_status_arg;
4708 psa_key_type_t got_type;
4709 size_t got_bits;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004710 psa_status_t expected_info_status =
David Saadab4ecc272019-02-14 13:48:10 +02004711 expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
Jaeden Amero70261c52019-01-04 11:47:20 +00004712 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004713
Gilles Peskine8817f612018-12-18 00:18:46 +01004714 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004715
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004716 PSA_ASSERT( psa_allocate_key( &handle ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004717 psa_key_policy_set_usage( &policy, usage, alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004718 PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004719
4720 /* Generate a key */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004721 TEST_EQUAL( psa_generate_key( handle, type, bits, NULL, 0 ),
4722 expected_status );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004723
4724 /* Test the key information */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004725 TEST_EQUAL( psa_get_key_information( handle, &got_type, &got_bits ),
4726 expected_info_status );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004727 if( expected_info_status != PSA_SUCCESS )
4728 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01004729 TEST_EQUAL( got_type, type );
4730 TEST_EQUAL( got_bits, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004731
Gilles Peskine818ca122018-06-20 18:16:48 +02004732 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004733 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004734 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004735
4736exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004737 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004738 mbedtls_psa_crypto_free( );
4739}
4740/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004741
Darryl Greend49a4992018-06-18 17:27:26 +01004742/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
4743void persistent_key_load_key_from_storage( data_t *data, int type_arg,
4744 int bits, int usage_arg,
Darryl Green0c6575a2018-11-07 16:05:30 +00004745 int alg_arg, int generation_method,
4746 int export_status )
Darryl Greend49a4992018-06-18 17:27:26 +01004747{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004748 psa_key_handle_t handle = 0;
4749 psa_key_handle_t base_key;
Darryl Greend49a4992018-06-18 17:27:26 +01004750 psa_key_type_t type = (psa_key_type_t) type_arg;
4751 psa_key_type_t type_get;
4752 size_t bits_get;
Jaeden Amero70261c52019-01-04 11:47:20 +00004753 psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT;
4754 psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004755 psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg;
4756 psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg;
Jaeden Amero70261c52019-01-04 11:47:20 +00004757 psa_key_policy_t base_policy_set = PSA_KEY_POLICY_INIT;
Darryl Green0c6575a2018-11-07 16:05:30 +00004758 psa_algorithm_t base_policy_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
4759 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004760 unsigned char *first_export = NULL;
4761 unsigned char *second_export = NULL;
4762 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4763 size_t first_exported_length;
4764 size_t second_exported_length;
4765
4766 ASSERT_ALLOC( first_export, export_size );
4767 ASSERT_ALLOC( second_export, export_size );
4768
Gilles Peskine8817f612018-12-18 00:18:46 +01004769 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004770
Gilles Peskine8817f612018-12-18 00:18:46 +01004771 PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
Gilles Peskine8817f612018-12-18 00:18:46 +01004772 &handle ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004773 psa_key_policy_set_usage( &policy_set, policy_usage,
4774 policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004775 PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
Darryl Greend49a4992018-06-18 17:27:26 +01004776
Darryl Green0c6575a2018-11-07 16:05:30 +00004777 switch( generation_method )
4778 {
4779 case IMPORT_KEY:
4780 /* Import the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01004781 PSA_ASSERT( psa_import_key( handle, type,
4782 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004783 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004784
Darryl Green0c6575a2018-11-07 16:05:30 +00004785 case GENERATE_KEY:
4786 /* Generate a key */
Gilles Peskine8817f612018-12-18 00:18:46 +01004787 PSA_ASSERT( psa_generate_key( handle, type, bits,
4788 NULL, 0 ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004789 break;
4790
4791 case DERIVE_KEY:
4792 /* Create base key */
Gilles Peskined40c1fb2019-01-19 12:20:52 +01004793 PSA_ASSERT( psa_allocate_key( &base_key ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004794 psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE,
4795 base_policy_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +01004796 PSA_ASSERT( psa_set_key_policy(
4797 base_key, &base_policy_set ) );
4798 PSA_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
4799 data->x, data->len ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004800 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004801 PSA_ASSERT( psa_key_derivation( &generator, base_key,
4802 base_policy_alg,
4803 NULL, 0, NULL, 0,
4804 export_size ) );
4805 PSA_ASSERT( psa_generator_import_key(
4806 handle, PSA_KEY_TYPE_RAW_DATA,
4807 bits, &generator ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004808 break;
4809 }
Darryl Greend49a4992018-06-18 17:27:26 +01004810
4811 /* Export the key */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004812 TEST_EQUAL( psa_export_key( handle,
4813 first_export, export_size,
4814 &first_exported_length ),
4815 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004816
4817 /* Shutdown and restart */
4818 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004819 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004820
Darryl Greend49a4992018-06-18 17:27:26 +01004821 /* Check key slot still contains key data */
Gilles Peskine8817f612018-12-18 00:18:46 +01004822 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
4823 &handle ) );
4824 PSA_ASSERT( psa_get_key_information(
4825 handle, &type_get, &bits_get ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004826 TEST_EQUAL( type_get, type );
4827 TEST_EQUAL( bits_get, (size_t) bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004828
Gilles Peskine8817f612018-12-18 00:18:46 +01004829 PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004830 TEST_EQUAL( psa_key_policy_get_usage( &policy_get ), policy_usage );
4831 TEST_EQUAL( psa_key_policy_get_algorithm( &policy_get ), policy_alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004832
4833 /* Export the key again */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004834 TEST_EQUAL( psa_export_key( handle,
4835 second_export, export_size,
4836 &second_exported_length ),
4837 export_status );
Darryl Greend49a4992018-06-18 17:27:26 +01004838
Darryl Green0c6575a2018-11-07 16:05:30 +00004839 if( export_status == PSA_SUCCESS )
4840 {
4841 ASSERT_COMPARE( first_export, first_exported_length,
4842 second_export, second_exported_length );
Darryl Greend49a4992018-06-18 17:27:26 +01004843
Darryl Green0c6575a2018-11-07 16:05:30 +00004844 switch( generation_method )
4845 {
4846 case IMPORT_KEY:
4847 ASSERT_COMPARE( data->x, data->len,
4848 first_export, first_exported_length );
4849 break;
4850 default:
4851 break;
4852 }
4853 }
4854
4855 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004856 if( ! exercise_key( handle, policy_usage, policy_alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004857 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004858
4859exit:
4860 mbedtls_free( first_export );
4861 mbedtls_free( second_export );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004862 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004863 mbedtls_psa_crypto_free();
4864}
4865/* END_CASE */