blob: 52b92ca6d8185b90940100217fef6c6b8e2b7a35 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/* BEGIN_HEADER */
itayzafrir3e02b3b2018-06-12 17:06:52 +03002#include <stdint.h>
mohammad160327010052018-07-03 13:16:15 +03003
4#if defined(MBEDTLS_PSA_CRYPTO_SPM)
5#include "spm/psa_defs.h"
6#endif
7
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02008#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02009#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +020010#include "mbedtls/oid.h"
11
Gilles Peskinee59236f2018-01-27 23:32:46 +010012#include "psa/crypto.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +030013
Jaeden Amerof24c7f82018-06-27 17:20:43 +010014/** An invalid export length that will never be set by psa_export_key(). */
15static const size_t INVALID_EXPORT_LENGTH = ~0U;
16
Gilles Peskinef426e0f2019-02-25 17:42:03 +010017/* A hash algorithm that is known to be supported.
18 *
19 * This is used in some smoke tests.
20 */
21#if defined(MBEDTLS_MD2_C)
22#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
23#elif defined(MBEDTLS_MD4_C)
24#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
25#elif defined(MBEDTLS_MD5_C)
26#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
27/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
28 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
29 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
30 * implausible anyway. */
31#elif defined(MBEDTLS_SHA1_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
33#elif defined(MBEDTLS_SHA256_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
35#elif defined(MBEDTLS_SHA512_C)
36#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
37#elif defined(MBEDTLS_SHA3_C)
38#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
39#else
40#undef KNOWN_SUPPORTED_HASH_ALG
41#endif
42
43/* A block cipher that is known to be supported.
44 *
45 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
46 */
47#if defined(MBEDTLS_AES_C)
48#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
49#elif defined(MBEDTLS_ARIA_C)
50#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
51#elif defined(MBEDTLS_CAMELLIA_C)
52#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
53#undef KNOWN_SUPPORTED_BLOCK_CIPHER
54#endif
55
56/* A MAC mode that is known to be supported.
57 *
58 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
59 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
60 *
61 * This is used in some smoke tests.
62 */
63#if defined(KNOWN_SUPPORTED_HASH_ALG)
64#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
65#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
66#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
67#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
68#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
69#else
70#undef KNOWN_SUPPORTED_MAC_ALG
71#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
72#endif
73
74/* A cipher algorithm and key type that are known to be supported.
75 *
76 * This is used in some smoke tests.
77 */
78#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
79#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
80#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
81#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
82#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
83#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
84#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
85#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
86#else
87#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
88#endif
89#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
90#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
91#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
92#elif defined(MBEDTLS_RC4_C)
93#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
94#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
95#else
96#undef KNOWN_SUPPORTED_CIPHER_ALG
97#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
98#endif
99
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200100/** Test if a buffer contains a constant byte value.
101 *
102 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200103 *
104 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200105 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200106 * \param size Size of the buffer in bytes.
107 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200108 * \return 1 if the buffer is all-bits-zero.
109 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200110 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200111static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200112{
113 size_t i;
114 for( i = 0; i < size; i++ )
115 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200116 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200117 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200118 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200119 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200120}
Gilles Peskine818ca122018-06-20 18:16:48 +0200121
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200122/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
123static int asn1_write_10x( unsigned char **p,
124 unsigned char *start,
125 size_t bits,
126 unsigned char x )
127{
128 int ret;
129 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200130 if( bits == 0 )
131 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
132 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200133 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300134 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200135 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
136 *p -= len;
137 ( *p )[len-1] = x;
138 if( bits % 8 == 0 )
139 ( *p )[1] |= 1;
140 else
141 ( *p )[0] |= 1 << ( bits % 8 );
142 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
143 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
144 MBEDTLS_ASN1_INTEGER ) );
145 return( len );
146}
147
148static int construct_fake_rsa_key( unsigned char *buffer,
149 size_t buffer_size,
150 unsigned char **p,
151 size_t bits,
152 int keypair )
153{
154 size_t half_bits = ( bits + 1 ) / 2;
155 int ret;
156 int len = 0;
157 /* Construct something that looks like a DER encoding of
158 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
159 * RSAPrivateKey ::= SEQUENCE {
160 * version Version,
161 * modulus INTEGER, -- n
162 * publicExponent INTEGER, -- e
163 * privateExponent INTEGER, -- d
164 * prime1 INTEGER, -- p
165 * prime2 INTEGER, -- q
166 * exponent1 INTEGER, -- d mod (p-1)
167 * exponent2 INTEGER, -- d mod (q-1)
168 * coefficient INTEGER, -- (inverse of q) mod p
169 * otherPrimeInfos OtherPrimeInfos OPTIONAL
170 * }
171 * Or, for a public key, the same structure with only
172 * version, modulus and publicExponent.
173 */
174 *p = buffer + buffer_size;
175 if( keypair )
176 {
177 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
178 asn1_write_10x( p, buffer, half_bits, 1 ) );
179 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
180 asn1_write_10x( p, buffer, half_bits, 1 ) );
181 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
182 asn1_write_10x( p, buffer, half_bits, 1 ) );
183 MBEDTLS_ASN1_CHK_ADD( len, /* q */
184 asn1_write_10x( p, buffer, half_bits, 1 ) );
185 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
186 asn1_write_10x( p, buffer, half_bits, 3 ) );
187 MBEDTLS_ASN1_CHK_ADD( len, /* d */
188 asn1_write_10x( p, buffer, bits, 1 ) );
189 }
190 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
191 asn1_write_10x( p, buffer, 17, 1 ) );
192 MBEDTLS_ASN1_CHK_ADD( len, /* n */
193 asn1_write_10x( p, buffer, bits, 1 ) );
194 if( keypair )
195 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
196 mbedtls_asn1_write_int( p, buffer, 0 ) );
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
198 {
199 const unsigned char tag =
200 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
201 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
202 }
203 return( len );
204}
205
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100206int exercise_mac_setup( psa_key_type_t key_type,
207 const unsigned char *key_bytes,
208 size_t key_length,
209 psa_algorithm_t alg,
210 psa_mac_operation_t *operation,
211 psa_status_t *status )
212{
213 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200214 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100215
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200216 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
217 psa_set_key_algorithm( &attributes, alg );
218 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200219 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
220 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100221
222 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100223 /* Whether setup succeeded or failed, abort must succeed. */
224 PSA_ASSERT( psa_mac_abort( operation ) );
225 /* If setup failed, reproduce the failure, so that the caller can
226 * test the resulting state of the operation object. */
227 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100228 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100229 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
230 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100231 }
232
233 psa_destroy_key( handle );
234 return( 1 );
235
236exit:
237 psa_destroy_key( handle );
238 return( 0 );
239}
240
241int exercise_cipher_setup( psa_key_type_t key_type,
242 const unsigned char *key_bytes,
243 size_t key_length,
244 psa_algorithm_t alg,
245 psa_cipher_operation_t *operation,
246 psa_status_t *status )
247{
248 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200249 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100250
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200251 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
252 psa_set_key_algorithm( &attributes, alg );
253 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200254 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
255 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100256
257 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100258 /* Whether setup succeeded or failed, abort must succeed. */
259 PSA_ASSERT( psa_cipher_abort( operation ) );
260 /* If setup failed, reproduce the failure, so that the caller can
261 * test the resulting state of the operation object. */
262 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100263 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100264 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
265 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100266 }
267
268 psa_destroy_key( handle );
269 return( 1 );
270
271exit:
272 psa_destroy_key( handle );
273 return( 0 );
274}
275
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100276static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200277 psa_key_usage_t usage,
278 psa_algorithm_t alg )
279{
Jaeden Amero769ce272019-01-04 11:48:03 +0000280 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200281 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200282 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200283 size_t mac_length = sizeof( mac );
284
285 if( usage & PSA_KEY_USAGE_SIGN )
286 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100287 PSA_ASSERT( psa_mac_sign_setup( &operation,
288 handle, alg ) );
289 PSA_ASSERT( psa_mac_update( &operation,
290 input, sizeof( input ) ) );
291 PSA_ASSERT( psa_mac_sign_finish( &operation,
292 mac, sizeof( mac ),
293 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200294 }
295
296 if( usage & PSA_KEY_USAGE_VERIFY )
297 {
298 psa_status_t verify_status =
299 ( usage & PSA_KEY_USAGE_SIGN ?
300 PSA_SUCCESS :
301 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100302 PSA_ASSERT( psa_mac_verify_setup( &operation,
303 handle, alg ) );
304 PSA_ASSERT( psa_mac_update( &operation,
305 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100306 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
307 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200308 }
309
310 return( 1 );
311
312exit:
313 psa_mac_abort( &operation );
314 return( 0 );
315}
316
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100317static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200318 psa_key_usage_t usage,
319 psa_algorithm_t alg )
320{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000321 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200322 unsigned char iv[16] = {0};
323 size_t iv_length = sizeof( iv );
324 const unsigned char plaintext[16] = "Hello, world...";
325 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
326 size_t ciphertext_length = sizeof( ciphertext );
327 unsigned char decrypted[sizeof( ciphertext )];
328 size_t part_length;
329
330 if( usage & PSA_KEY_USAGE_ENCRYPT )
331 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100332 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
333 handle, alg ) );
334 PSA_ASSERT( psa_cipher_generate_iv( &operation,
335 iv, sizeof( iv ),
336 &iv_length ) );
337 PSA_ASSERT( psa_cipher_update( &operation,
338 plaintext, sizeof( plaintext ),
339 ciphertext, sizeof( ciphertext ),
340 &ciphertext_length ) );
341 PSA_ASSERT( psa_cipher_finish( &operation,
342 ciphertext + ciphertext_length,
343 sizeof( ciphertext ) - ciphertext_length,
344 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200345 ciphertext_length += part_length;
346 }
347
348 if( usage & PSA_KEY_USAGE_DECRYPT )
349 {
350 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200351 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200352 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
353 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200354 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
355 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
356 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
357 * have this macro yet. */
358 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
359 psa_get_key_type( &attributes ) );
360 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200361 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100362 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
363 handle, alg ) );
364 PSA_ASSERT( psa_cipher_set_iv( &operation,
365 iv, iv_length ) );
366 PSA_ASSERT( psa_cipher_update( &operation,
367 ciphertext, ciphertext_length,
368 decrypted, sizeof( decrypted ),
369 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200370 status = psa_cipher_finish( &operation,
371 decrypted + part_length,
372 sizeof( decrypted ) - part_length,
373 &part_length );
374 /* For a stream cipher, all inputs are valid. For a block cipher,
375 * if the input is some aribtrary data rather than an actual
376 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200377 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200378 TEST_ASSERT( status == PSA_SUCCESS ||
379 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200380 else
381 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200382 }
383
384 return( 1 );
385
386exit:
387 psa_cipher_abort( &operation );
388 return( 0 );
389}
390
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100391static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200392 psa_key_usage_t usage,
393 psa_algorithm_t alg )
394{
395 unsigned char nonce[16] = {0};
396 size_t nonce_length = sizeof( nonce );
397 unsigned char plaintext[16] = "Hello, world...";
398 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
399 size_t ciphertext_length = sizeof( ciphertext );
400 size_t plaintext_length = sizeof( ciphertext );
401
402 if( usage & PSA_KEY_USAGE_ENCRYPT )
403 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100404 PSA_ASSERT( psa_aead_encrypt( handle, alg,
405 nonce, nonce_length,
406 NULL, 0,
407 plaintext, sizeof( plaintext ),
408 ciphertext, sizeof( ciphertext ),
409 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200410 }
411
412 if( usage & PSA_KEY_USAGE_DECRYPT )
413 {
414 psa_status_t verify_status =
415 ( usage & PSA_KEY_USAGE_ENCRYPT ?
416 PSA_SUCCESS :
417 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100418 TEST_EQUAL( psa_aead_decrypt( handle, alg,
419 nonce, nonce_length,
420 NULL, 0,
421 ciphertext, ciphertext_length,
422 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100423 &plaintext_length ),
424 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200425 }
426
427 return( 1 );
428
429exit:
430 return( 0 );
431}
432
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100433static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200434 psa_key_usage_t usage,
435 psa_algorithm_t alg )
436{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200437 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
438 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200439 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200440 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100441 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
442
443 /* If the policy allows signing with any hash, just pick one. */
444 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
445 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100446#if defined(KNOWN_SUPPORTED_HASH_ALG)
447 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
448 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100449#else
450 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100451 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100452#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100453 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200454
455 if( usage & PSA_KEY_USAGE_SIGN )
456 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200457 /* Some algorithms require the payload to have the size of
458 * the hash encoded in the algorithm. Use this input size
459 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200460 if( hash_alg != 0 )
461 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100462 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
463 payload, payload_length,
464 signature, sizeof( signature ),
465 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200466 }
467
468 if( usage & PSA_KEY_USAGE_VERIFY )
469 {
470 psa_status_t verify_status =
471 ( usage & PSA_KEY_USAGE_SIGN ?
472 PSA_SUCCESS :
473 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100474 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
475 payload, payload_length,
476 signature, signature_length ),
477 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200478 }
479
480 return( 1 );
481
482exit:
483 return( 0 );
484}
485
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100486static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200487 psa_key_usage_t usage,
488 psa_algorithm_t alg )
489{
490 unsigned char plaintext[256] = "Hello, world...";
491 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
492 size_t ciphertext_length = sizeof( ciphertext );
493 size_t plaintext_length = 16;
494
495 if( usage & PSA_KEY_USAGE_ENCRYPT )
496 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100497 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
498 plaintext, plaintext_length,
499 NULL, 0,
500 ciphertext, sizeof( ciphertext ),
501 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200502 }
503
504 if( usage & PSA_KEY_USAGE_DECRYPT )
505 {
506 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100507 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200508 ciphertext, ciphertext_length,
509 NULL, 0,
510 plaintext, sizeof( plaintext ),
511 &plaintext_length );
512 TEST_ASSERT( status == PSA_SUCCESS ||
513 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
514 ( status == PSA_ERROR_INVALID_ARGUMENT ||
515 status == PSA_ERROR_INVALID_PADDING ) ) );
516 }
517
518 return( 1 );
519
520exit:
521 return( 0 );
522}
Gilles Peskine02b75072018-07-01 22:31:34 +0200523
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100524static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200525 psa_key_usage_t usage,
526 psa_algorithm_t alg )
527{
528 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
529 unsigned char label[16] = "This is a label.";
530 size_t label_length = sizeof( label );
531 unsigned char seed[16] = "abcdefghijklmnop";
532 size_t seed_length = sizeof( seed );
533 unsigned char output[1];
534
535 if( usage & PSA_KEY_USAGE_DERIVE )
536 {
Gilles Peskineb70a0fd2019-01-07 22:59:38 +0100537 if( PSA_ALG_IS_HKDF( alg ) )
538 {
539 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
540 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
541 PSA_KDF_STEP_SALT,
542 label,
543 label_length ) );
544 PSA_ASSERT( psa_key_derivation_input_key( &generator,
545 PSA_KDF_STEP_SECRET,
546 handle ) );
547 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
548 PSA_KDF_STEP_INFO,
549 seed,
550 seed_length ) );
551 }
552 else
553 {
554 // legacy
555 PSA_ASSERT( psa_key_derivation( &generator,
556 handle, alg,
557 label, label_length,
558 seed, seed_length,
559 sizeof( output ) ) );
560 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100561 PSA_ASSERT( psa_generator_read( &generator,
562 output,
563 sizeof( output ) ) );
564 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200565 }
566
567 return( 1 );
568
569exit:
570 return( 0 );
571}
572
Gilles Peskinec7998b72018-11-07 18:45:02 +0100573/* We need two keys to exercise key agreement. Exercise the
574 * private key against its own public key. */
575static psa_status_t key_agreement_with_self( psa_crypto_generator_t *generator,
Gilles Peskine969c5d62019-01-16 15:53:06 +0100576 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100577{
578 psa_key_type_t private_key_type;
579 psa_key_type_t public_key_type;
580 size_t key_bits;
581 uint8_t *public_key = NULL;
582 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200583 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinec7998b72018-11-07 18:45:02 +0100584 * psa_key_agreement fails. This isn't fully satisfactory, but it's
585 * good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200586 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200587 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100588
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200589 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
590 private_key_type = psa_get_key_type( &attributes );
591 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100592 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
593 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
594 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100595 PSA_ASSERT( psa_export_public_key( handle,
596 public_key, public_key_length,
597 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100598
Gilles Peskine969c5d62019-01-16 15:53:06 +0100599 status = psa_key_agreement( generator, PSA_KDF_STEP_SECRET, handle,
600 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100601exit:
602 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200603 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100604 return( status );
605}
606
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200607/* We need two keys to exercise key agreement. Exercise the
608 * private key against its own public key. */
609static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
610 psa_key_handle_t handle )
611{
612 psa_key_type_t private_key_type;
613 psa_key_type_t public_key_type;
614 size_t key_bits;
615 uint8_t *public_key = NULL;
616 size_t public_key_length;
617 uint8_t output[1024];
618 size_t output_length;
619 /* Return GENERIC_ERROR if something other than the final call to
620 * psa_key_agreement fails. This isn't fully satisfactory, but it's
621 * good enough: callers will report it as a failed test anyway. */
622 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200623 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200624
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200625 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
626 private_key_type = psa_get_key_type( &attributes );
627 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200628 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
629 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
630 ASSERT_ALLOC( public_key, public_key_length );
631 PSA_ASSERT( psa_export_public_key( handle,
632 public_key, public_key_length,
633 &public_key_length ) );
634
635 status = psa_key_agreement_raw_shared_secret(
636 alg, handle,
637 public_key, public_key_length,
638 output, sizeof( output ), &output_length );
639exit:
640 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200641 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200642 return( status );
643}
644
645static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
646 psa_key_usage_t usage,
647 psa_algorithm_t alg )
648{
649 int ok = 0;
650
651 if( usage & PSA_KEY_USAGE_DERIVE )
652 {
653 /* We need two keys to exercise key agreement. Exercise the
654 * private key against its own public key. */
655 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
656 }
657 ok = 1;
658
659exit:
660 return( ok );
661}
662
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100663static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200664 psa_key_usage_t usage,
665 psa_algorithm_t alg )
666{
667 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200668 unsigned char output[1];
669 int ok = 0;
670
671 if( usage & PSA_KEY_USAGE_DERIVE )
672 {
673 /* We need two keys to exercise key agreement. Exercise the
674 * private key against its own public key. */
Gilles Peskine969c5d62019-01-16 15:53:06 +0100675 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
676 PSA_ASSERT( key_agreement_with_self( &generator, handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +0100677 PSA_ASSERT( psa_generator_read( &generator,
678 output,
679 sizeof( output ) ) );
680 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200681 }
682 ok = 1;
683
684exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200685 return( ok );
686}
687
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200688static int is_oid_of_key_type( psa_key_type_t type,
689 const uint8_t *oid, size_t oid_length )
690{
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200691 const uint8_t *expected_oid = NULL;
692 size_t expected_oid_length = 0;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200693#if defined(MBEDTLS_RSA_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200694 if( PSA_KEY_TYPE_IS_RSA( type ) )
695 {
696 expected_oid = (uint8_t *) MBEDTLS_OID_PKCS1_RSA;
697 expected_oid_length = sizeof( MBEDTLS_OID_PKCS1_RSA ) - 1;
698 }
699 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200700#endif /* MBEDTLS_RSA_C */
701#if defined(MBEDTLS_ECP_C)
Gilles Peskineae3d2a22018-08-13 14:14:22 +0200702 if( PSA_KEY_TYPE_IS_ECC( type ) )
703 {
704 expected_oid = (uint8_t *) MBEDTLS_OID_EC_ALG_UNRESTRICTED;
705 expected_oid_length = sizeof( MBEDTLS_OID_EC_ALG_UNRESTRICTED ) - 1;
706 }
707 else
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200708#endif /* MBEDTLS_ECP_C */
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200709 {
710 char message[40];
711 mbedtls_snprintf( message, sizeof( message ),
712 "OID not known for key type=0x%08lx",
713 (unsigned long) type );
714 test_fail( message, __LINE__, __FILE__ );
715 return( 0 );
716 }
717
Gilles Peskinebd7dea92018-09-27 13:57:19 +0200718 ASSERT_COMPARE( expected_oid, expected_oid_length, oid, oid_length );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200719 return( 1 );
720
721exit:
722 return( 0 );
723}
724
725static int asn1_skip_integer( unsigned char **p, const unsigned char *end,
726 size_t min_bits, size_t max_bits,
727 int must_be_odd )
728{
729 size_t len;
730 size_t actual_bits;
731 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100732 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100733 MBEDTLS_ASN1_INTEGER ),
734 0 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200735 /* Tolerate a slight departure from DER encoding:
736 * - 0 may be represented by an empty string or a 1-byte string.
737 * - The sign bit may be used as a value bit. */
738 if( ( len == 1 && ( *p )[0] == 0 ) ||
739 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
740 {
741 ++( *p );
742 --len;
743 }
744 if( min_bits == 0 && len == 0 )
745 return( 1 );
746 msb = ( *p )[0];
747 TEST_ASSERT( msb != 0 );
748 actual_bits = 8 * ( len - 1 );
749 while( msb != 0 )
750 {
751 msb >>= 1;
752 ++actual_bits;
753 }
754 TEST_ASSERT( actual_bits >= min_bits );
755 TEST_ASSERT( actual_bits <= max_bits );
756 if( must_be_odd )
757 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
758 *p += len;
759 return( 1 );
760exit:
761 return( 0 );
762}
763
764static int asn1_get_implicit_tag( unsigned char **p, const unsigned char *end,
765 size_t *len,
766 unsigned char n, unsigned char tag )
767{
768 int ret;
769 ret = mbedtls_asn1_get_tag( p, end, len,
770 MBEDTLS_ASN1_CONTEXT_SPECIFIC |
771 MBEDTLS_ASN1_CONSTRUCTED | ( n ) );
772 if( ret != 0 )
773 return( ret );
774 end = *p + *len;
775 ret = mbedtls_asn1_get_tag( p, end, len, tag );
776 if( ret != 0 )
777 return( ret );
778 if( *p + *len != end )
779 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
780 return( 0 );
781}
782
783static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
784 uint8_t *exported, size_t exported_length )
785{
786 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100787 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200788 else
789 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200790
791#if defined(MBEDTLS_DES_C)
792 if( type == PSA_KEY_TYPE_DES )
793 {
794 /* Check the parity bits. */
795 unsigned i;
796 for( i = 0; i < bits / 8; i++ )
797 {
798 unsigned bit_count = 0;
799 unsigned m;
800 for( m = 1; m <= 0x100; m <<= 1 )
801 {
802 if( exported[i] & m )
803 ++bit_count;
804 }
805 TEST_ASSERT( bit_count % 2 != 0 );
806 }
807 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200808 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200809#endif
810
811#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
812 if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
813 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200814 uint8_t *p = exported;
815 uint8_t *end = exported + exported_length;
816 size_t len;
817 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200818 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200819 * modulus INTEGER, -- n
820 * publicExponent INTEGER, -- e
821 * privateExponent INTEGER, -- d
822 * prime1 INTEGER, -- p
823 * prime2 INTEGER, -- q
824 * exponent1 INTEGER, -- d mod (p-1)
825 * exponent2 INTEGER, -- d mod (q-1)
826 * coefficient INTEGER, -- (inverse of q) mod p
827 * }
828 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100829 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
830 MBEDTLS_ASN1_SEQUENCE |
831 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
832 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200833 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
834 goto exit;
835 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
836 goto exit;
837 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
838 goto exit;
839 /* Require d to be at least half the size of n. */
840 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
841 goto exit;
842 /* Require p and q to be at most half the size of n, rounded up. */
843 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
844 goto exit;
845 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
846 goto exit;
847 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
848 goto exit;
849 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
850 goto exit;
851 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
852 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100853 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100854 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200855 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200856#endif /* MBEDTLS_RSA_C */
857
858#if defined(MBEDTLS_ECP_C)
859 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
860 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100861 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100862 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100863 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200864 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200865#endif /* MBEDTLS_ECP_C */
866
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200867 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
868 {
869 uint8_t *p = exported;
870 uint8_t *end = exported + exported_length;
871 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200872#if defined(MBEDTLS_RSA_C)
873 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
874 {
875 /* RSAPublicKey ::= SEQUENCE {
876 * modulus INTEGER, -- n
877 * publicExponent INTEGER } -- e
878 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100879 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
880 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100881 MBEDTLS_ASN1_CONSTRUCTED ),
882 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100883 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200884 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
885 goto exit;
886 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
887 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100888 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200889 }
890 else
891#endif /* MBEDTLS_RSA_C */
892#if defined(MBEDTLS_ECP_C)
893 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
894 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000895 /* The representation of an ECC public key is:
896 * - The byte 0x04;
897 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
898 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
899 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000900 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100901 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
902 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200903 }
904 else
905#endif /* MBEDTLS_ECP_C */
906 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100907 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200908 mbedtls_snprintf( message, sizeof( message ),
909 "No sanity check for public key type=0x%08lx",
910 (unsigned long) type );
911 test_fail( message, __LINE__, __FILE__ );
912 return( 0 );
913 }
914 }
915 else
916
917 {
918 /* No sanity checks for other types */
919 }
920
921 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200922
923exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200924 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200925}
926
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100927static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200928 psa_key_usage_t usage )
929{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200930 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200931 uint8_t *exported = NULL;
932 size_t exported_size = 0;
933 size_t exported_length = 0;
934 int ok = 0;
935
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200936 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200937
938 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200939 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200940 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100941 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
942 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200943 ok = 1;
944 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200945 }
946
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200947 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
948 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200949 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200950
Gilles Peskine8817f612018-12-18 00:18:46 +0100951 PSA_ASSERT( psa_export_key( handle,
952 exported, exported_size,
953 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200954 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
955 psa_get_key_bits( &attributes ),
956 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200957
958exit:
959 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200960 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200961 return( ok );
962}
963
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100964static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200965{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200966 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200967 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200968 uint8_t *exported = NULL;
969 size_t exported_size = 0;
970 size_t exported_length = 0;
971 int ok = 0;
972
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200973 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
974 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200975 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100976 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100977 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200978 return( 1 );
979 }
980
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200981 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(
982 psa_get_key_type( &attributes ) );
983 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
984 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200985 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200986
Gilles Peskine8817f612018-12-18 00:18:46 +0100987 PSA_ASSERT( psa_export_public_key( handle,
988 exported, exported_size,
989 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200990 ok = exported_key_sanity_check( public_type,
991 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200992 exported, exported_length );
993
994exit:
995 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200996 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200997 return( ok );
998}
999
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001000/** Do smoke tests on a key.
1001 *
1002 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1003 * sign/verify, or derivation) that is permitted according to \p usage.
1004 * \p usage and \p alg should correspond to the expected policy on the
1005 * key.
1006 *
1007 * Export the key if permitted by \p usage, and check that the output
1008 * looks sensible. If \p usage forbids export, check that
1009 * \p psa_export_key correctly rejects the attempt. If the key is
1010 * asymmetric, also check \p psa_export_public_key.
1011 *
1012 * If the key fails the tests, this function calls the test framework's
1013 * `test_fail` function and returns false. Otherwise this function returns
1014 * true. Therefore it should be used as follows:
1015 * ```
1016 * if( ! exercise_key( ... ) ) goto exit;
1017 * ```
1018 *
1019 * \param handle The key to exercise. It should be capable of performing
1020 * \p alg.
1021 * \param usage The usage flags to assume.
1022 * \param alg The algorithm to exercise.
1023 *
1024 * \retval 0 The key failed the smoke tests.
1025 * \retval 1 The key passed the smoke tests.
1026 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001027static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001028 psa_key_usage_t usage,
1029 psa_algorithm_t alg )
1030{
1031 int ok;
1032 if( alg == 0 )
1033 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1034 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001035 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001036 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001037 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001038 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001039 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001040 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001041 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001042 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001043 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001044 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001045 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001046 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1047 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001048 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001049 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001050 else
1051 {
1052 char message[40];
1053 mbedtls_snprintf( message, sizeof( message ),
1054 "No code to exercise alg=0x%08lx",
1055 (unsigned long) alg );
1056 test_fail( message, __LINE__, __FILE__ );
1057 ok = 0;
1058 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001059
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001060 ok = ok && exercise_export_key( handle, usage );
1061 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001062
Gilles Peskine02b75072018-07-01 22:31:34 +02001063 return( ok );
1064}
1065
Gilles Peskine10df3412018-10-25 22:35:43 +02001066static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1067 psa_algorithm_t alg )
1068{
1069 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1070 {
1071 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1072 PSA_KEY_USAGE_VERIFY :
1073 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1074 }
1075 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1076 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1077 {
1078 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1079 PSA_KEY_USAGE_ENCRYPT :
1080 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1081 }
1082 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1083 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1084 {
1085 return( PSA_KEY_USAGE_DERIVE );
1086 }
1087 else
1088 {
1089 return( 0 );
1090 }
1091
1092}
Darryl Green0c6575a2018-11-07 16:05:30 +00001093
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001094static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1095{
1096 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1097 uint8_t buffer[1];
1098 size_t length;
1099 int ok = 0;
1100
1101 psa_make_key_persistent( &attributes, 0x6964, PSA_KEY_LIFETIME_PERSISTENT );
1102 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1103 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1104 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1105 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1106 PSA_ERROR_INVALID_HANDLE );
1107 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001108 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001109 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1110 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1111 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1112 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1113
1114 TEST_EQUAL( psa_export_key( handle,
1115 buffer, sizeof( buffer ), &length ),
1116 PSA_ERROR_INVALID_HANDLE );
1117 TEST_EQUAL( psa_export_public_key( handle,
1118 buffer, sizeof( buffer ), &length ),
1119 PSA_ERROR_INVALID_HANDLE );
1120
1121 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1122 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1123
1124 ok = 1;
1125
1126exit:
1127 psa_reset_key_attributes( &attributes );
1128 return( ok );
1129}
1130
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001131/* An overapproximation of the amount of storage needed for a key of the
1132 * given type and with the given content. The API doesn't make it easy
1133 * to find a good value for the size. The current implementation doesn't
1134 * care about the value anyway. */
1135#define KEY_BITS_FROM_DATA( type, data ) \
1136 ( data )->len
1137
Darryl Green0c6575a2018-11-07 16:05:30 +00001138typedef enum {
1139 IMPORT_KEY = 0,
1140 GENERATE_KEY = 1,
1141 DERIVE_KEY = 2
1142} generate_method;
1143
Gilles Peskinee59236f2018-01-27 23:32:46 +01001144/* END_HEADER */
1145
1146/* BEGIN_DEPENDENCIES
1147 * depends_on:MBEDTLS_PSA_CRYPTO_C
1148 * END_DEPENDENCIES
1149 */
1150
1151/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001152void static_checks( )
1153{
1154 size_t max_truncated_mac_size =
1155 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1156
1157 /* Check that the length for a truncated MAC always fits in the algorithm
1158 * encoding. The shifted mask is the maximum truncated value. The
1159 * untruncated algorithm may be one byte larger. */
1160 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1161}
1162/* END_CASE */
1163
1164/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001165void attributes_set_get( int id_arg, int lifetime_arg,
1166 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001167 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001168{
Gilles Peskine4747d192019-04-17 15:05:45 +02001169 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001170 psa_key_id_t id = id_arg;
1171 psa_key_lifetime_t lifetime = lifetime_arg;
1172 psa_key_usage_t usage_flags = usage_flags_arg;
1173 psa_algorithm_t alg = alg_arg;
1174 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001175 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001176
1177 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1178 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1179 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001182 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001183
1184 psa_make_key_persistent( &attributes, id, lifetime );
1185 psa_set_key_usage_flags( &attributes, usage_flags );
1186 psa_set_key_algorithm( &attributes, alg );
1187 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001188 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001189
1190 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1191 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1192 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1193 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1194 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001195 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001196
1197 psa_reset_key_attributes( &attributes );
1198
1199 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1200 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1201 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1202 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1203 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001204 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001205}
1206/* END_CASE */
1207
1208/* BEGIN_CASE */
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001209void import( data_t *data, int type_arg,
1210 int attr_bits_arg,
1211 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001212{
1213 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1214 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001215 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001216 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001217 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001218 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001219 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001220
Gilles Peskine8817f612018-12-18 00:18:46 +01001221 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001222
Gilles Peskine4747d192019-04-17 15:05:45 +02001223 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001224 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001225 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001226 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001227 if( status != PSA_SUCCESS )
1228 goto exit;
1229
1230 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1231 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001232 if( attr_bits != 0 )
1233 TEST_EQUAL( attr_bits, got_attributes.bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001234
1235 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001236 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001237
1238exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001239 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001240 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001241 mbedtls_psa_crypto_free( );
1242}
1243/* END_CASE */
1244
1245/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001246void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1247{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001248 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001249 size_t bits = bits_arg;
1250 psa_status_t expected_status = expected_status_arg;
1251 psa_status_t status;
1252 psa_key_type_t type =
1253 keypair ? PSA_KEY_TYPE_RSA_KEYPAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
1254 size_t buffer_size = /* Slight overapproximations */
1255 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001256 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001257 unsigned char *p;
1258 int ret;
1259 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001260 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001261
Gilles Peskine8817f612018-12-18 00:18:46 +01001262 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001263 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001264
1265 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1266 bits, keypair ) ) >= 0 );
1267 length = ret;
1268
1269 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001270 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001271 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001272 TEST_EQUAL( status, expected_status );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001273 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001274 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001275
1276exit:
1277 mbedtls_free( buffer );
1278 mbedtls_psa_crypto_free( );
1279}
1280/* END_CASE */
1281
1282/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001283void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001284 int type_arg,
1285 int alg_arg,
1286 int usage_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001287 int expected_bits,
1288 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001289 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001290 int canonical_input )
1291{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001292 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001293 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001294 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001295 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001296 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001297 unsigned char *exported = NULL;
1298 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001299 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001300 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001301 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001302 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001303 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001304
Moran Pekercb088e72018-07-17 17:36:59 +03001305 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001306 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001307 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001308 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001309 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001310
Gilles Peskine4747d192019-04-17 15:05:45 +02001311 psa_set_key_usage_flags( &attributes, usage_arg );
1312 psa_set_key_algorithm( &attributes, alg );
1313 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001314
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001315 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001316 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001317
1318 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001319 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1320 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1321 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001322
1323 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001324 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001325 exported, export_size,
1326 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001327 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001328
1329 /* The exported length must be set by psa_export_key() to a value between 0
1330 * and export_size. On errors, the exported length must be 0. */
1331 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1332 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1333 TEST_ASSERT( exported_length <= export_size );
1334
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001335 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001336 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001337 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001338 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001339 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001340 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001341 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001342
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001343 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001344 goto exit;
1345
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001346 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001347 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001348 else
1349 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001350 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001351 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1352 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001353 PSA_ASSERT( psa_export_key( handle2,
1354 reexported,
1355 export_size,
1356 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001357 ASSERT_COMPARE( exported, exported_length,
1358 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001359 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001360 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001361 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001362
1363destroy:
1364 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001365 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001366 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001367
1368exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001369 mbedtls_free( exported );
1370 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001371 psa_reset_key_attributes( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001372 mbedtls_psa_crypto_free( );
1373}
1374/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001375
Moran Pekerf709f4a2018-06-06 17:26:04 +03001376/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001377void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001378{
Gilles Peskine8817f612018-12-18 00:18:46 +01001379 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001380 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001381
1382exit:
1383 mbedtls_psa_crypto_free( );
1384}
1385/* END_CASE */
1386
1387/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001388void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001389 int type_arg,
1390 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001391 int export_size_delta,
1392 int expected_export_status_arg,
1393 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001394{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001395 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001396 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001397 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001398 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001399 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001400 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001401 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001402 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001403 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001404
Gilles Peskine8817f612018-12-18 00:18:46 +01001405 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001406
Gilles Peskine4747d192019-04-17 15:05:45 +02001407 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1408 psa_set_key_algorithm( &attributes, alg );
1409 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001410
1411 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001412 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001413
Gilles Peskine49c25912018-10-29 15:15:31 +01001414 /* Export the public key */
1415 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001416 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001417 exported, export_size,
1418 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001419 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001420 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001421 {
1422 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
1423 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001424 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1425 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001426 TEST_ASSERT( expected_public_key->len <=
1427 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001428 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1429 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001430 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001431
1432exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001433 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001434 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001435 psa_reset_key_attributes( &attributes );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001436 mbedtls_psa_crypto_free( );
1437}
1438/* END_CASE */
1439
Gilles Peskine20035e32018-02-03 22:44:14 +01001440/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001441void import_and_exercise_key( data_t *data,
1442 int type_arg,
1443 int bits_arg,
1444 int alg_arg )
1445{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001446 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001447 psa_key_type_t type = type_arg;
1448 size_t bits = bits_arg;
1449 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001450 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001451 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001452 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001453
Gilles Peskine8817f612018-12-18 00:18:46 +01001454 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001455
Gilles Peskine4747d192019-04-17 15:05:45 +02001456 psa_set_key_usage_flags( &attributes, usage );
1457 psa_set_key_algorithm( &attributes, alg );
1458 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001459
1460 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001461 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001462
1463 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001464 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1465 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1466 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001467
1468 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001469 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001470 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001471
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001472 PSA_ASSERT( psa_destroy_key( handle ) );
1473 test_operations_on_invalid_handle( handle );
1474
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001475exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001476 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001477 psa_reset_key_attributes( &got_attributes );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001478 mbedtls_psa_crypto_free( );
1479}
1480/* END_CASE */
1481
1482/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001483void key_policy( int usage_arg, int alg_arg )
1484{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001485 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001486 psa_algorithm_t alg = alg_arg;
1487 psa_key_usage_t usage = usage_arg;
1488 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1489 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001490 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001491
1492 memset( key, 0x2a, sizeof( key ) );
1493
Gilles Peskine8817f612018-12-18 00:18:46 +01001494 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001495
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001496 psa_set_key_usage_flags( &attributes, usage );
1497 psa_set_key_algorithm( &attributes, alg );
1498 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001499
Gilles Peskine73676cb2019-05-15 20:15:10 +02001500 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001501
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001502 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1503 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1504 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1505 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001506
1507exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001508 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001509 psa_reset_key_attributes( &attributes );
Gilles Peskined5b33222018-06-18 22:20:03 +02001510 mbedtls_psa_crypto_free( );
1511}
1512/* END_CASE */
1513
1514/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001515void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001516{
1517 /* Test each valid way of initializing the object, except for `= {0}`, as
1518 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1519 * though it's OK by the C standard. We could test for this, but we'd need
1520 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001521 psa_key_attributes_t func = psa_key_attributes_init( );
1522 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1523 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001524
1525 memset( &zero, 0, sizeof( zero ) );
1526
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001527 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1528 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1529 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001530
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001531 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1532 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1533 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1534
1535 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1536 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1537 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1538
1539 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1540 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1541 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1542
1543 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1544 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1545 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001546}
1547/* END_CASE */
1548
1549/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001550void mac_key_policy( int policy_usage,
1551 int policy_alg,
1552 int key_type,
1553 data_t *key_data,
1554 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001555{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001556 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001557 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001558 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001559 psa_status_t status;
1560 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001561
Gilles Peskine8817f612018-12-18 00:18:46 +01001562 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001563
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001564 psa_set_key_usage_flags( &attributes, policy_usage );
1565 psa_set_key_algorithm( &attributes, policy_alg );
1566 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001567
Gilles Peskine049c7532019-05-15 20:22:09 +02001568 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1569 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001570
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001571 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001572 if( policy_alg == exercise_alg &&
1573 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001574 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001575 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001576 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001577 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001578
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001579 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001580 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001581 if( policy_alg == exercise_alg &&
1582 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001583 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001584 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001585 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001586
1587exit:
1588 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001589 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001590 mbedtls_psa_crypto_free( );
1591}
1592/* END_CASE */
1593
1594/* BEGIN_CASE */
1595void cipher_key_policy( int policy_usage,
1596 int policy_alg,
1597 int key_type,
1598 data_t *key_data,
1599 int exercise_alg )
1600{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001601 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001602 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001603 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001604 psa_status_t status;
1605
Gilles Peskine8817f612018-12-18 00:18:46 +01001606 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001607
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001608 psa_set_key_usage_flags( &attributes, policy_usage );
1609 psa_set_key_algorithm( &attributes, policy_alg );
1610 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001611
Gilles Peskine049c7532019-05-15 20:22:09 +02001612 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1613 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001614
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001615 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001616 if( policy_alg == exercise_alg &&
1617 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001618 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001619 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001620 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001621 psa_cipher_abort( &operation );
1622
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001623 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001624 if( policy_alg == exercise_alg &&
1625 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001626 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001627 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001628 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001629
1630exit:
1631 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001632 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001633 mbedtls_psa_crypto_free( );
1634}
1635/* END_CASE */
1636
1637/* BEGIN_CASE */
1638void aead_key_policy( int policy_usage,
1639 int policy_alg,
1640 int key_type,
1641 data_t *key_data,
1642 int nonce_length_arg,
1643 int tag_length_arg,
1644 int exercise_alg )
1645{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001646 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001647 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001648 psa_status_t status;
1649 unsigned char nonce[16] = {0};
1650 size_t nonce_length = nonce_length_arg;
1651 unsigned char tag[16];
1652 size_t tag_length = tag_length_arg;
1653 size_t output_length;
1654
1655 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1656 TEST_ASSERT( tag_length <= sizeof( tag ) );
1657
Gilles Peskine8817f612018-12-18 00:18:46 +01001658 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001659
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001660 psa_set_key_usage_flags( &attributes, policy_usage );
1661 psa_set_key_algorithm( &attributes, policy_alg );
1662 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001663
Gilles Peskine049c7532019-05-15 20:22:09 +02001664 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1665 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001666
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001667 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001668 nonce, nonce_length,
1669 NULL, 0,
1670 NULL, 0,
1671 tag, tag_length,
1672 &output_length );
1673 if( policy_alg == exercise_alg &&
1674 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001675 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001676 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001677 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001678
1679 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001680 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001681 nonce, nonce_length,
1682 NULL, 0,
1683 tag, tag_length,
1684 NULL, 0,
1685 &output_length );
1686 if( policy_alg == exercise_alg &&
1687 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001688 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001689 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001690 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001691
1692exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001693 psa_destroy_key( handle );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001694 mbedtls_psa_crypto_free( );
1695}
1696/* END_CASE */
1697
1698/* BEGIN_CASE */
1699void asymmetric_encryption_key_policy( int policy_usage,
1700 int policy_alg,
1701 int key_type,
1702 data_t *key_data,
1703 int exercise_alg )
1704{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001705 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001706 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001707 psa_status_t status;
1708 size_t key_bits;
1709 size_t buffer_length;
1710 unsigned char *buffer = NULL;
1711 size_t output_length;
1712
Gilles Peskine8817f612018-12-18 00:18:46 +01001713 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001714
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001715 psa_set_key_usage_flags( &attributes, policy_usage );
1716 psa_set_key_algorithm( &attributes, policy_alg );
1717 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001718
Gilles Peskine049c7532019-05-15 20:22:09 +02001719 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1720 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001721
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001722 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1723 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001724 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1725 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001726 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001727
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001728 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001729 NULL, 0,
1730 NULL, 0,
1731 buffer, buffer_length,
1732 &output_length );
1733 if( policy_alg == exercise_alg &&
1734 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001735 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001736 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001737 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001738
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001739 if( buffer_length != 0 )
1740 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001741 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001742 buffer, buffer_length,
1743 NULL, 0,
1744 buffer, buffer_length,
1745 &output_length );
1746 if( policy_alg == exercise_alg &&
1747 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001748 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001749 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001750 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751
1752exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001753 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001754 psa_reset_key_attributes( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001755 mbedtls_psa_crypto_free( );
1756 mbedtls_free( buffer );
1757}
1758/* END_CASE */
1759
1760/* BEGIN_CASE */
1761void asymmetric_signature_key_policy( int policy_usage,
1762 int policy_alg,
1763 int key_type,
1764 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001765 int exercise_alg,
1766 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001767{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001768 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001769 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001770 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001771 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1772 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1773 * compatible with the policy and `payload_length_arg` is supposed to be
1774 * a valid input length to sign. If `payload_length_arg <= 0`,
1775 * `exercise_alg` is supposed to be forbidden by the policy. */
1776 int compatible_alg = payload_length_arg > 0;
1777 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001778 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1779 size_t signature_length;
1780
Gilles Peskine8817f612018-12-18 00:18:46 +01001781 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001782
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001783 psa_set_key_usage_flags( &attributes, policy_usage );
1784 psa_set_key_algorithm( &attributes, policy_alg );
1785 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001786
Gilles Peskine049c7532019-05-15 20:22:09 +02001787 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1788 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001789
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001790 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001791 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001792 signature, sizeof( signature ),
1793 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001794 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001795 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001797 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001798
1799 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001800 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001801 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001802 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001803 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001804 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001805 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001806 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001807
1808exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001809 psa_destroy_key( handle );
Gilles Peskined5b33222018-06-18 22:20:03 +02001810 mbedtls_psa_crypto_free( );
1811}
1812/* END_CASE */
1813
1814/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001815void derive_key_policy( int policy_usage,
1816 int policy_alg,
1817 int key_type,
1818 data_t *key_data,
1819 int exercise_alg )
1820{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001821 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001822 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001823 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1824 psa_status_t status;
1825
Gilles Peskine8817f612018-12-18 00:18:46 +01001826 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001827
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001828 psa_set_key_usage_flags( &attributes, policy_usage );
1829 psa_set_key_algorithm( &attributes, policy_alg );
1830 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001831
Gilles Peskine049c7532019-05-15 20:22:09 +02001832 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1833 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001834
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001835 status = psa_key_derivation( &generator, handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02001836 exercise_alg,
1837 NULL, 0,
1838 NULL, 0,
1839 1 );
1840 if( policy_alg == exercise_alg &&
1841 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001842 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001843 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001844 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001845
1846exit:
1847 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001848 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001849 mbedtls_psa_crypto_free( );
1850}
1851/* END_CASE */
1852
1853/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02001854void agreement_key_policy( int policy_usage,
1855 int policy_alg,
1856 int key_type_arg,
1857 data_t *key_data,
1858 int exercise_alg )
1859{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001860 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001861 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001862 psa_key_type_t key_type = key_type_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02001863 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1864 psa_status_t status;
1865
Gilles Peskine8817f612018-12-18 00:18:46 +01001866 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001867
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001868 psa_set_key_usage_flags( &attributes, policy_usage );
1869 psa_set_key_algorithm( &attributes, policy_alg );
1870 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001871
Gilles Peskine049c7532019-05-15 20:22:09 +02001872 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1873 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001874
Gilles Peskine969c5d62019-01-16 15:53:06 +01001875 PSA_ASSERT( psa_key_derivation_setup( &generator, exercise_alg ) );
1876 status = key_agreement_with_self( &generator, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001877
Gilles Peskine01d718c2018-09-18 12:01:02 +02001878 if( policy_alg == exercise_alg &&
1879 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001880 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001881 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001882 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001883
1884exit:
1885 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001886 psa_destroy_key( handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001887 mbedtls_psa_crypto_free( );
1888}
1889/* END_CASE */
1890
1891/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001892void raw_agreement_key_policy( int policy_usage,
1893 int policy_alg,
1894 int key_type_arg,
1895 data_t *key_data,
1896 int exercise_alg )
1897{
1898 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001899 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001900 psa_key_type_t key_type = key_type_arg;
1901 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
1902 psa_status_t status;
1903
1904 PSA_ASSERT( psa_crypto_init( ) );
1905
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001906 psa_set_key_usage_flags( &attributes, policy_usage );
1907 psa_set_key_algorithm( &attributes, policy_alg );
1908 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001909
Gilles Peskine049c7532019-05-15 20:22:09 +02001910 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1911 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02001912
1913 status = raw_key_agreement_with_self( exercise_alg, handle );
1914
1915 if( policy_alg == exercise_alg &&
1916 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
1917 PSA_ASSERT( status );
1918 else
1919 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
1920
1921exit:
1922 psa_generator_abort( &generator );
1923 psa_destroy_key( handle );
1924 mbedtls_psa_crypto_free( );
1925}
1926/* END_CASE */
1927
1928/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02001929void copy_success( int source_usage_arg, int source_alg_arg,
1930 int type_arg, data_t *material,
1931 int copy_attributes,
1932 int target_usage_arg, int target_alg_arg,
1933 int expected_usage_arg, int expected_alg_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01001934{
Gilles Peskineca25db92019-04-19 11:43:08 +02001935 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
1936 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001937 psa_key_usage_t expected_usage = expected_usage_arg;
1938 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02001939 psa_key_handle_t source_handle = 0;
1940 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01001941 uint8_t *export_buffer = NULL;
1942
Gilles Peskine57ab7212019-01-28 13:03:09 +01001943 PSA_ASSERT( psa_crypto_init( ) );
1944
Gilles Peskineca25db92019-04-19 11:43:08 +02001945 /* Prepare the source key. */
1946 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
1947 psa_set_key_algorithm( &source_attributes, source_alg_arg );
1948 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02001949 PSA_ASSERT( psa_import_key( &source_attributes,
1950 material->x, material->len,
1951 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02001952 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001953
Gilles Peskineca25db92019-04-19 11:43:08 +02001954 /* Prepare the target attributes. */
1955 if( copy_attributes )
1956 target_attributes = source_attributes;
1957 if( target_usage_arg != -1 )
1958 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
1959 if( target_alg_arg != -1 )
1960 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001961
1962 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02001963 PSA_ASSERT( psa_copy_key( source_handle,
1964 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001965
1966 /* Destroy the source to ensure that this doesn't affect the target. */
1967 PSA_ASSERT( psa_destroy_key( source_handle ) );
1968
1969 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02001970 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
1971 TEST_EQUAL( psa_get_key_type( &source_attributes ),
1972 psa_get_key_type( &target_attributes ) );
1973 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
1974 psa_get_key_bits( &target_attributes ) );
1975 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
1976 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001977 if( expected_usage & PSA_KEY_USAGE_EXPORT )
1978 {
1979 size_t length;
1980 ASSERT_ALLOC( export_buffer, material->len );
1981 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
1982 material->len, &length ) );
1983 ASSERT_COMPARE( material->x, material->len,
1984 export_buffer, length );
1985 }
1986 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
1987 goto exit;
1988
1989 PSA_ASSERT( psa_close_key( target_handle ) );
1990
1991exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001992 psa_reset_key_attributes( &source_attributes );
1993 psa_reset_key_attributes( &target_attributes );
Gilles Peskine57ab7212019-01-28 13:03:09 +01001994 mbedtls_psa_crypto_free( );
1995 mbedtls_free( export_buffer );
1996}
1997/* END_CASE */
1998
1999/* BEGIN_CASE */
Gilles Peskine4a644642019-05-03 17:14:08 +02002000void copy_fail( int source_usage_arg, int source_alg_arg,
2001 int type_arg, data_t *material,
2002 int target_type_arg, int target_bits_arg,
2003 int target_usage_arg, int target_alg_arg,
2004 int expected_status_arg )
2005{
2006 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2007 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2008 psa_key_handle_t source_handle = 0;
2009 psa_key_handle_t target_handle = 0;
2010
2011 PSA_ASSERT( psa_crypto_init( ) );
2012
2013 /* Prepare the source key. */
2014 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2015 psa_set_key_algorithm( &source_attributes, source_alg_arg );
2016 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002017 PSA_ASSERT( psa_import_key( &source_attributes,
2018 material->x, material->len,
2019 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002020
2021 /* Prepare the target attributes. */
2022 psa_set_key_type( &target_attributes, target_type_arg );
2023 psa_set_key_bits( &target_attributes, target_bits_arg );
2024 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2025 psa_set_key_algorithm( &target_attributes, target_alg_arg );
2026
2027 /* Try to copy the key. */
2028 TEST_EQUAL( psa_copy_key( source_handle,
2029 &target_attributes, &target_handle ),
2030 expected_status_arg );
2031exit:
2032 psa_reset_key_attributes( &source_attributes );
2033 psa_reset_key_attributes( &target_attributes );
2034 mbedtls_psa_crypto_free( );
2035}
2036/* END_CASE */
2037
2038/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002039void hash_operation_init( )
2040{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002041 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002042 /* Test each valid way of initializing the object, except for `= {0}`, as
2043 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2044 * though it's OK by the C standard. We could test for this, but we'd need
2045 * to supress the Clang warning for the test. */
2046 psa_hash_operation_t func = psa_hash_operation_init( );
2047 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2048 psa_hash_operation_t zero;
2049
2050 memset( &zero, 0, sizeof( zero ) );
2051
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002052 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002053 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2054 PSA_ERROR_BAD_STATE );
2055 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2056 PSA_ERROR_BAD_STATE );
2057 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2058 PSA_ERROR_BAD_STATE );
2059
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002060 /* A default hash operation should be abortable without error. */
2061 PSA_ASSERT( psa_hash_abort( &func ) );
2062 PSA_ASSERT( psa_hash_abort( &init ) );
2063 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002064}
2065/* END_CASE */
2066
2067/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002068void hash_setup( int alg_arg,
2069 int expected_status_arg )
2070{
2071 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002072 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002073 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002074 psa_status_t status;
2075
Gilles Peskine8817f612018-12-18 00:18:46 +01002076 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002077
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002078 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002079 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002080
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002081 /* Whether setup succeeded or failed, abort must succeed. */
2082 PSA_ASSERT( psa_hash_abort( &operation ) );
2083
2084 /* If setup failed, reproduce the failure, so as to
2085 * test the resulting state of the operation object. */
2086 if( status != PSA_SUCCESS )
2087 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2088
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002089 /* Now the operation object should be reusable. */
2090#if defined(KNOWN_SUPPORTED_HASH_ALG)
2091 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2092 PSA_ASSERT( psa_hash_abort( &operation ) );
2093#endif
2094
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002095exit:
2096 mbedtls_psa_crypto_free( );
2097}
2098/* END_CASE */
2099
2100/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002101void hash_bad_order( )
2102{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002103 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002104 unsigned char input[] = "";
2105 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002106 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002107 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2108 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2109 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002110 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002111 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002112 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002113
Gilles Peskine8817f612018-12-18 00:18:46 +01002114 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002115
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002116 /* Call setup twice in a row. */
2117 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2118 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2119 PSA_ERROR_BAD_STATE );
2120 PSA_ASSERT( psa_hash_abort( &operation ) );
2121
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002122 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002123 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002124 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002125 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002126
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002127 /* Call update after finish. */
2128 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2129 PSA_ASSERT( psa_hash_finish( &operation,
2130 hash, sizeof( hash ), &hash_len ) );
2131 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002132 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002133 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002134
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002135 /* Call verify without calling setup beforehand. */
2136 TEST_EQUAL( psa_hash_verify( &operation,
2137 valid_hash, sizeof( valid_hash ) ),
2138 PSA_ERROR_BAD_STATE );
2139 PSA_ASSERT( psa_hash_abort( &operation ) );
2140
2141 /* Call verify after finish. */
2142 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2143 PSA_ASSERT( psa_hash_finish( &operation,
2144 hash, sizeof( hash ), &hash_len ) );
2145 TEST_EQUAL( psa_hash_verify( &operation,
2146 valid_hash, sizeof( valid_hash ) ),
2147 PSA_ERROR_BAD_STATE );
2148 PSA_ASSERT( psa_hash_abort( &operation ) );
2149
2150 /* Call verify twice in a row. */
2151 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2152 PSA_ASSERT( psa_hash_verify( &operation,
2153 valid_hash, sizeof( valid_hash ) ) );
2154 TEST_EQUAL( psa_hash_verify( &operation,
2155 valid_hash, sizeof( valid_hash ) ),
2156 PSA_ERROR_BAD_STATE );
2157 PSA_ASSERT( psa_hash_abort( &operation ) );
2158
2159 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002160 TEST_EQUAL( psa_hash_finish( &operation,
2161 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002162 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002163 PSA_ASSERT( psa_hash_abort( &operation ) );
2164
2165 /* Call finish twice in a row. */
2166 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2167 PSA_ASSERT( psa_hash_finish( &operation,
2168 hash, sizeof( hash ), &hash_len ) );
2169 TEST_EQUAL( psa_hash_finish( &operation,
2170 hash, sizeof( hash ), &hash_len ),
2171 PSA_ERROR_BAD_STATE );
2172 PSA_ASSERT( psa_hash_abort( &operation ) );
2173
2174 /* Call finish after calling verify. */
2175 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2176 PSA_ASSERT( psa_hash_verify( &operation,
2177 valid_hash, sizeof( valid_hash ) ) );
2178 TEST_EQUAL( psa_hash_finish( &operation,
2179 hash, sizeof( hash ), &hash_len ),
2180 PSA_ERROR_BAD_STATE );
2181 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002182
2183exit:
2184 mbedtls_psa_crypto_free( );
2185}
2186/* END_CASE */
2187
itayzafrir27e69452018-11-01 14:26:34 +02002188/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2189void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002190{
2191 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002192 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2193 * appended to it */
2194 unsigned char hash[] = {
2195 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2196 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2197 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002198 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002199 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002200
Gilles Peskine8817f612018-12-18 00:18:46 +01002201 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002202
itayzafrir27e69452018-11-01 14:26:34 +02002203 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002204 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002205 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002206 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002207
itayzafrir27e69452018-11-01 14:26:34 +02002208 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002209 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002210 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002211 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002212
itayzafrir27e69452018-11-01 14:26:34 +02002213 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002214 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002215 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002216 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002217
itayzafrirec93d302018-10-18 18:01:10 +03002218exit:
2219 mbedtls_psa_crypto_free( );
2220}
2221/* END_CASE */
2222
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002223/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2224void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002225{
2226 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002227 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002228 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002229 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002230 size_t hash_len;
2231
Gilles Peskine8817f612018-12-18 00:18:46 +01002232 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002233
itayzafrir58028322018-10-25 10:22:01 +03002234 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002235 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002236 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002237 hash, expected_size - 1, &hash_len ),
2238 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002239
2240exit:
2241 mbedtls_psa_crypto_free( );
2242}
2243/* END_CASE */
2244
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002245/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2246void hash_clone_source_state( )
2247{
2248 psa_algorithm_t alg = PSA_ALG_SHA_256;
2249 unsigned char hash[PSA_HASH_MAX_SIZE];
2250 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2251 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2252 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2253 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2254 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2255 size_t hash_len;
2256
2257 PSA_ASSERT( psa_crypto_init( ) );
2258 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2259
2260 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2261 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2262 PSA_ASSERT( psa_hash_finish( &op_finished,
2263 hash, sizeof( hash ), &hash_len ) );
2264 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2265 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2266
2267 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2268 PSA_ERROR_BAD_STATE );
2269
2270 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2271 PSA_ASSERT( psa_hash_finish( &op_init,
2272 hash, sizeof( hash ), &hash_len ) );
2273 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2274 PSA_ASSERT( psa_hash_finish( &op_finished,
2275 hash, sizeof( hash ), &hash_len ) );
2276 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2277 PSA_ASSERT( psa_hash_finish( &op_aborted,
2278 hash, sizeof( hash ), &hash_len ) );
2279
2280exit:
2281 psa_hash_abort( &op_source );
2282 psa_hash_abort( &op_init );
2283 psa_hash_abort( &op_setup );
2284 psa_hash_abort( &op_finished );
2285 psa_hash_abort( &op_aborted );
2286 mbedtls_psa_crypto_free( );
2287}
2288/* END_CASE */
2289
2290/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2291void hash_clone_target_state( )
2292{
2293 psa_algorithm_t alg = PSA_ALG_SHA_256;
2294 unsigned char hash[PSA_HASH_MAX_SIZE];
2295 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2296 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2297 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2298 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2299 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2300 size_t hash_len;
2301
2302 PSA_ASSERT( psa_crypto_init( ) );
2303
2304 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2305 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2306 PSA_ASSERT( psa_hash_finish( &op_finished,
2307 hash, sizeof( hash ), &hash_len ) );
2308 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2309 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2310
2311 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2312 PSA_ASSERT( psa_hash_finish( &op_target,
2313 hash, sizeof( hash ), &hash_len ) );
2314
2315 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2316 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2317 PSA_ERROR_BAD_STATE );
2318 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2319 PSA_ERROR_BAD_STATE );
2320
2321exit:
2322 psa_hash_abort( &op_target );
2323 psa_hash_abort( &op_init );
2324 psa_hash_abort( &op_setup );
2325 psa_hash_abort( &op_finished );
2326 psa_hash_abort( &op_aborted );
2327 mbedtls_psa_crypto_free( );
2328}
2329/* END_CASE */
2330
itayzafrir58028322018-10-25 10:22:01 +03002331/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002332void mac_operation_init( )
2333{
Jaeden Amero252ef282019-02-15 14:05:35 +00002334 const uint8_t input[1] = { 0 };
2335
Jaeden Amero769ce272019-01-04 11:48:03 +00002336 /* Test each valid way of initializing the object, except for `= {0}`, as
2337 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2338 * though it's OK by the C standard. We could test for this, but we'd need
2339 * to supress the Clang warning for the test. */
2340 psa_mac_operation_t func = psa_mac_operation_init( );
2341 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2342 psa_mac_operation_t zero;
2343
2344 memset( &zero, 0, sizeof( zero ) );
2345
Jaeden Amero252ef282019-02-15 14:05:35 +00002346 /* A freshly-initialized MAC operation should not be usable. */
2347 TEST_EQUAL( psa_mac_update( &func,
2348 input, sizeof( input ) ),
2349 PSA_ERROR_BAD_STATE );
2350 TEST_EQUAL( psa_mac_update( &init,
2351 input, sizeof( input ) ),
2352 PSA_ERROR_BAD_STATE );
2353 TEST_EQUAL( psa_mac_update( &zero,
2354 input, sizeof( input ) ),
2355 PSA_ERROR_BAD_STATE );
2356
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002357 /* A default MAC operation should be abortable without error. */
2358 PSA_ASSERT( psa_mac_abort( &func ) );
2359 PSA_ASSERT( psa_mac_abort( &init ) );
2360 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002361}
2362/* END_CASE */
2363
2364/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002365void mac_setup( int key_type_arg,
2366 data_t *key,
2367 int alg_arg,
2368 int expected_status_arg )
2369{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002370 psa_key_type_t key_type = key_type_arg;
2371 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002372 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002373 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002374 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2375#if defined(KNOWN_SUPPORTED_MAC_ALG)
2376 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2377#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002378
Gilles Peskine8817f612018-12-18 00:18:46 +01002379 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002380
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002381 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2382 &operation, &status ) )
2383 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002384 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002385
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002386 /* The operation object should be reusable. */
2387#if defined(KNOWN_SUPPORTED_MAC_ALG)
2388 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2389 smoke_test_key_data,
2390 sizeof( smoke_test_key_data ),
2391 KNOWN_SUPPORTED_MAC_ALG,
2392 &operation, &status ) )
2393 goto exit;
2394 TEST_EQUAL( status, PSA_SUCCESS );
2395#endif
2396
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002397exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002398 mbedtls_psa_crypto_free( );
2399}
2400/* END_CASE */
2401
2402/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002403void mac_bad_order( )
2404{
2405 psa_key_handle_t handle = 0;
2406 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2407 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2408 const uint8_t key[] = {
2409 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2410 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2411 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002412 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002413 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2414 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2415 size_t sign_mac_length = 0;
2416 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2417 const uint8_t verify_mac[] = {
2418 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2419 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2420 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2421
2422 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002423 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2424 psa_set_key_algorithm( &attributes, alg );
2425 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002426
Gilles Peskine73676cb2019-05-15 20:15:10 +02002427 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002428
Jaeden Amero252ef282019-02-15 14:05:35 +00002429 /* Call update without calling setup beforehand. */
2430 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2431 PSA_ERROR_BAD_STATE );
2432 PSA_ASSERT( psa_mac_abort( &operation ) );
2433
2434 /* Call sign finish without calling setup beforehand. */
2435 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2436 &sign_mac_length),
2437 PSA_ERROR_BAD_STATE );
2438 PSA_ASSERT( psa_mac_abort( &operation ) );
2439
2440 /* Call verify finish without calling setup beforehand. */
2441 TEST_EQUAL( psa_mac_verify_finish( &operation,
2442 verify_mac, sizeof( verify_mac ) ),
2443 PSA_ERROR_BAD_STATE );
2444 PSA_ASSERT( psa_mac_abort( &operation ) );
2445
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002446 /* Call setup twice in a row. */
2447 PSA_ASSERT( psa_mac_sign_setup( &operation,
2448 handle, alg ) );
2449 TEST_EQUAL( psa_mac_sign_setup( &operation,
2450 handle, alg ),
2451 PSA_ERROR_BAD_STATE );
2452 PSA_ASSERT( psa_mac_abort( &operation ) );
2453
Jaeden Amero252ef282019-02-15 14:05:35 +00002454 /* Call update after sign finish. */
2455 PSA_ASSERT( psa_mac_sign_setup( &operation,
2456 handle, alg ) );
2457 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2458 PSA_ASSERT( psa_mac_sign_finish( &operation,
2459 sign_mac, sizeof( sign_mac ),
2460 &sign_mac_length ) );
2461 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2462 PSA_ERROR_BAD_STATE );
2463 PSA_ASSERT( psa_mac_abort( &operation ) );
2464
2465 /* Call update after verify finish. */
2466 PSA_ASSERT( psa_mac_verify_setup( &operation,
2467 handle, alg ) );
2468 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2469 PSA_ASSERT( psa_mac_verify_finish( &operation,
2470 verify_mac, sizeof( verify_mac ) ) );
2471 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2472 PSA_ERROR_BAD_STATE );
2473 PSA_ASSERT( psa_mac_abort( &operation ) );
2474
2475 /* Call sign finish twice in a row. */
2476 PSA_ASSERT( psa_mac_sign_setup( &operation,
2477 handle, alg ) );
2478 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2479 PSA_ASSERT( psa_mac_sign_finish( &operation,
2480 sign_mac, sizeof( sign_mac ),
2481 &sign_mac_length ) );
2482 TEST_EQUAL( psa_mac_sign_finish( &operation,
2483 sign_mac, sizeof( sign_mac ),
2484 &sign_mac_length ),
2485 PSA_ERROR_BAD_STATE );
2486 PSA_ASSERT( psa_mac_abort( &operation ) );
2487
2488 /* Call verify finish twice in a row. */
2489 PSA_ASSERT( psa_mac_verify_setup( &operation,
2490 handle, alg ) );
2491 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2492 PSA_ASSERT( psa_mac_verify_finish( &operation,
2493 verify_mac, sizeof( verify_mac ) ) );
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
2499 /* Setup sign but try verify. */
2500 PSA_ASSERT( psa_mac_sign_setup( &operation,
2501 handle, alg ) );
2502 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2503 TEST_EQUAL( psa_mac_verify_finish( &operation,
2504 verify_mac, sizeof( verify_mac ) ),
2505 PSA_ERROR_BAD_STATE );
2506 PSA_ASSERT( psa_mac_abort( &operation ) );
2507
2508 /* Setup verify but try sign. */
2509 PSA_ASSERT( psa_mac_verify_setup( &operation,
2510 handle, alg ) );
2511 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2512 TEST_EQUAL( psa_mac_sign_finish( &operation,
2513 sign_mac, sizeof( sign_mac ),
2514 &sign_mac_length ),
2515 PSA_ERROR_BAD_STATE );
2516 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002517
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002518exit:
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002519 mbedtls_psa_crypto_free( );
2520}
2521/* END_CASE */
2522
2523/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002524void mac_sign( int key_type_arg,
2525 data_t *key,
2526 int alg_arg,
2527 data_t *input,
2528 data_t *expected_mac )
2529{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002530 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002531 psa_key_type_t key_type = key_type_arg;
2532 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002533 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002534 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002535 /* Leave a little extra room in the output buffer. At the end of the
2536 * test, we'll check that the implementation didn't overwrite onto
2537 * this extra room. */
2538 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2539 size_t mac_buffer_size =
2540 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2541 size_t mac_length = 0;
2542
2543 memset( actual_mac, '+', sizeof( actual_mac ) );
2544 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2545 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2546
Gilles Peskine8817f612018-12-18 00:18:46 +01002547 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002548
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002549 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2550 psa_set_key_algorithm( &attributes, alg );
2551 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002552
Gilles Peskine73676cb2019-05-15 20:15:10 +02002553 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002554
2555 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002556 PSA_ASSERT( psa_mac_sign_setup( &operation,
2557 handle, alg ) );
2558 PSA_ASSERT( psa_mac_update( &operation,
2559 input->x, input->len ) );
2560 PSA_ASSERT( psa_mac_sign_finish( &operation,
2561 actual_mac, mac_buffer_size,
2562 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002563
2564 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002565 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2566 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002567
2568 /* Verify that the end of the buffer is untouched. */
2569 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2570 sizeof( actual_mac ) - mac_length ) );
2571
2572exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002573 psa_destroy_key( handle );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002574 mbedtls_psa_crypto_free( );
2575}
2576/* END_CASE */
2577
2578/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002579void mac_verify( int key_type_arg,
2580 data_t *key,
2581 int alg_arg,
2582 data_t *input,
2583 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002584{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002585 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002586 psa_key_type_t key_type = key_type_arg;
2587 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002588 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002589 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002590
Gilles Peskine69c12672018-06-28 00:07:19 +02002591 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2592
Gilles Peskine8817f612018-12-18 00:18:46 +01002593 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002594
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002595 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2596 psa_set_key_algorithm( &attributes, alg );
2597 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002598
Gilles Peskine73676cb2019-05-15 20:15:10 +02002599 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002600
Gilles Peskine8817f612018-12-18 00:18:46 +01002601 PSA_ASSERT( psa_mac_verify_setup( &operation,
2602 handle, alg ) );
2603 PSA_ASSERT( psa_destroy_key( handle ) );
2604 PSA_ASSERT( psa_mac_update( &operation,
2605 input->x, input->len ) );
2606 PSA_ASSERT( psa_mac_verify_finish( &operation,
2607 expected_mac->x,
2608 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002609
2610exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002611 psa_destroy_key( handle );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002612 mbedtls_psa_crypto_free( );
2613}
2614/* END_CASE */
2615
2616/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002617void cipher_operation_init( )
2618{
Jaeden Ameroab439972019-02-15 14:12:05 +00002619 const uint8_t input[1] = { 0 };
2620 unsigned char output[1] = { 0 };
2621 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002622 /* Test each valid way of initializing the object, except for `= {0}`, as
2623 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2624 * though it's OK by the C standard. We could test for this, but we'd need
2625 * to supress the Clang warning for the test. */
2626 psa_cipher_operation_t func = psa_cipher_operation_init( );
2627 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2628 psa_cipher_operation_t zero;
2629
2630 memset( &zero, 0, sizeof( zero ) );
2631
Jaeden Ameroab439972019-02-15 14:12:05 +00002632 /* A freshly-initialized cipher operation should not be usable. */
2633 TEST_EQUAL( psa_cipher_update( &func,
2634 input, sizeof( input ),
2635 output, sizeof( output ),
2636 &output_length ),
2637 PSA_ERROR_BAD_STATE );
2638 TEST_EQUAL( psa_cipher_update( &init,
2639 input, sizeof( input ),
2640 output, sizeof( output ),
2641 &output_length ),
2642 PSA_ERROR_BAD_STATE );
2643 TEST_EQUAL( psa_cipher_update( &zero,
2644 input, sizeof( input ),
2645 output, sizeof( output ),
2646 &output_length ),
2647 PSA_ERROR_BAD_STATE );
2648
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002649 /* A default cipher operation should be abortable without error. */
2650 PSA_ASSERT( psa_cipher_abort( &func ) );
2651 PSA_ASSERT( psa_cipher_abort( &init ) );
2652 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002653}
2654/* END_CASE */
2655
2656/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002657void cipher_setup( int key_type_arg,
2658 data_t *key,
2659 int alg_arg,
2660 int expected_status_arg )
2661{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002662 psa_key_type_t key_type = key_type_arg;
2663 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002664 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002665 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002666 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002667#if defined(KNOWN_SUPPORTED_MAC_ALG)
2668 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2669#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002670
Gilles Peskine8817f612018-12-18 00:18:46 +01002671 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002672
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002673 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2674 &operation, &status ) )
2675 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002676 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002677
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002678 /* The operation object should be reusable. */
2679#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2680 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2681 smoke_test_key_data,
2682 sizeof( smoke_test_key_data ),
2683 KNOWN_SUPPORTED_CIPHER_ALG,
2684 &operation, &status ) )
2685 goto exit;
2686 TEST_EQUAL( status, PSA_SUCCESS );
2687#endif
2688
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002689exit:
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002690 mbedtls_psa_crypto_free( );
2691}
2692/* END_CASE */
2693
2694/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002695void cipher_bad_order( )
2696{
2697 psa_key_handle_t handle = 0;
2698 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2699 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002700 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002701 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2702 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2703 const uint8_t key[] = {
2704 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2705 0xaa, 0xaa, 0xaa, 0xaa };
2706 const uint8_t text[] = {
2707 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2708 0xbb, 0xbb, 0xbb, 0xbb };
2709 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2710 size_t length = 0;
2711
2712 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002713 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2714 psa_set_key_algorithm( &attributes, alg );
2715 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002716 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002717
2718
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002719 /* Call encrypt setup twice in a row. */
2720 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2721 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2722 PSA_ERROR_BAD_STATE );
2723 PSA_ASSERT( psa_cipher_abort( &operation ) );
2724
2725 /* Call decrypt setup twice in a row. */
2726 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2727 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2728 PSA_ERROR_BAD_STATE );
2729 PSA_ASSERT( psa_cipher_abort( &operation ) );
2730
Jaeden Ameroab439972019-02-15 14:12:05 +00002731 /* Generate an IV without calling setup beforehand. */
2732 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2733 buffer, sizeof( buffer ),
2734 &length ),
2735 PSA_ERROR_BAD_STATE );
2736 PSA_ASSERT( psa_cipher_abort( &operation ) );
2737
2738 /* Generate an IV twice in a row. */
2739 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2740 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2741 buffer, sizeof( buffer ),
2742 &length ) );
2743 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2744 buffer, sizeof( buffer ),
2745 &length ),
2746 PSA_ERROR_BAD_STATE );
2747 PSA_ASSERT( psa_cipher_abort( &operation ) );
2748
2749 /* Generate an IV after it's already set. */
2750 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2751 PSA_ASSERT( psa_cipher_set_iv( &operation,
2752 iv, sizeof( iv ) ) );
2753 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2754 buffer, sizeof( buffer ),
2755 &length ),
2756 PSA_ERROR_BAD_STATE );
2757 PSA_ASSERT( psa_cipher_abort( &operation ) );
2758
2759 /* Set an IV without calling setup beforehand. */
2760 TEST_EQUAL( psa_cipher_set_iv( &operation,
2761 iv, sizeof( iv ) ),
2762 PSA_ERROR_BAD_STATE );
2763 PSA_ASSERT( psa_cipher_abort( &operation ) );
2764
2765 /* Set an IV after it's already set. */
2766 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2767 PSA_ASSERT( psa_cipher_set_iv( &operation,
2768 iv, sizeof( iv ) ) );
2769 TEST_EQUAL( psa_cipher_set_iv( &operation,
2770 iv, sizeof( iv ) ),
2771 PSA_ERROR_BAD_STATE );
2772 PSA_ASSERT( psa_cipher_abort( &operation ) );
2773
2774 /* Set an IV after it's already generated. */
2775 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2776 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2777 buffer, sizeof( buffer ),
2778 &length ) );
2779 TEST_EQUAL( psa_cipher_set_iv( &operation,
2780 iv, sizeof( iv ) ),
2781 PSA_ERROR_BAD_STATE );
2782 PSA_ASSERT( psa_cipher_abort( &operation ) );
2783
2784 /* Call update without calling setup beforehand. */
2785 TEST_EQUAL( psa_cipher_update( &operation,
2786 text, sizeof( text ),
2787 buffer, sizeof( buffer ),
2788 &length ),
2789 PSA_ERROR_BAD_STATE );
2790 PSA_ASSERT( psa_cipher_abort( &operation ) );
2791
2792 /* Call update without an IV where an IV is required. */
2793 TEST_EQUAL( psa_cipher_update( &operation,
2794 text, sizeof( text ),
2795 buffer, sizeof( buffer ),
2796 &length ),
2797 PSA_ERROR_BAD_STATE );
2798 PSA_ASSERT( psa_cipher_abort( &operation ) );
2799
2800 /* Call update after finish. */
2801 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2802 PSA_ASSERT( psa_cipher_set_iv( &operation,
2803 iv, sizeof( iv ) ) );
2804 PSA_ASSERT( psa_cipher_finish( &operation,
2805 buffer, sizeof( buffer ), &length ) );
2806 TEST_EQUAL( psa_cipher_update( &operation,
2807 text, sizeof( text ),
2808 buffer, sizeof( buffer ),
2809 &length ),
2810 PSA_ERROR_BAD_STATE );
2811 PSA_ASSERT( psa_cipher_abort( &operation ) );
2812
2813 /* Call finish without calling setup beforehand. */
2814 TEST_EQUAL( psa_cipher_finish( &operation,
2815 buffer, sizeof( buffer ), &length ),
2816 PSA_ERROR_BAD_STATE );
2817 PSA_ASSERT( psa_cipher_abort( &operation ) );
2818
2819 /* Call finish without an IV where an IV is required. */
2820 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2821 /* Not calling update means we are encrypting an empty buffer, which is OK
2822 * for cipher modes with padding. */
2823 TEST_EQUAL( psa_cipher_finish( &operation,
2824 buffer, sizeof( buffer ), &length ),
2825 PSA_ERROR_BAD_STATE );
2826 PSA_ASSERT( psa_cipher_abort( &operation ) );
2827
2828 /* Call finish twice in a row. */
2829 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2830 PSA_ASSERT( psa_cipher_set_iv( &operation,
2831 iv, sizeof( iv ) ) );
2832 PSA_ASSERT( psa_cipher_finish( &operation,
2833 buffer, sizeof( buffer ), &length ) );
2834 TEST_EQUAL( psa_cipher_finish( &operation,
2835 buffer, sizeof( buffer ), &length ),
2836 PSA_ERROR_BAD_STATE );
2837 PSA_ASSERT( psa_cipher_abort( &operation ) );
2838
2839exit:
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002840 mbedtls_psa_crypto_free( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002841}
2842/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002843
Gilles Peskine50e586b2018-06-08 14:28:46 +02002844/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02002845void cipher_encrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002846 data_t *key,
2847 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002848 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002849{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002850 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002851 psa_status_t status;
2852 psa_key_type_t key_type = key_type_arg;
2853 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002854 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002855 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002856 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002857 unsigned char *output = NULL;
2858 size_t output_buffer_size = 0;
2859 size_t function_output_length = 0;
2860 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002861 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002862 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002863
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002864 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2865 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002866
Gilles Peskine8817f612018-12-18 00:18:46 +01002867 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002868
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002869 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2870 psa_set_key_algorithm( &attributes, alg );
2871 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002872
Gilles Peskine73676cb2019-05-15 20:15:10 +02002873 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002874
Gilles Peskine8817f612018-12-18 00:18:46 +01002875 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2876 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002877
Gilles Peskine8817f612018-12-18 00:18:46 +01002878 PSA_ASSERT( psa_cipher_set_iv( &operation,
2879 iv, iv_size ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002880 output_buffer_size = ( (size_t) input->len +
2881 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002882 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002883
Gilles Peskine8817f612018-12-18 00:18:46 +01002884 PSA_ASSERT( psa_cipher_update( &operation,
2885 input->x, input->len,
2886 output, output_buffer_size,
2887 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002888 total_output_length += function_output_length;
2889 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002890 output + total_output_length,
2891 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002892 &function_output_length );
2893 total_output_length += function_output_length;
2894
Gilles Peskinefe11b722018-12-18 00:24:04 +01002895 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002896 if( expected_status == PSA_SUCCESS )
2897 {
Gilles Peskine8817f612018-12-18 00:18:46 +01002898 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002899 ASSERT_COMPARE( expected_output->x, expected_output->len,
2900 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002901 }
2902
2903exit:
2904 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002905 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002906 mbedtls_psa_crypto_free( );
2907}
2908/* END_CASE */
2909
2910/* BEGIN_CASE */
2911void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
2912 data_t *key,
2913 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002914 int first_part_size_arg,
2915 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02002916 data_t *expected_output )
2917{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002918 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002919 psa_key_type_t key_type = key_type_arg;
2920 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002921 size_t first_part_size = first_part_size_arg;
2922 size_t output1_length = output1_length_arg;
2923 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002924 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002925 size_t iv_size;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002926 unsigned char *output = NULL;
2927 size_t output_buffer_size = 0;
2928 size_t function_output_length = 0;
2929 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002930 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002931 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002932
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002933 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
2934 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002935
Gilles Peskine8817f612018-12-18 00:18:46 +01002936 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002937
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002938 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
2939 psa_set_key_algorithm( &attributes, alg );
2940 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03002941
Gilles Peskine73676cb2019-05-15 20:15:10 +02002942 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002943
Gilles Peskine8817f612018-12-18 00:18:46 +01002944 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
2945 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002946
Gilles Peskine8817f612018-12-18 00:18:46 +01002947 PSA_ASSERT( psa_cipher_set_iv( &operation,
2948 iv, sizeof( iv ) ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01002949 output_buffer_size = ( (size_t) input->len +
2950 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002951 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002952
Gilles Peskinee0866522019-02-19 19:44:00 +01002953 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01002954 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
2955 output, output_buffer_size,
2956 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002957 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002958 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002959 PSA_ASSERT( psa_cipher_update( &operation,
2960 input->x + first_part_size,
2961 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002962 output + total_output_length,
2963 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002964 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01002965 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002966 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002967 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01002968 output + total_output_length,
2969 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01002970 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02002971 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01002972 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002973
Gilles Peskinebd7dea92018-09-27 13:57:19 +02002974 ASSERT_COMPARE( expected_output->x, expected_output->len,
2975 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002976
2977exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03002978 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002979 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02002980 mbedtls_psa_crypto_free( );
2981}
2982/* END_CASE */
2983
2984/* BEGIN_CASE */
2985void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002986 data_t *key,
2987 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01002988 int first_part_size_arg,
2989 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03002990 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02002991{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002992 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002993
2994 psa_key_type_t key_type = key_type_arg;
2995 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01002996 size_t first_part_size = first_part_size_arg;
2997 size_t output1_length = output1_length_arg;
2998 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02002999 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003000 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003001 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003002 size_t output_buffer_size = 0;
3003 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003004 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003005 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003006 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003007
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003008 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3009 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003010
Gilles Peskine8817f612018-12-18 00:18:46 +01003011 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003012
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003013 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3014 psa_set_key_algorithm( &attributes, alg );
3015 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003016
Gilles Peskine73676cb2019-05-15 20:15:10 +02003017 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003018
Gilles Peskine8817f612018-12-18 00:18:46 +01003019 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3020 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003021
Gilles Peskine8817f612018-12-18 00:18:46 +01003022 PSA_ASSERT( psa_cipher_set_iv( &operation,
3023 iv, sizeof( iv ) ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003024
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003025 output_buffer_size = ( (size_t) input->len +
3026 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003027 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003028
Gilles Peskinee0866522019-02-19 19:44:00 +01003029 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003030 PSA_ASSERT( psa_cipher_update( &operation,
3031 input->x, first_part_size,
3032 output, output_buffer_size,
3033 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003034 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003035 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003036 PSA_ASSERT( psa_cipher_update( &operation,
3037 input->x + first_part_size,
3038 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003039 output + total_output_length,
3040 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003041 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003042 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003043 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003044 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003045 output + total_output_length,
3046 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003047 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003048 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003049 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003050
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003051 ASSERT_COMPARE( expected_output->x, expected_output->len,
3052 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003053
3054exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003055 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003056 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003057 mbedtls_psa_crypto_free( );
3058}
3059/* END_CASE */
3060
Gilles Peskine50e586b2018-06-08 14:28:46 +02003061/* BEGIN_CASE */
3062void cipher_decrypt( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003063 data_t *key,
3064 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003065 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003066{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003067 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003068 psa_status_t status;
3069 psa_key_type_t key_type = key_type_arg;
3070 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003071 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003072 unsigned char iv[16] = {0};
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003073 size_t iv_size;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003074 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003075 size_t output_buffer_size = 0;
3076 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003077 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003078 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003079 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003080
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003081 iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
3082 memset( iv, 0x2a, iv_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003083
Gilles Peskine8817f612018-12-18 00:18:46 +01003084 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003085
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003086 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3087 psa_set_key_algorithm( &attributes, alg );
3088 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003089
Gilles Peskine73676cb2019-05-15 20:15:10 +02003090 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003091
Gilles Peskine8817f612018-12-18 00:18:46 +01003092 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3093 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003094
Gilles Peskine8817f612018-12-18 00:18:46 +01003095 PSA_ASSERT( psa_cipher_set_iv( &operation,
3096 iv, iv_size ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003097
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003098 output_buffer_size = ( (size_t) input->len +
3099 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003100 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003101
Gilles Peskine8817f612018-12-18 00:18:46 +01003102 PSA_ASSERT( psa_cipher_update( &operation,
3103 input->x, input->len,
3104 output, output_buffer_size,
3105 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003106 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003107 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003108 output + total_output_length,
3109 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003110 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003111 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003112 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003113
3114 if( expected_status == PSA_SUCCESS )
3115 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003116 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003117 ASSERT_COMPARE( expected_output->x, expected_output->len,
3118 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003119 }
3120
Gilles Peskine50e586b2018-06-08 14:28:46 +02003121exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003122 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003123 psa_destroy_key( handle );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003124 mbedtls_psa_crypto_free( );
3125}
3126/* END_CASE */
3127
Gilles Peskine50e586b2018-06-08 14:28:46 +02003128/* BEGIN_CASE */
3129void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003130 data_t *key,
3131 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003132{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003133 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003134 psa_key_type_t key_type = key_type_arg;
3135 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003136 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003137 size_t iv_size = 16;
3138 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003139 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003140 size_t output1_size = 0;
3141 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003142 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003143 size_t output2_size = 0;
3144 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003145 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003146 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3147 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003148 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003149
Gilles Peskine8817f612018-12-18 00:18:46 +01003150 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003151
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003152 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3153 psa_set_key_algorithm( &attributes, alg );
3154 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003155
Gilles Peskine73676cb2019-05-15 20:15:10 +02003156 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003157
Gilles Peskine8817f612018-12-18 00:18:46 +01003158 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3159 handle, alg ) );
3160 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3161 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003162
Gilles Peskine8817f612018-12-18 00:18:46 +01003163 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3164 iv, iv_size,
3165 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003166 output1_size = ( (size_t) input->len +
3167 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003168 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003169
Gilles Peskine8817f612018-12-18 00:18:46 +01003170 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3171 output1, output1_size,
3172 &output1_length ) );
3173 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003174 output1 + output1_length,
3175 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003176 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003177
Gilles Peskine048b7f02018-06-08 14:20:49 +02003178 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003179
Gilles Peskine8817f612018-12-18 00:18:46 +01003180 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003181
3182 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003183 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003184
Gilles Peskine8817f612018-12-18 00:18:46 +01003185 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3186 iv, iv_length ) );
3187 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3188 output2, output2_size,
3189 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003190 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003191 PSA_ASSERT( psa_cipher_finish( &operation2,
3192 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003193 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003194 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003195
Gilles Peskine048b7f02018-06-08 14:20:49 +02003196 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003197
Gilles Peskine8817f612018-12-18 00:18:46 +01003198 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003199
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003200 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003201
3202exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003203 mbedtls_free( output1 );
3204 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003205 psa_destroy_key( handle );
Moran Pekerded84402018-06-06 16:36:50 +03003206 mbedtls_psa_crypto_free( );
3207}
3208/* END_CASE */
3209
3210/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003211void cipher_verify_output_multipart( int alg_arg,
3212 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003213 data_t *key,
3214 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003215 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003216{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003217 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003218 psa_key_type_t key_type = key_type_arg;
3219 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003220 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003221 unsigned char iv[16] = {0};
3222 size_t iv_size = 16;
3223 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003224 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003225 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003226 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003227 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003228 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003229 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003230 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003231 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3232 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003233 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003234
Gilles Peskine8817f612018-12-18 00:18:46 +01003235 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003236
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003237 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3238 psa_set_key_algorithm( &attributes, alg );
3239 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003240
Gilles Peskine73676cb2019-05-15 20:15:10 +02003241 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003242
Gilles Peskine8817f612018-12-18 00:18:46 +01003243 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3244 handle, alg ) );
3245 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3246 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003247
Gilles Peskine8817f612018-12-18 00:18:46 +01003248 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3249 iv, iv_size,
3250 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003251 output1_buffer_size = ( (size_t) input->len +
3252 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003253 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003254
Gilles Peskinee0866522019-02-19 19:44:00 +01003255 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003256
Gilles Peskine8817f612018-12-18 00:18:46 +01003257 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3258 output1, output1_buffer_size,
3259 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003260 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003261
Gilles Peskine8817f612018-12-18 00:18:46 +01003262 PSA_ASSERT( psa_cipher_update( &operation1,
3263 input->x + first_part_size,
3264 input->len - first_part_size,
3265 output1, output1_buffer_size,
3266 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003267 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003268
Gilles Peskine8817f612018-12-18 00:18:46 +01003269 PSA_ASSERT( psa_cipher_finish( &operation1,
3270 output1 + output1_length,
3271 output1_buffer_size - output1_length,
3272 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003273 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003274
Gilles Peskine8817f612018-12-18 00:18:46 +01003275 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003276
Gilles Peskine048b7f02018-06-08 14:20:49 +02003277 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003278 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003279
Gilles Peskine8817f612018-12-18 00:18:46 +01003280 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3281 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003282
Gilles Peskine8817f612018-12-18 00:18:46 +01003283 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3284 output2, output2_buffer_size,
3285 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003286 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003287
Gilles Peskine8817f612018-12-18 00:18:46 +01003288 PSA_ASSERT( psa_cipher_update( &operation2,
3289 output1 + first_part_size,
3290 output1_length - first_part_size,
3291 output2, output2_buffer_size,
3292 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003293 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003294
Gilles Peskine8817f612018-12-18 00:18:46 +01003295 PSA_ASSERT( psa_cipher_finish( &operation2,
3296 output2 + output2_length,
3297 output2_buffer_size - output2_length,
3298 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003299 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003300
Gilles Peskine8817f612018-12-18 00:18:46 +01003301 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003302
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003303 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003304
3305exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003306 mbedtls_free( output1 );
3307 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003308 psa_destroy_key( handle );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003309 mbedtls_psa_crypto_free( );
3310}
3311/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003312
Gilles Peskine20035e32018-02-03 22:44:14 +01003313/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003314void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003315 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003316 data_t *nonce,
3317 data_t *additional_data,
3318 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003319 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003320{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003321 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003322 psa_key_type_t key_type = key_type_arg;
3323 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003324 unsigned char *output_data = NULL;
3325 size_t output_size = 0;
3326 size_t output_length = 0;
3327 unsigned char *output_data2 = NULL;
3328 size_t output_length2 = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003329 size_t tag_length = 16;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003330 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003331 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003332
Gilles Peskine4abf7412018-06-18 16:35:34 +02003333 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003334 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003335
Gilles Peskine8817f612018-12-18 00:18:46 +01003336 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003337
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003338 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3339 psa_set_key_algorithm( &attributes, alg );
3340 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003341
Gilles Peskine049c7532019-05-15 20:22:09 +02003342 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3343 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003344
Gilles Peskinefe11b722018-12-18 00:24:04 +01003345 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3346 nonce->x, nonce->len,
3347 additional_data->x,
3348 additional_data->len,
3349 input_data->x, input_data->len,
3350 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003351 &output_length ),
3352 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003353
3354 if( PSA_SUCCESS == expected_result )
3355 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003356 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003357
Gilles Peskinefe11b722018-12-18 00:24:04 +01003358 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3359 nonce->x, nonce->len,
3360 additional_data->x,
3361 additional_data->len,
3362 output_data, output_length,
3363 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003364 &output_length2 ),
3365 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003366
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003367 ASSERT_COMPARE( input_data->x, input_data->len,
3368 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003369 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003370
Gilles Peskinea1cac842018-06-11 19:33:02 +02003371exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003372 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003373 mbedtls_free( output_data );
3374 mbedtls_free( output_data2 );
3375 mbedtls_psa_crypto_free( );
3376}
3377/* END_CASE */
3378
3379/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003380void aead_encrypt( int key_type_arg, data_t *key_data,
3381 int alg_arg,
3382 data_t *nonce,
3383 data_t *additional_data,
3384 data_t *input_data,
3385 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003386{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003387 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003388 psa_key_type_t key_type = key_type_arg;
3389 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003390 unsigned char *output_data = NULL;
3391 size_t output_size = 0;
3392 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003393 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003394 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003395
Gilles Peskine4abf7412018-06-18 16:35:34 +02003396 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003397 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003398
Gilles Peskine8817f612018-12-18 00:18:46 +01003399 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003400
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003401 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3402 psa_set_key_algorithm( &attributes, alg );
3403 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003404
Gilles Peskine049c7532019-05-15 20:22:09 +02003405 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3406 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003407
Gilles Peskine8817f612018-12-18 00:18:46 +01003408 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3409 nonce->x, nonce->len,
3410 additional_data->x, additional_data->len,
3411 input_data->x, input_data->len,
3412 output_data, output_size,
3413 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003414
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003415 ASSERT_COMPARE( expected_result->x, expected_result->len,
3416 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003417
Gilles Peskinea1cac842018-06-11 19:33:02 +02003418exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003419 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003420 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003421 mbedtls_psa_crypto_free( );
3422}
3423/* END_CASE */
3424
3425/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003426void aead_decrypt( int key_type_arg, data_t *key_data,
3427 int alg_arg,
3428 data_t *nonce,
3429 data_t *additional_data,
3430 data_t *input_data,
3431 data_t *expected_data,
3432 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003433{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003434 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003435 psa_key_type_t key_type = key_type_arg;
3436 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003437 unsigned char *output_data = NULL;
3438 size_t output_size = 0;
3439 size_t output_length = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003440 size_t tag_length = 16;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003441 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003442 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003443
Gilles Peskine4abf7412018-06-18 16:35:34 +02003444 output_size = input_data->len + tag_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003445 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003446
Gilles Peskine8817f612018-12-18 00:18:46 +01003447 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003448
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003449 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3450 psa_set_key_algorithm( &attributes, alg );
3451 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003452
Gilles Peskine049c7532019-05-15 20:22:09 +02003453 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3454 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003455
Gilles Peskinefe11b722018-12-18 00:24:04 +01003456 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3457 nonce->x, nonce->len,
3458 additional_data->x,
3459 additional_data->len,
3460 input_data->x, input_data->len,
3461 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003462 &output_length ),
3463 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003464
Gilles Peskine2d277862018-06-18 15:41:12 +02003465 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003466 ASSERT_COMPARE( expected_data->x, expected_data->len,
3467 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003468
Gilles Peskinea1cac842018-06-11 19:33:02 +02003469exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003470 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003471 mbedtls_free( output_data );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003472 mbedtls_psa_crypto_free( );
3473}
3474/* END_CASE */
3475
3476/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003477void signature_size( int type_arg,
3478 int bits,
3479 int alg_arg,
3480 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003481{
3482 psa_key_type_t type = type_arg;
3483 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003484 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003485 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003486exit:
3487 ;
3488}
3489/* END_CASE */
3490
3491/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003492void sign_deterministic( int key_type_arg, data_t *key_data,
3493 int alg_arg, data_t *input_data,
3494 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003495{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003496 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003497 psa_key_type_t key_type = key_type_arg;
3498 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003499 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003500 unsigned char *signature = NULL;
3501 size_t signature_size;
3502 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003503 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003504
Gilles Peskine8817f612018-12-18 00:18:46 +01003505 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003506
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003507 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3508 psa_set_key_algorithm( &attributes, alg );
3509 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003510
Gilles Peskine049c7532019-05-15 20:22:09 +02003511 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3512 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003513 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3514 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003515
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003516 /* Allocate a buffer which has the size advertized by the
3517 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003518 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3519 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003520 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003521 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003522 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003523
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003524 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003525 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3526 input_data->x, input_data->len,
3527 signature, signature_size,
3528 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003529 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003530 ASSERT_COMPARE( output_data->x, output_data->len,
3531 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003532
3533exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003534 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003535 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003536 mbedtls_free( signature );
Gilles Peskine20035e32018-02-03 22:44:14 +01003537 mbedtls_psa_crypto_free( );
3538}
3539/* END_CASE */
3540
3541/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003542void sign_fail( int key_type_arg, data_t *key_data,
3543 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003544 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003545{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003546 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003547 psa_key_type_t key_type = key_type_arg;
3548 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003549 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003550 psa_status_t actual_status;
3551 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003552 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003553 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003554 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003555
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003556 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003557
Gilles Peskine8817f612018-12-18 00:18:46 +01003558 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003559
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003560 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3561 psa_set_key_algorithm( &attributes, alg );
3562 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003563
Gilles Peskine049c7532019-05-15 20:22:09 +02003564 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3565 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003566
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003567 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003568 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003569 signature, signature_size,
3570 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003571 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003572 /* The value of *signature_length is unspecified on error, but
3573 * whatever it is, it should be less than signature_size, so that
3574 * if the caller tries to read *signature_length bytes without
3575 * checking the error code then they don't overflow a buffer. */
3576 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003577
3578exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003579 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003580 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003581 mbedtls_free( signature );
3582 mbedtls_psa_crypto_free( );
3583}
3584/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003585
3586/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003587void sign_verify( int key_type_arg, data_t *key_data,
3588 int alg_arg, data_t *input_data )
3589{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003590 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003591 psa_key_type_t key_type = key_type_arg;
3592 psa_algorithm_t alg = alg_arg;
3593 size_t key_bits;
3594 unsigned char *signature = NULL;
3595 size_t signature_size;
3596 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003597 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003598
Gilles Peskine8817f612018-12-18 00:18:46 +01003599 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003600
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003601 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3602 psa_set_key_algorithm( &attributes, alg );
3603 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003604
Gilles Peskine049c7532019-05-15 20:22:09 +02003605 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3606 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003607 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3608 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003609
3610 /* Allocate a buffer which has the size advertized by the
3611 * library. */
3612 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3613 key_bits, alg );
3614 TEST_ASSERT( signature_size != 0 );
3615 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003616 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003617
3618 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003619 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3620 input_data->x, input_data->len,
3621 signature, signature_size,
3622 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003623 /* Check that the signature length looks sensible. */
3624 TEST_ASSERT( signature_length <= signature_size );
3625 TEST_ASSERT( signature_length > 0 );
3626
3627 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003628 PSA_ASSERT( psa_asymmetric_verify(
3629 handle, alg,
3630 input_data->x, input_data->len,
3631 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003632
3633 if( input_data->len != 0 )
3634 {
3635 /* Flip a bit in the input and verify that the signature is now
3636 * detected as invalid. Flip a bit at the beginning, not at the end,
3637 * because ECDSA may ignore the last few bits of the input. */
3638 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003639 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3640 input_data->x, input_data->len,
3641 signature, signature_length ),
3642 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003643 }
3644
3645exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003646 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003647 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003648 mbedtls_free( signature );
3649 mbedtls_psa_crypto_free( );
3650}
3651/* END_CASE */
3652
3653/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003654void asymmetric_verify( int key_type_arg, data_t *key_data,
3655 int alg_arg, data_t *hash_data,
3656 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003657{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003658 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003659 psa_key_type_t key_type = key_type_arg;
3660 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003661 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003662
Gilles Peskine69c12672018-06-28 00:07:19 +02003663 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3664
Gilles Peskine8817f612018-12-18 00:18:46 +01003665 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003666
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003667 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3668 psa_set_key_algorithm( &attributes, alg );
3669 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003670
Gilles Peskine049c7532019-05-15 20:22:09 +02003671 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3672 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003673
Gilles Peskine8817f612018-12-18 00:18:46 +01003674 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3675 hash_data->x, hash_data->len,
3676 signature_data->x,
3677 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003678exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003679 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003680 psa_destroy_key( handle );
itayzafrir5c753392018-05-08 11:18:38 +03003681 mbedtls_psa_crypto_free( );
3682}
3683/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003684
3685/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003686void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3687 int alg_arg, data_t *hash_data,
3688 data_t *signature_data,
3689 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003690{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003691 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003692 psa_key_type_t key_type = key_type_arg;
3693 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003694 psa_status_t actual_status;
3695 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003696 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003697
Gilles Peskine8817f612018-12-18 00:18:46 +01003698 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003699
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003700 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3701 psa_set_key_algorithm( &attributes, alg );
3702 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003703
Gilles Peskine049c7532019-05-15 20:22:09 +02003704 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3705 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003706
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003707 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003708 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003709 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003710 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003711
Gilles Peskinefe11b722018-12-18 00:24:04 +01003712 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003713
3714exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003715 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003716 psa_destroy_key( handle );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003717 mbedtls_psa_crypto_free( );
3718}
3719/* END_CASE */
3720
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003721/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003722void asymmetric_encrypt( int key_type_arg,
3723 data_t *key_data,
3724 int alg_arg,
3725 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003726 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003727 int expected_output_length_arg,
3728 int expected_status_arg )
3729{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003730 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003731 psa_key_type_t key_type = key_type_arg;
3732 psa_algorithm_t alg = alg_arg;
3733 size_t expected_output_length = expected_output_length_arg;
3734 size_t key_bits;
3735 unsigned char *output = NULL;
3736 size_t output_size;
3737 size_t output_length = ~0;
3738 psa_status_t actual_status;
3739 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003740 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003741
Gilles Peskine8817f612018-12-18 00:18:46 +01003742 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003743
Gilles Peskine656896e2018-06-29 19:12:28 +02003744 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003745 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3746 psa_set_key_algorithm( &attributes, alg );
3747 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003748 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3749 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003750
3751 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003752 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3753 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003754 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003755 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003756
3757 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003758 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003759 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003760 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003761 output, output_size,
3762 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003763 TEST_EQUAL( actual_status, expected_status );
3764 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003765
Gilles Peskine68428122018-06-30 18:42:41 +02003766 /* If the label is empty, the test framework puts a non-null pointer
3767 * in label->x. Test that a null pointer works as well. */
3768 if( label->len == 0 )
3769 {
3770 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003771 if( output_size != 0 )
3772 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003773 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003774 input_data->x, input_data->len,
3775 NULL, label->len,
3776 output, output_size,
3777 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003778 TEST_EQUAL( actual_status, expected_status );
3779 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003780 }
3781
Gilles Peskine656896e2018-06-29 19:12:28 +02003782exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003783 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003784 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02003785 mbedtls_free( output );
3786 mbedtls_psa_crypto_free( );
3787}
3788/* END_CASE */
3789
3790/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003791void asymmetric_encrypt_decrypt( int key_type_arg,
3792 data_t *key_data,
3793 int alg_arg,
3794 data_t *input_data,
3795 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003796{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003797 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003798 psa_key_type_t key_type = key_type_arg;
3799 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003800 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003801 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003802 size_t output_size;
3803 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003804 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003805 size_t output2_size;
3806 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003807 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003808
Gilles Peskine8817f612018-12-18 00:18:46 +01003809 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003810
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003811 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3812 psa_set_key_algorithm( &attributes, alg );
3813 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003814
Gilles Peskine049c7532019-05-15 20:22:09 +02003815 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3816 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003817
3818 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003819 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3820 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003821 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003822 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003823 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003824 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003825
Gilles Peskineeebd7382018-06-08 18:11:54 +02003826 /* We test encryption by checking that encrypt-then-decrypt gives back
3827 * the original plaintext because of the non-optional random
3828 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003829 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
3830 input_data->x, input_data->len,
3831 label->x, label->len,
3832 output, output_size,
3833 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003834 /* We don't know what ciphertext length to expect, but check that
3835 * it looks sensible. */
3836 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03003837
Gilles Peskine8817f612018-12-18 00:18:46 +01003838 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3839 output, output_length,
3840 label->x, label->len,
3841 output2, output2_size,
3842 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003843 ASSERT_COMPARE( input_data->x, input_data->len,
3844 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003845
3846exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003847 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003848 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003849 mbedtls_free( output );
3850 mbedtls_free( output2 );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003851 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003852}
3853/* END_CASE */
3854
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003855/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003856void asymmetric_decrypt( int key_type_arg,
3857 data_t *key_data,
3858 int alg_arg,
3859 data_t *input_data,
3860 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02003861 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003862{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003863 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003864 psa_key_type_t key_type = key_type_arg;
3865 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003866 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03003867 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003868 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003869 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003870
Jaeden Amero412654a2019-02-06 12:57:46 +00003871 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003872 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003873
Gilles Peskine8817f612018-12-18 00:18:46 +01003874 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003875
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003876 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3877 psa_set_key_algorithm( &attributes, alg );
3878 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003879
Gilles Peskine049c7532019-05-15 20:22:09 +02003880 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3881 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003882
Gilles Peskine8817f612018-12-18 00:18:46 +01003883 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3884 input_data->x, input_data->len,
3885 label->x, label->len,
3886 output,
3887 output_size,
3888 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003889 ASSERT_COMPARE( expected_data->x, expected_data->len,
3890 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003891
Gilles Peskine68428122018-06-30 18:42:41 +02003892 /* If the label is empty, the test framework puts a non-null pointer
3893 * in label->x. Test that a null pointer works as well. */
3894 if( label->len == 0 )
3895 {
3896 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003897 if( output_size != 0 )
3898 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01003899 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
3900 input_data->x, input_data->len,
3901 NULL, label->len,
3902 output,
3903 output_size,
3904 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003905 ASSERT_COMPARE( expected_data->x, expected_data->len,
3906 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02003907 }
3908
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003909exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003910 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003911 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003912 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003913 mbedtls_psa_crypto_free( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003914}
3915/* END_CASE */
3916
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003917/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02003918void asymmetric_decrypt_fail( int key_type_arg,
3919 data_t *key_data,
3920 int alg_arg,
3921 data_t *input_data,
3922 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00003923 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02003924 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003925{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003926 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003927 psa_key_type_t key_type = key_type_arg;
3928 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003929 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00003930 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003931 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003932 psa_status_t actual_status;
3933 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003934 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003935
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003936 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003937
Gilles Peskine8817f612018-12-18 00:18:46 +01003938 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003939
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003940 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3941 psa_set_key_algorithm( &attributes, alg );
3942 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003943
Gilles Peskine049c7532019-05-15 20:22:09 +02003944 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3945 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003946
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003947 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003948 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003949 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003950 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02003951 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003952 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003953 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003954
Gilles Peskine68428122018-06-30 18:42:41 +02003955 /* If the label is empty, the test framework puts a non-null pointer
3956 * in label->x. Test that a null pointer works as well. */
3957 if( label->len == 0 )
3958 {
3959 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003960 if( output_size != 0 )
3961 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003962 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02003963 input_data->x, input_data->len,
3964 NULL, label->len,
3965 output, output_size,
3966 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003967 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02003968 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02003969 }
3970
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003971exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003972 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003973 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02003974 mbedtls_free( output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003975 mbedtls_psa_crypto_free( );
3976}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003977/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02003978
3979/* BEGIN_CASE */
Jaeden Amerod94d6712019-01-04 14:11:48 +00003980void crypto_generator_init( )
3981{
3982 /* Test each valid way of initializing the object, except for `= {0}`, as
3983 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
3984 * though it's OK by the C standard. We could test for this, but we'd need
3985 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003986 size_t capacity;
Jaeden Amerod94d6712019-01-04 14:11:48 +00003987 psa_crypto_generator_t func = psa_crypto_generator_init( );
3988 psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT;
3989 psa_crypto_generator_t zero;
3990
3991 memset( &zero, 0, sizeof( zero ) );
3992
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003993 /* A default generator should not be able to report its capacity. */
3994 TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
3995 PSA_ERROR_BAD_STATE );
3996 TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
3997 PSA_ERROR_BAD_STATE );
3998 TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
3999 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004000
4001 /* A default generator should be abortable without error. */
4002 PSA_ASSERT( psa_generator_abort(&func) );
4003 PSA_ASSERT( psa_generator_abort(&init) );
4004 PSA_ASSERT( psa_generator_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004005}
4006/* END_CASE */
4007
4008/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004009void derive_setup( int key_type_arg,
4010 data_t *key_data,
4011 int alg_arg,
4012 data_t *salt,
4013 data_t *label,
4014 int requested_capacity_arg,
4015 int expected_status_arg )
4016{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004017 psa_key_handle_t handle = 0;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004018 size_t key_type = key_type_arg;
4019 psa_algorithm_t alg = alg_arg;
4020 size_t requested_capacity = requested_capacity_arg;
4021 psa_status_t expected_status = expected_status_arg;
4022 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004023 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004024
Gilles Peskine8817f612018-12-18 00:18:46 +01004025 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004026
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004027 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4028 psa_set_key_algorithm( &attributes, alg );
4029 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004030
Gilles Peskine049c7532019-05-15 20:22:09 +02004031 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4032 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004033
Gilles Peskinefe11b722018-12-18 00:24:04 +01004034 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4035 salt->x, salt->len,
4036 label->x, label->len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004037 requested_capacity ),
4038 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004039
4040exit:
4041 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004042 psa_destroy_key( handle );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004043 mbedtls_psa_crypto_free( );
4044}
4045/* END_CASE */
4046
4047/* BEGIN_CASE */
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004048void test_derive_invalid_generator_state( )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004049{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004050 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004051 size_t key_type = PSA_KEY_TYPE_DERIVE;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004052 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004053 psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004054 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004055 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004056 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4057 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4058 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004059 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004060
Gilles Peskine8817f612018-12-18 00:18:46 +01004061 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004062
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004063 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4064 psa_set_key_algorithm( &attributes, alg );
4065 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004066
Gilles Peskine73676cb2019-05-15 20:15:10 +02004067 PSA_ASSERT( psa_import_key( &attributes,
4068 key_data, sizeof( key_data ),
4069 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004070
4071 /* valid key derivation */
Gilles Peskine8817f612018-12-18 00:18:46 +01004072 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4073 NULL, 0,
4074 NULL, 0,
4075 capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004076
4077 /* state of generator shouldn't allow additional generation */
Gilles Peskinefe11b722018-12-18 00:24:04 +01004078 TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
4079 NULL, 0,
4080 NULL, 0,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004081 capacity ),
4082 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004083
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004084 PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004085
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004086 TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004087 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004088
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004089exit:
4090 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004091 psa_destroy_key( handle );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004092 mbedtls_psa_crypto_free( );
4093}
4094/* END_CASE */
4095
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004096/* BEGIN_CASE */
4097void test_derive_invalid_generator_tests( )
4098{
4099 uint8_t output_buffer[16];
4100 size_t buffer_size = 16;
4101 size_t capacity = 0;
4102 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4103
Nir Sonnenschein50789302018-10-31 12:16:38 +02004104 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004105 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004106
4107 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004108 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004109
Gilles Peskine8817f612018-12-18 00:18:46 +01004110 PSA_ASSERT( psa_generator_abort( &generator ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004111
Nir Sonnenschein50789302018-10-31 12:16:38 +02004112 TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004113 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004114
Nir Sonnenschein50789302018-10-31 12:16:38 +02004115 TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004116 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004117
4118exit:
4119 psa_generator_abort( &generator );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004120}
4121/* END_CASE */
4122
4123/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004124void derive_output( int alg_arg,
4125 data_t *key_data,
4126 data_t *salt,
4127 data_t *label,
4128 int requested_capacity_arg,
4129 data_t *expected_output1,
4130 data_t *expected_output2 )
4131{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004132 psa_key_handle_t handle = 0;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004133 psa_algorithm_t alg = alg_arg;
4134 size_t requested_capacity = requested_capacity_arg;
4135 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4136 uint8_t *expected_outputs[2] =
4137 {expected_output1->x, expected_output2->x};
4138 size_t output_sizes[2] =
4139 {expected_output1->len, expected_output2->len};
4140 size_t output_buffer_size = 0;
4141 uint8_t *output_buffer = NULL;
4142 size_t expected_capacity;
4143 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004144 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004145 psa_status_t status;
4146 unsigned i;
4147
4148 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4149 {
4150 if( output_sizes[i] > output_buffer_size )
4151 output_buffer_size = output_sizes[i];
4152 if( output_sizes[i] == 0 )
4153 expected_outputs[i] = NULL;
4154 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004155 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004156 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004157
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004158 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4159 psa_set_key_algorithm( &attributes, alg );
4160 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004161
Gilles Peskine049c7532019-05-15 20:22:09 +02004162 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4163 &handle ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004164
4165 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004166 if( PSA_ALG_IS_HKDF( alg ) )
4167 {
4168 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4169 PSA_ASSERT( psa_set_generator_capacity( &generator,
4170 requested_capacity ) );
4171 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4172 PSA_KDF_STEP_SALT,
4173 salt->x, salt->len ) );
4174 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4175 PSA_KDF_STEP_SECRET,
4176 handle ) );
4177 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4178 PSA_KDF_STEP_INFO,
4179 label->x, label->len ) );
4180 }
4181 else
4182 {
4183 // legacy
4184 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4185 salt->x, salt->len,
4186 label->x, label->len,
4187 requested_capacity ) );
4188 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004189 PSA_ASSERT( psa_get_generator_capacity( &generator,
4190 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004191 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004192 expected_capacity = requested_capacity;
4193
4194 /* Expansion phase. */
4195 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4196 {
4197 /* Read some bytes. */
4198 status = psa_generator_read( &generator,
4199 output_buffer, output_sizes[i] );
4200 if( expected_capacity == 0 && output_sizes[i] == 0 )
4201 {
4202 /* Reading 0 bytes when 0 bytes are available can go either way. */
4203 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004204 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004205 continue;
4206 }
4207 else if( expected_capacity == 0 ||
4208 output_sizes[i] > expected_capacity )
4209 {
4210 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004211 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004212 expected_capacity = 0;
4213 continue;
4214 }
4215 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004216 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004217 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004218 ASSERT_COMPARE( output_buffer, output_sizes[i],
4219 expected_outputs[i], output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004220 /* Check the generator status. */
4221 expected_capacity -= output_sizes[i];
Gilles Peskine8817f612018-12-18 00:18:46 +01004222 PSA_ASSERT( psa_get_generator_capacity( &generator,
4223 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004224 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004225 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004226 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004227
4228exit:
4229 mbedtls_free( output_buffer );
4230 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004231 psa_destroy_key( handle );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004232 mbedtls_psa_crypto_free( );
4233}
4234/* END_CASE */
4235
4236/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004237void derive_full( int alg_arg,
4238 data_t *key_data,
4239 data_t *salt,
4240 data_t *label,
4241 int requested_capacity_arg )
4242{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004243 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004244 psa_algorithm_t alg = alg_arg;
4245 size_t requested_capacity = requested_capacity_arg;
4246 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
4247 unsigned char output_buffer[16];
4248 size_t expected_capacity = requested_capacity;
4249 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004250 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004251
Gilles Peskine8817f612018-12-18 00:18:46 +01004252 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004253
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004254 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4255 psa_set_key_algorithm( &attributes, alg );
4256 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004257
Gilles Peskine049c7532019-05-15 20:22:09 +02004258 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4259 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004260
4261 /* Extraction phase. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004262 if( PSA_ALG_IS_HKDF( alg ) )
4263 {
4264 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4265 PSA_ASSERT( psa_set_generator_capacity( &generator,
4266 requested_capacity ) );
4267 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4268 PSA_KDF_STEP_SALT,
4269 salt->x, salt->len ) );
4270 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4271 PSA_KDF_STEP_SECRET,
4272 handle ) );
4273 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4274 PSA_KDF_STEP_INFO,
4275 label->x, label->len ) );
4276 }
4277 else
4278 {
4279 // legacy
4280 PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
4281 salt->x, salt->len,
4282 label->x, label->len,
4283 requested_capacity ) );
4284 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004285 PSA_ASSERT( psa_get_generator_capacity( &generator,
4286 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004287 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004288
4289 /* Expansion phase. */
4290 while( current_capacity > 0 )
4291 {
4292 size_t read_size = sizeof( output_buffer );
4293 if( read_size > current_capacity )
4294 read_size = current_capacity;
Gilles Peskine8817f612018-12-18 00:18:46 +01004295 PSA_ASSERT( psa_generator_read( &generator,
4296 output_buffer,
4297 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004298 expected_capacity -= read_size;
Gilles Peskine8817f612018-12-18 00:18:46 +01004299 PSA_ASSERT( psa_get_generator_capacity( &generator,
4300 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004301 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004302 }
4303
4304 /* Check that the generator refuses to go over capacity. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004305 TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004306 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004307
Gilles Peskine8817f612018-12-18 00:18:46 +01004308 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004309
4310exit:
4311 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004312 psa_destroy_key( handle );
Gilles Peskined54931c2018-07-17 21:06:59 +02004313 mbedtls_psa_crypto_free( );
4314}
4315/* END_CASE */
4316
4317/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004318void derive_key_exercise( int alg_arg,
4319 data_t *key_data,
4320 data_t *salt,
4321 data_t *label,
4322 int derived_type_arg,
4323 int derived_bits_arg,
4324 int derived_usage_arg,
4325 int derived_alg_arg )
4326{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004327 psa_key_handle_t base_handle = 0;
4328 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004329 psa_algorithm_t alg = alg_arg;
4330 psa_key_type_t derived_type = derived_type_arg;
4331 size_t derived_bits = derived_bits_arg;
4332 psa_key_usage_t derived_usage = derived_usage_arg;
4333 psa_algorithm_t derived_alg = derived_alg_arg;
4334 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
4335 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004336 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004337 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004338
Gilles Peskine8817f612018-12-18 00:18:46 +01004339 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004340
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004341 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4342 psa_set_key_algorithm( &attributes, alg );
4343 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004344 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4345 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004346
4347 /* Derive a key. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004348 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4349 salt->x, salt->len,
4350 label->x, label->len,
4351 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004352 psa_set_key_usage_flags( &attributes, derived_usage );
4353 psa_set_key_algorithm( &attributes, derived_alg );
4354 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004355 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine98dd7792019-05-15 19:43:49 +02004356 PSA_ASSERT( psa_generate_derived_key( &attributes, &generator,
4357 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004358
4359 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004360 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4361 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4362 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004363
4364 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004365 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004366 goto exit;
4367
4368exit:
4369 psa_generator_abort( &generator );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004370 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004371 psa_destroy_key( base_handle );
4372 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004373 mbedtls_psa_crypto_free( );
4374}
4375/* END_CASE */
4376
4377/* BEGIN_CASE */
4378void derive_key_export( int alg_arg,
4379 data_t *key_data,
4380 data_t *salt,
4381 data_t *label,
4382 int bytes1_arg,
4383 int bytes2_arg )
4384{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004385 psa_key_handle_t base_handle = 0;
4386 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004387 psa_algorithm_t alg = alg_arg;
4388 size_t bytes1 = bytes1_arg;
4389 size_t bytes2 = bytes2_arg;
4390 size_t capacity = bytes1 + bytes2;
4391 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004392 uint8_t *output_buffer = NULL;
4393 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004394 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4395 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004396 size_t length;
4397
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004398 ASSERT_ALLOC( output_buffer, capacity );
4399 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004400 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004401
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004402 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4403 psa_set_key_algorithm( &base_attributes, alg );
4404 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004405 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4406 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004407
4408 /* Derive some material and output it. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004409 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4410 salt->x, salt->len,
4411 label->x, label->len,
4412 capacity ) );
4413 PSA_ASSERT( psa_generator_read( &generator,
4414 output_buffer,
4415 capacity ) );
4416 PSA_ASSERT( psa_generator_abort( &generator ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004417
4418 /* Derive the same output again, but this time store it in key objects. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004419 PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
4420 salt->x, salt->len,
4421 label->x, label->len,
4422 capacity ) );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004423 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4424 psa_set_key_algorithm( &derived_attributes, 0 );
4425 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004426 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine98dd7792019-05-15 19:43:49 +02004427 PSA_ASSERT( psa_generate_derived_key( &derived_attributes, &generator,
4428 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004429 PSA_ASSERT( psa_export_key( derived_handle,
4430 export_buffer, bytes1,
4431 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004432 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004433 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004434 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine98dd7792019-05-15 19:43:49 +02004435 PSA_ASSERT( psa_generate_derived_key( &derived_attributes, &generator,
4436 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004437 PSA_ASSERT( psa_export_key( derived_handle,
4438 export_buffer + bytes1, bytes2,
4439 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004440 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004441
4442 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004443 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4444 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004445
4446exit:
4447 mbedtls_free( output_buffer );
4448 mbedtls_free( export_buffer );
4449 psa_generator_abort( &generator );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004450 psa_destroy_key( base_handle );
4451 psa_destroy_key( derived_handle );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004452 mbedtls_psa_crypto_free( );
4453}
4454/* END_CASE */
4455
4456/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004457void key_agreement_setup( int alg_arg,
4458 int our_key_type_arg, data_t *our_key_data,
4459 data_t *peer_key_data,
4460 int expected_status_arg )
4461{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004462 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004463 psa_algorithm_t alg = alg_arg;
4464 psa_key_type_t our_key_type = our_key_type_arg;
4465 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004466 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004467 psa_status_t expected_status = expected_status_arg;
4468 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004469
Gilles Peskine8817f612018-12-18 00:18:46 +01004470 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004471
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004472 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4473 psa_set_key_algorithm( &attributes, alg );
4474 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004475 PSA_ASSERT( psa_import_key( &attributes,
4476 our_key_data->x, our_key_data->len,
4477 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004478
Gilles Peskine77f40d82019-04-11 21:27:06 +02004479 /* The tests currently include inputs that should fail at either step.
4480 * Test cases that fail at the setup step should be changed to call
4481 * key_derivation_setup instead, and this function should be renamed
4482 * to key_agreement_fail. */
4483 status = psa_key_derivation_setup( &generator, alg );
4484 if( status == PSA_SUCCESS )
4485 {
4486 TEST_EQUAL( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
4487 our_key,
4488 peer_key_data->x, peer_key_data->len ),
4489 expected_status );
4490 }
4491 else
4492 {
4493 TEST_ASSERT( status == expected_status );
4494 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004495
4496exit:
4497 psa_generator_abort( &generator );
4498 psa_destroy_key( our_key );
4499 mbedtls_psa_crypto_free( );
4500}
4501/* END_CASE */
4502
4503/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004504void raw_key_agreement( int alg_arg,
4505 int our_key_type_arg, data_t *our_key_data,
4506 data_t *peer_key_data,
4507 data_t *expected_output )
4508{
4509 psa_key_handle_t our_key = 0;
4510 psa_algorithm_t alg = alg_arg;
4511 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004512 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004513 unsigned char *output = NULL;
4514 size_t output_length = ~0;
4515
4516 ASSERT_ALLOC( output, expected_output->len );
4517 PSA_ASSERT( psa_crypto_init( ) );
4518
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004519 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4520 psa_set_key_algorithm( &attributes, alg );
4521 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004522 PSA_ASSERT( psa_import_key( &attributes,
4523 our_key_data->x, our_key_data->len,
4524 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004525
4526 PSA_ASSERT( psa_key_agreement_raw_shared_secret(
4527 alg, our_key,
4528 peer_key_data->x, peer_key_data->len,
4529 output, expected_output->len, &output_length ) );
4530 ASSERT_COMPARE( output, output_length,
4531 expected_output->x, expected_output->len );
4532
4533exit:
4534 mbedtls_free( output );
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;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004550 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_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 Peskineff5f0e72019-04-18 12:53:30 +02004556 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4557 psa_set_key_algorithm( &attributes, alg );
4558 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004559 PSA_ASSERT( psa_import_key( &attributes,
4560 our_key_data->x, our_key_data->len,
4561 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004562
Gilles Peskine969c5d62019-01-16 15:53:06 +01004563 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4564 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004565 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004566 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004567 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4568 {
4569 /* The test data is for info="" */
4570 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4571 PSA_KDF_STEP_INFO,
4572 NULL, 0 ) );
4573 }
Gilles Peskine59685592018-09-18 12:11:34 +02004574
Gilles Peskinebf491972018-10-25 22:36:12 +02004575 /* Test the advertized capacity. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004576 PSA_ASSERT( psa_get_generator_capacity(
4577 &generator, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004578 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004579
Gilles Peskinebf491972018-10-25 22:36:12 +02004580 /* Test the actual capacity by reading the output. */
4581 while( actual_capacity > sizeof( output ) )
4582 {
Gilles Peskine8817f612018-12-18 00:18:46 +01004583 PSA_ASSERT( psa_generator_read( &generator,
4584 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004585 actual_capacity -= sizeof( output );
4586 }
Gilles Peskine8817f612018-12-18 00:18:46 +01004587 PSA_ASSERT( psa_generator_read( &generator,
4588 output, actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004589 TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004590 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004591
Gilles Peskine59685592018-09-18 12:11:34 +02004592exit:
4593 psa_generator_abort( &generator );
4594 psa_destroy_key( our_key );
4595 mbedtls_psa_crypto_free( );
4596}
4597/* END_CASE */
4598
4599/* BEGIN_CASE */
4600void key_agreement_output( int alg_arg,
4601 int our_key_type_arg, data_t *our_key_data,
4602 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004603 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004604{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004605 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004606 psa_algorithm_t alg = alg_arg;
4607 psa_key_type_t our_key_type = our_key_type_arg;
4608 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004609 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004610 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004611
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004612 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4613 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004614
Gilles Peskine8817f612018-12-18 00:18:46 +01004615 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004616
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004617 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4618 psa_set_key_algorithm( &attributes, alg );
4619 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004620 PSA_ASSERT( psa_import_key( &attributes,
4621 our_key_data->x, our_key_data->len,
4622 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004623
Gilles Peskine969c5d62019-01-16 15:53:06 +01004624 PSA_ASSERT( psa_key_derivation_setup( &generator, alg ) );
4625 PSA_ASSERT( psa_key_agreement( &generator, PSA_KDF_STEP_SECRET,
Gilles Peskine8817f612018-12-18 00:18:46 +01004626 our_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004627 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004628 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4629 {
4630 /* The test data is for info="" */
4631 PSA_ASSERT( psa_key_derivation_input_bytes( &generator,
4632 PSA_KDF_STEP_INFO,
4633 NULL, 0 ) );
4634 }
Gilles Peskine59685592018-09-18 12:11:34 +02004635
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004636 PSA_ASSERT( psa_generator_read( &generator,
4637 actual_output,
4638 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004639 ASSERT_COMPARE( actual_output, expected_output1->len,
4640 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004641 if( expected_output2->len != 0 )
4642 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004643 PSA_ASSERT( psa_generator_read( &generator,
4644 actual_output,
4645 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004646 ASSERT_COMPARE( actual_output, expected_output2->len,
4647 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004648 }
Gilles Peskine59685592018-09-18 12:11:34 +02004649
4650exit:
4651 psa_generator_abort( &generator );
4652 psa_destroy_key( our_key );
4653 mbedtls_psa_crypto_free( );
4654 mbedtls_free( actual_output );
4655}
4656/* END_CASE */
4657
4658/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004659void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004660{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004661 size_t bytes = bytes_arg;
4662 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004663 unsigned char *output = NULL;
4664 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004665 size_t i;
4666 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004667
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004668 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4669 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004670 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004671
Gilles Peskine8817f612018-12-18 00:18:46 +01004672 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004673
Gilles Peskinea50d7392018-06-21 10:22:13 +02004674 /* Run several times, to ensure that every output byte will be
4675 * nonzero at least once with overwhelming probability
4676 * (2^(-8*number_of_runs)). */
4677 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02004678 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004679 if( bytes != 0 )
4680 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01004681 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004682
4683 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004684 ASSERT_COMPARE( output + bytes, sizeof( trail ),
4685 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004686
4687 for( i = 0; i < bytes; i++ )
4688 {
4689 if( output[i] != 0 )
4690 ++changed[i];
4691 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004692 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02004693
4694 /* Check that every byte was changed to nonzero at least once. This
4695 * validates that psa_generate_random is overwriting every byte of
4696 * the output buffer. */
4697 for( i = 0; i < bytes; i++ )
4698 {
4699 TEST_ASSERT( changed[i] != 0 );
4700 }
Gilles Peskine05d69892018-06-19 22:00:52 +02004701
4702exit:
4703 mbedtls_psa_crypto_free( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004704 mbedtls_free( output );
4705 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02004706}
4707/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02004708
4709/* BEGIN_CASE */
4710void generate_key( int type_arg,
4711 int bits_arg,
4712 int usage_arg,
4713 int alg_arg,
4714 int expected_status_arg )
4715{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004716 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004717 psa_key_type_t type = type_arg;
4718 psa_key_usage_t usage = usage_arg;
4719 size_t bits = bits_arg;
4720 psa_algorithm_t alg = alg_arg;
4721 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004722 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004723 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004724
Gilles Peskine8817f612018-12-18 00:18:46 +01004725 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004726
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004727 psa_set_key_usage_flags( &attributes, usage );
4728 psa_set_key_algorithm( &attributes, alg );
4729 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004730 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004731
4732 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004733 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004734 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004735 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004736
4737 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004738 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
4739 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
4740 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004741
Gilles Peskine818ca122018-06-20 18:16:48 +02004742 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004743 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02004744 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004745
4746exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004747 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004748 psa_destroy_key( handle );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004749 mbedtls_psa_crypto_free( );
4750}
4751/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03004752
Gilles Peskinee56e8782019-04-26 17:34:02 +02004753/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
4754void generate_key_rsa( int bits_arg,
4755 data_t *e_arg,
4756 int expected_status_arg )
4757{
4758 psa_key_handle_t handle = 0;
4759 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEYPAIR;
4760 size_t bits = bits_arg;
4761 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
4762 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
4763 psa_status_t expected_status = expected_status_arg;
4764 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4765 uint8_t *exported = NULL;
4766 size_t exported_size =
4767 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
4768 size_t exported_length = SIZE_MAX;
4769 uint8_t *e_read_buffer = NULL;
4770 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02004771 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004772 size_t e_read_length = SIZE_MAX;
4773
4774 if( e_arg->len == 0 ||
4775 ( e_arg->len == 3 &&
4776 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
4777 {
4778 is_default_public_exponent = 1;
4779 e_read_size = 0;
4780 }
4781 ASSERT_ALLOC( e_read_buffer, e_read_size );
4782 ASSERT_ALLOC( exported, exported_size );
4783
4784 PSA_ASSERT( psa_crypto_init( ) );
4785
4786 psa_set_key_usage_flags( &attributes, usage );
4787 psa_set_key_algorithm( &attributes, alg );
4788 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
4789 e_arg->x, e_arg->len ) );
4790 psa_set_key_bits( &attributes, bits );
4791
4792 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004793 TEST_EQUAL( psa_generate_random_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02004794 if( expected_status != PSA_SUCCESS )
4795 goto exit;
4796
4797 /* Test the key information */
4798 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4799 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4800 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4801 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
4802 e_read_buffer, e_read_size,
4803 &e_read_length ) );
4804 if( is_default_public_exponent )
4805 TEST_EQUAL( e_read_length, 0 );
4806 else
4807 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
4808
4809 /* Do something with the key according to its type and permitted usage. */
4810 if( ! exercise_key( handle, usage, alg ) )
4811 goto exit;
4812
4813 /* Export the key and check the public exponent. */
4814 PSA_ASSERT( psa_export_public_key( handle,
4815 exported, exported_size,
4816 &exported_length ) );
4817 {
4818 uint8_t *p = exported;
4819 uint8_t *end = exported + exported_length;
4820 size_t len;
4821 /* RSAPublicKey ::= SEQUENCE {
4822 * modulus INTEGER, -- n
4823 * publicExponent INTEGER } -- e
4824 */
4825 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4826 MBEDTLS_ASN1_SEQUENCE |
4827 MBEDTLS_ASN1_CONSTRUCTED ) );
4828 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
4829 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
4830 MBEDTLS_ASN1_INTEGER ) );
4831 if( len >= 1 && p[0] == 0 )
4832 {
4833 ++p;
4834 --len;
4835 }
4836 if( e_arg->len == 0 )
4837 {
4838 TEST_EQUAL( len, 3 );
4839 TEST_EQUAL( p[0], 1 );
4840 TEST_EQUAL( p[1], 0 );
4841 TEST_EQUAL( p[2], 1 );
4842 }
4843 else
4844 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
4845 }
4846
4847exit:
4848 psa_reset_key_attributes( &attributes );
4849 psa_destroy_key( handle );
4850 mbedtls_psa_crypto_free( );
4851 mbedtls_free( e_read_buffer );
4852 mbedtls_free( exported );
4853}
4854/* END_CASE */
4855
Darryl Greend49a4992018-06-18 17:27:26 +01004856/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004857void persistent_key_load_key_from_storage( data_t *data,
4858 int type_arg, int bits_arg,
4859 int usage_flags_arg, int alg_arg,
4860 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01004861{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004862 psa_key_id_t key_id = 1;
4863 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004864 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004865 psa_key_handle_t base_key = 0;
4866 psa_key_type_t type = type_arg;
4867 size_t bits = bits_arg;
4868 psa_key_usage_t usage_flags = usage_flags_arg;
4869 psa_algorithm_t alg = alg_arg;
Darryl Green0c6575a2018-11-07 16:05:30 +00004870 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01004871 unsigned char *first_export = NULL;
4872 unsigned char *second_export = NULL;
4873 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
4874 size_t first_exported_length;
4875 size_t second_exported_length;
4876
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004877 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4878 {
4879 ASSERT_ALLOC( first_export, export_size );
4880 ASSERT_ALLOC( second_export, export_size );
4881 }
Darryl Greend49a4992018-06-18 17:27:26 +01004882
Gilles Peskine8817f612018-12-18 00:18:46 +01004883 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004884
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004885 psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT );
4886 psa_set_key_usage_flags( &attributes, usage_flags );
4887 psa_set_key_algorithm( &attributes, alg );
4888 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004889 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01004890
Darryl Green0c6575a2018-11-07 16:05:30 +00004891 switch( generation_method )
4892 {
4893 case IMPORT_KEY:
4894 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02004895 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
4896 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004897 break;
Darryl Greend49a4992018-06-18 17:27:26 +01004898
Darryl Green0c6575a2018-11-07 16:05:30 +00004899 case GENERATE_KEY:
4900 /* Generate a key */
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004901 PSA_ASSERT( psa_generate_random_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004902 break;
4903
4904 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004905 {
4906 /* Create base key */
4907 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
4908 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4909 psa_set_key_usage_flags( &base_attributes,
4910 PSA_KEY_USAGE_DERIVE );
4911 psa_set_key_algorithm( &base_attributes, derive_alg );
4912 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004913 PSA_ASSERT( psa_import_key( &base_attributes,
4914 data->x, data->len,
4915 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004916 /* Derive a key. */
4917 PSA_ASSERT( psa_key_derivation_setup( &generator, derive_alg ) );
4918 PSA_ASSERT( psa_key_derivation_input_key( &generator,
4919 PSA_KDF_STEP_SECRET,
4920 base_key ) );
4921 PSA_ASSERT( psa_key_derivation_input_bytes(
4922 &generator, PSA_KDF_STEP_INFO,
4923 NULL, 0 ) );
Gilles Peskine98dd7792019-05-15 19:43:49 +02004924 PSA_ASSERT( psa_generate_derived_key( &attributes, &generator,
4925 &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004926 PSA_ASSERT( psa_generator_abort( &generator ) );
4927 PSA_ASSERT( psa_destroy_key( base_key ) );
4928 base_key = 0;
4929 }
Darryl Green0c6575a2018-11-07 16:05:30 +00004930 break;
4931 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004932 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004933
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004934 /* Export the key if permitted by the key policy. */
4935 if( usage_flags & PSA_KEY_USAGE_EXPORT )
4936 {
4937 PSA_ASSERT( psa_export_key( handle,
4938 first_export, export_size,
4939 &first_exported_length ) );
4940 if( generation_method == IMPORT_KEY )
4941 ASSERT_COMPARE( data->x, data->len,
4942 first_export, first_exported_length );
4943 }
Darryl Greend49a4992018-06-18 17:27:26 +01004944
4945 /* Shutdown and restart */
4946 mbedtls_psa_crypto_free();
Gilles Peskine8817f612018-12-18 00:18:46 +01004947 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01004948
Darryl Greend49a4992018-06-18 17:27:26 +01004949 /* Check key slot still contains key data */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004950 PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
Gilles Peskine8817f612018-12-18 00:18:46 +01004951 &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004952 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4953 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
4954 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
4955 PSA_KEY_LIFETIME_PERSISTENT );
4956 TEST_EQUAL( psa_get_key_type( &attributes ), type );
4957 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
4958 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
4959 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01004960
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004961 /* Export the key again if permitted by the key policy. */
4962 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00004963 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004964 PSA_ASSERT( psa_export_key( handle,
4965 second_export, export_size,
4966 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004967 ASSERT_COMPARE( first_export, first_exported_length,
4968 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00004969 }
4970
4971 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004972 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00004973 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01004974
4975exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004976 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01004977 mbedtls_free( first_export );
4978 mbedtls_free( second_export );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02004979 psa_generator_abort( &generator );
4980 psa_destroy_key( base_key );
4981 if( handle == 0 )
4982 {
4983 /* In case there was a test failure after creating the persistent key
4984 * but while it was not open, try to re-open the persistent key
4985 * to delete it. */
4986 psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle );
4987 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004988 psa_destroy_key( handle );
Darryl Greend49a4992018-06-18 17:27:26 +01004989 mbedtls_psa_crypto_free();
4990}
4991/* END_CASE */