blob: a70fa9e87dbd2efd1fc92220fd196a913a08f5a4 [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
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02004#include "mbedtls/asn1.h"
Gilles Peskine0b352bc2018-06-28 00:16:11 +02005#include "mbedtls/asn1write.h"
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02006#include "mbedtls/oid.h"
7
Gilles Peskinebdc96fd2019-08-07 12:08:04 +02008/* For MBEDTLS_CTR_DRBG_MAX_REQUEST, knowing that psa_generate_random()
9 * uses mbedtls_ctr_drbg internally. */
10#include "mbedtls/ctr_drbg.h"
11
Gilles Peskine1838e822019-06-20 12:40:56 +020012#include "psa_crypto_helpers.h"
itayzafrir3e02b3b2018-06-12 17:06:52 +030013
Gilles Peskinec744d992019-07-30 17:26:54 +020014/* Tests that require more than 128kB of RAM plus change have this symbol
15 * as a dependency. Currently we always define this symbol, so the tests
16 * are always executed. In the future we should make this conditional
17 * so that tests that require a lot of memory are skipped on constrained
18 * platforms. */
Gilles Peskine49232e82019-08-07 11:01:30 +020019#define HAVE_RAM_AVAILABLE_128K
Gilles Peskinec744d992019-07-30 17:26:54 +020020
Gilles Peskinebdc96fd2019-08-07 12:08:04 +020021#include "psa/crypto.h"
22
Jaeden Amerof24c7f82018-06-27 17:20:43 +010023/** An invalid export length that will never be set by psa_export_key(). */
24static const size_t INVALID_EXPORT_LENGTH = ~0U;
25
Gilles Peskinef426e0f2019-02-25 17:42:03 +010026/* A hash algorithm that is known to be supported.
27 *
28 * This is used in some smoke tests.
29 */
30#if defined(MBEDTLS_MD2_C)
31#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
32#elif defined(MBEDTLS_MD4_C)
33#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
34#elif defined(MBEDTLS_MD5_C)
35#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
36/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
37 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
38 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
39 * implausible anyway. */
40#elif defined(MBEDTLS_SHA1_C)
41#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
42#elif defined(MBEDTLS_SHA256_C)
43#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
44#elif defined(MBEDTLS_SHA512_C)
45#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
46#elif defined(MBEDTLS_SHA3_C)
47#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
48#else
49#undef KNOWN_SUPPORTED_HASH_ALG
50#endif
51
52/* A block cipher that is known to be supported.
53 *
54 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
55 */
56#if defined(MBEDTLS_AES_C)
57#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
58#elif defined(MBEDTLS_ARIA_C)
59#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
60#elif defined(MBEDTLS_CAMELLIA_C)
61#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
62#undef KNOWN_SUPPORTED_BLOCK_CIPHER
63#endif
64
65/* A MAC mode that is known to be supported.
66 *
67 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
68 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
69 *
70 * This is used in some smoke tests.
71 */
72#if defined(KNOWN_SUPPORTED_HASH_ALG)
73#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
74#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
75#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
76#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
77#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
78#else
79#undef KNOWN_SUPPORTED_MAC_ALG
80#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
81#endif
82
83/* A cipher algorithm and key type that are known to be supported.
84 *
85 * This is used in some smoke tests.
86 */
87#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
88#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
89#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
90#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
91#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
92#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
93#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
94#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
95#else
96#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
97#endif
98#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
99#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
100#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
101#elif defined(MBEDTLS_RC4_C)
102#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
103#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
104#else
105#undef KNOWN_SUPPORTED_CIPHER_ALG
106#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
107#endif
108
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200109/** Test if a buffer contains a constant byte value.
110 *
111 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200112 *
113 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200114 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200115 * \param size Size of the buffer in bytes.
116 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200117 * \return 1 if the buffer is all-bits-zero.
118 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200119 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200120static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200121{
122 size_t i;
123 for( i = 0; i < size; i++ )
124 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200125 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200126 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200127 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200128 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200129}
Gilles Peskine818ca122018-06-20 18:16:48 +0200130
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200131/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
132static int asn1_write_10x( unsigned char **p,
133 unsigned char *start,
134 size_t bits,
135 unsigned char x )
136{
137 int ret;
138 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200139 if( bits == 0 )
140 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
141 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200142 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300143 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200144 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
145 *p -= len;
146 ( *p )[len-1] = x;
147 if( bits % 8 == 0 )
148 ( *p )[1] |= 1;
149 else
150 ( *p )[0] |= 1 << ( bits % 8 );
151 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
152 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
153 MBEDTLS_ASN1_INTEGER ) );
154 return( len );
155}
156
157static int construct_fake_rsa_key( unsigned char *buffer,
158 size_t buffer_size,
159 unsigned char **p,
160 size_t bits,
161 int keypair )
162{
163 size_t half_bits = ( bits + 1 ) / 2;
164 int ret;
165 int len = 0;
166 /* Construct something that looks like a DER encoding of
167 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
168 * RSAPrivateKey ::= SEQUENCE {
169 * version Version,
170 * modulus INTEGER, -- n
171 * publicExponent INTEGER, -- e
172 * privateExponent INTEGER, -- d
173 * prime1 INTEGER, -- p
174 * prime2 INTEGER, -- q
175 * exponent1 INTEGER, -- d mod (p-1)
176 * exponent2 INTEGER, -- d mod (q-1)
177 * coefficient INTEGER, -- (inverse of q) mod p
178 * otherPrimeInfos OtherPrimeInfos OPTIONAL
179 * }
180 * Or, for a public key, the same structure with only
181 * version, modulus and publicExponent.
182 */
183 *p = buffer + buffer_size;
184 if( keypair )
185 {
186 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
187 asn1_write_10x( p, buffer, half_bits, 1 ) );
188 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
189 asn1_write_10x( p, buffer, half_bits, 1 ) );
190 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
191 asn1_write_10x( p, buffer, half_bits, 1 ) );
192 MBEDTLS_ASN1_CHK_ADD( len, /* q */
193 asn1_write_10x( p, buffer, half_bits, 1 ) );
194 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
195 asn1_write_10x( p, buffer, half_bits, 3 ) );
196 MBEDTLS_ASN1_CHK_ADD( len, /* d */
197 asn1_write_10x( p, buffer, bits, 1 ) );
198 }
199 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
200 asn1_write_10x( p, buffer, 17, 1 ) );
201 MBEDTLS_ASN1_CHK_ADD( len, /* n */
202 asn1_write_10x( p, buffer, bits, 1 ) );
203 if( keypair )
204 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
205 mbedtls_asn1_write_int( p, buffer, 0 ) );
206 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
207 {
208 const unsigned char tag =
209 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
210 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
211 }
212 return( len );
213}
214
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100215int exercise_mac_setup( psa_key_type_t key_type,
216 const unsigned char *key_bytes,
217 size_t key_length,
218 psa_algorithm_t alg,
219 psa_mac_operation_t *operation,
220 psa_status_t *status )
221{
222 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200223 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100224
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200225 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
226 psa_set_key_algorithm( &attributes, alg );
227 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200228 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
229 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100230
231 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100232 /* Whether setup succeeded or failed, abort must succeed. */
233 PSA_ASSERT( psa_mac_abort( operation ) );
234 /* If setup failed, reproduce the failure, so that the caller can
235 * test the resulting state of the operation object. */
236 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100237 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100238 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
239 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100240 }
241
242 psa_destroy_key( handle );
243 return( 1 );
244
245exit:
246 psa_destroy_key( handle );
247 return( 0 );
248}
249
250int exercise_cipher_setup( psa_key_type_t key_type,
251 const unsigned char *key_bytes,
252 size_t key_length,
253 psa_algorithm_t alg,
254 psa_cipher_operation_t *operation,
255 psa_status_t *status )
256{
257 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200258 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100259
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200260 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
261 psa_set_key_algorithm( &attributes, alg );
262 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200263 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
264 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100265
266 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100267 /* Whether setup succeeded or failed, abort must succeed. */
268 PSA_ASSERT( psa_cipher_abort( operation ) );
269 /* If setup failed, reproduce the failure, so that the caller can
270 * test the resulting state of the operation object. */
271 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100272 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100273 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
274 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100275 }
276
277 psa_destroy_key( handle );
278 return( 1 );
279
280exit:
281 psa_destroy_key( handle );
282 return( 0 );
283}
284
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100285static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200286 psa_key_usage_t usage,
287 psa_algorithm_t alg )
288{
Jaeden Amero769ce272019-01-04 11:48:03 +0000289 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200290 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200291 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200292 size_t mac_length = sizeof( mac );
293
294 if( usage & PSA_KEY_USAGE_SIGN )
295 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100296 PSA_ASSERT( psa_mac_sign_setup( &operation,
297 handle, alg ) );
298 PSA_ASSERT( psa_mac_update( &operation,
299 input, sizeof( input ) ) );
300 PSA_ASSERT( psa_mac_sign_finish( &operation,
301 mac, sizeof( mac ),
302 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200303 }
304
305 if( usage & PSA_KEY_USAGE_VERIFY )
306 {
307 psa_status_t verify_status =
308 ( usage & PSA_KEY_USAGE_SIGN ?
309 PSA_SUCCESS :
310 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100311 PSA_ASSERT( psa_mac_verify_setup( &operation,
312 handle, alg ) );
313 PSA_ASSERT( psa_mac_update( &operation,
314 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100315 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
316 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200317 }
318
319 return( 1 );
320
321exit:
322 psa_mac_abort( &operation );
323 return( 0 );
324}
325
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100326static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200327 psa_key_usage_t usage,
328 psa_algorithm_t alg )
329{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000330 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200331 unsigned char iv[16] = {0};
332 size_t iv_length = sizeof( iv );
333 const unsigned char plaintext[16] = "Hello, world...";
334 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
335 size_t ciphertext_length = sizeof( ciphertext );
336 unsigned char decrypted[sizeof( ciphertext )];
337 size_t part_length;
338
339 if( usage & PSA_KEY_USAGE_ENCRYPT )
340 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100341 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
342 handle, alg ) );
343 PSA_ASSERT( psa_cipher_generate_iv( &operation,
344 iv, sizeof( iv ),
345 &iv_length ) );
346 PSA_ASSERT( psa_cipher_update( &operation,
347 plaintext, sizeof( plaintext ),
348 ciphertext, sizeof( ciphertext ),
349 &ciphertext_length ) );
350 PSA_ASSERT( psa_cipher_finish( &operation,
351 ciphertext + ciphertext_length,
352 sizeof( ciphertext ) - ciphertext_length,
353 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200354 ciphertext_length += part_length;
355 }
356
357 if( usage & PSA_KEY_USAGE_DECRYPT )
358 {
359 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200360 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200361 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
362 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200363 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
364 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
365 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
366 * have this macro yet. */
367 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
368 psa_get_key_type( &attributes ) );
369 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200370 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100371 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
372 handle, alg ) );
373 PSA_ASSERT( psa_cipher_set_iv( &operation,
374 iv, iv_length ) );
375 PSA_ASSERT( psa_cipher_update( &operation,
376 ciphertext, ciphertext_length,
377 decrypted, sizeof( decrypted ),
378 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200379 status = psa_cipher_finish( &operation,
380 decrypted + part_length,
381 sizeof( decrypted ) - part_length,
382 &part_length );
383 /* For a stream cipher, all inputs are valid. For a block cipher,
384 * if the input is some aribtrary data rather than an actual
385 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200386 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200387 TEST_ASSERT( status == PSA_SUCCESS ||
388 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200389 else
390 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200391 }
392
393 return( 1 );
394
395exit:
396 psa_cipher_abort( &operation );
397 return( 0 );
398}
399
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100400static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200401 psa_key_usage_t usage,
402 psa_algorithm_t alg )
403{
404 unsigned char nonce[16] = {0};
405 size_t nonce_length = sizeof( nonce );
406 unsigned char plaintext[16] = "Hello, world...";
407 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
408 size_t ciphertext_length = sizeof( ciphertext );
409 size_t plaintext_length = sizeof( ciphertext );
410
411 if( usage & PSA_KEY_USAGE_ENCRYPT )
412 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100413 PSA_ASSERT( psa_aead_encrypt( handle, alg,
414 nonce, nonce_length,
415 NULL, 0,
416 plaintext, sizeof( plaintext ),
417 ciphertext, sizeof( ciphertext ),
418 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200419 }
420
421 if( usage & PSA_KEY_USAGE_DECRYPT )
422 {
423 psa_status_t verify_status =
424 ( usage & PSA_KEY_USAGE_ENCRYPT ?
425 PSA_SUCCESS :
426 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100427 TEST_EQUAL( psa_aead_decrypt( handle, alg,
428 nonce, nonce_length,
429 NULL, 0,
430 ciphertext, ciphertext_length,
431 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100432 &plaintext_length ),
433 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200434 }
435
436 return( 1 );
437
438exit:
439 return( 0 );
440}
441
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100442static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200443 psa_key_usage_t usage,
444 psa_algorithm_t alg )
445{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200446 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
447 size_t payload_length = 16;
Gilles Peskine69c12672018-06-28 00:07:19 +0200448 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200449 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100450 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
451
452 /* If the policy allows signing with any hash, just pick one. */
453 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
454 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100455#if defined(KNOWN_SUPPORTED_HASH_ALG)
456 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
457 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100458#else
459 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100460 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100461#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100462 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200463
464 if( usage & PSA_KEY_USAGE_SIGN )
465 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200466 /* Some algorithms require the payload to have the size of
467 * the hash encoded in the algorithm. Use this input size
468 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200469 if( hash_alg != 0 )
470 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine8817f612018-12-18 00:18:46 +0100471 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
472 payload, payload_length,
473 signature, sizeof( signature ),
474 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200475 }
476
477 if( usage & PSA_KEY_USAGE_VERIFY )
478 {
479 psa_status_t verify_status =
480 ( usage & PSA_KEY_USAGE_SIGN ?
481 PSA_SUCCESS :
482 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100483 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
484 payload, payload_length,
485 signature, signature_length ),
486 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200487 }
488
489 return( 1 );
490
491exit:
492 return( 0 );
493}
494
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100495static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200496 psa_key_usage_t usage,
497 psa_algorithm_t alg )
498{
499 unsigned char plaintext[256] = "Hello, world...";
500 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
501 size_t ciphertext_length = sizeof( ciphertext );
502 size_t plaintext_length = 16;
503
504 if( usage & PSA_KEY_USAGE_ENCRYPT )
505 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100506 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
507 plaintext, plaintext_length,
508 NULL, 0,
509 ciphertext, sizeof( ciphertext ),
510 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200511 }
512
513 if( usage & PSA_KEY_USAGE_DECRYPT )
514 {
515 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100516 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200517 ciphertext, ciphertext_length,
518 NULL, 0,
519 plaintext, sizeof( plaintext ),
520 &plaintext_length );
521 TEST_ASSERT( status == PSA_SUCCESS ||
522 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
523 ( status == PSA_ERROR_INVALID_ARGUMENT ||
524 status == PSA_ERROR_INVALID_PADDING ) ) );
525 }
526
527 return( 1 );
528
529exit:
530 return( 0 );
531}
Gilles Peskine02b75072018-07-01 22:31:34 +0200532
Janos Follathf2815ea2019-07-03 12:41:36 +0100533static int setup_key_derivation_wrap( psa_key_derivation_operation_t* operation,
534 psa_key_handle_t handle,
535 psa_algorithm_t alg,
536 unsigned char* input1, size_t input1_length,
537 unsigned char* input2, size_t input2_length,
538 size_t capacity )
539{
540 PSA_ASSERT( psa_key_derivation_setup( operation, alg ) );
541 if( PSA_ALG_IS_HKDF( alg ) )
542 {
543 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
544 PSA_KEY_DERIVATION_INPUT_SALT,
545 input1, input1_length ) );
546 PSA_ASSERT( psa_key_derivation_input_key( operation,
547 PSA_KEY_DERIVATION_INPUT_SECRET,
548 handle ) );
549 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
550 PSA_KEY_DERIVATION_INPUT_INFO,
551 input2,
552 input2_length ) );
553 }
554 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
555 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
556 {
557 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
558 PSA_KEY_DERIVATION_INPUT_SEED,
559 input1, input1_length ) );
560 PSA_ASSERT( psa_key_derivation_input_key( operation,
561 PSA_KEY_DERIVATION_INPUT_SECRET,
562 handle ) );
563 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
564 PSA_KEY_DERIVATION_INPUT_LABEL,
565 input2, input2_length ) );
566 }
567 else
568 {
569 TEST_ASSERT( ! "Key derivation algorithm not supported" );
570 }
571
Gilles Peskinec744d992019-07-30 17:26:54 +0200572 if( capacity != SIZE_MAX )
573 PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
Janos Follathf2815ea2019-07-03 12:41:36 +0100574
575 return( 1 );
576
577exit:
578 return( 0 );
579}
580
581
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100582static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200583 psa_key_usage_t usage,
584 psa_algorithm_t alg )
585{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200586 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathf2815ea2019-07-03 12:41:36 +0100587 unsigned char input1[] = "Input 1";
588 size_t input1_length = sizeof( input1 );
589 unsigned char input2[] = "Input 2";
590 size_t input2_length = sizeof( input2 );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200591 unsigned char output[1];
Janos Follathf2815ea2019-07-03 12:41:36 +0100592 size_t capacity = sizeof( output );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200593
594 if( usage & PSA_KEY_USAGE_DERIVE )
595 {
Janos Follathf2815ea2019-07-03 12:41:36 +0100596 if( !setup_key_derivation_wrap( &operation, handle, alg,
597 input1, input1_length,
598 input2, input2_length, capacity ) )
599 goto exit;
Gilles Peskine7607cd62019-05-29 17:35:00 +0200600
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200601 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200602 output,
Janos Follathf2815ea2019-07-03 12:41:36 +0100603 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200604 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200605 }
606
607 return( 1 );
608
609exit:
610 return( 0 );
611}
612
Gilles Peskinec7998b72018-11-07 18:45:02 +0100613/* We need two keys to exercise key agreement. Exercise the
614 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200615static psa_status_t key_agreement_with_self(
616 psa_key_derivation_operation_t *operation,
617 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100618{
619 psa_key_type_t private_key_type;
620 psa_key_type_t public_key_type;
621 size_t key_bits;
622 uint8_t *public_key = NULL;
623 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200624 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200625 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
626 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200627 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200628 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100629
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200630 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
631 private_key_type = psa_get_key_type( &attributes );
632 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200633 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100634 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
635 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100636 PSA_ASSERT( psa_export_public_key( handle,
637 public_key, public_key_length,
638 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100639
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200640 status = psa_key_derivation_key_agreement(
641 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
642 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100643exit:
644 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200645 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100646 return( status );
647}
648
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200649/* We need two keys to exercise key agreement. Exercise the
650 * private key against its own public key. */
651static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
652 psa_key_handle_t handle )
653{
654 psa_key_type_t private_key_type;
655 psa_key_type_t public_key_type;
656 size_t key_bits;
657 uint8_t *public_key = NULL;
658 size_t public_key_length;
659 uint8_t output[1024];
660 size_t output_length;
661 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200662 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
663 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200664 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200665 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200666
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200667 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
668 private_key_type = psa_get_key_type( &attributes );
669 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200670 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200671 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
672 ASSERT_ALLOC( public_key, public_key_length );
673 PSA_ASSERT( psa_export_public_key( handle,
674 public_key, public_key_length,
675 &public_key_length ) );
676
Gilles Peskinebe697d82019-05-16 18:00:41 +0200677 status = psa_raw_key_agreement( alg, handle,
678 public_key, public_key_length,
679 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200680exit:
681 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200682 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200683 return( status );
684}
685
686static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
687 psa_key_usage_t usage,
688 psa_algorithm_t alg )
689{
690 int ok = 0;
691
692 if( usage & PSA_KEY_USAGE_DERIVE )
693 {
694 /* We need two keys to exercise key agreement. Exercise the
695 * private key against its own public key. */
696 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
697 }
698 ok = 1;
699
700exit:
701 return( ok );
702}
703
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100704static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200705 psa_key_usage_t usage,
706 psa_algorithm_t alg )
707{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200708 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200709 unsigned char output[1];
710 int ok = 0;
711
712 if( usage & PSA_KEY_USAGE_DERIVE )
713 {
714 /* We need two keys to exercise key agreement. Exercise the
715 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200716 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
717 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
718 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200719 output,
720 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200721 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200722 }
723 ok = 1;
724
725exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200726 return( ok );
727}
728
Jaeden Amerof7dca862019-06-27 17:31:33 +0100729int asn1_skip_integer( unsigned char **p, const unsigned char *end,
730 size_t min_bits, size_t max_bits,
731 int must_be_odd )
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200732{
733 size_t len;
734 size_t actual_bits;
735 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100736 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100737 MBEDTLS_ASN1_INTEGER ),
738 0 );
k-stachowiak9b88efc2019-09-13 15:26:53 +0200739
740 /* Check if the retrieved length doesn't extend the actual buffer's size.
741 * It is assumed here, that end >= p, which validates casting to size_t. */
742 TEST_ASSERT( len <= (size_t)( end - *p) );
743
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200744 /* Tolerate a slight departure from DER encoding:
745 * - 0 may be represented by an empty string or a 1-byte string.
746 * - The sign bit may be used as a value bit. */
747 if( ( len == 1 && ( *p )[0] == 0 ) ||
748 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
749 {
750 ++( *p );
751 --len;
752 }
753 if( min_bits == 0 && len == 0 )
754 return( 1 );
755 msb = ( *p )[0];
756 TEST_ASSERT( msb != 0 );
757 actual_bits = 8 * ( len - 1 );
758 while( msb != 0 )
759 {
760 msb >>= 1;
761 ++actual_bits;
762 }
763 TEST_ASSERT( actual_bits >= min_bits );
764 TEST_ASSERT( actual_bits <= max_bits );
765 if( must_be_odd )
766 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
767 *p += len;
768 return( 1 );
769exit:
770 return( 0 );
771}
772
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200773static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
774 uint8_t *exported, size_t exported_length )
775{
776 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100777 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200778 else
779 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200780
781#if defined(MBEDTLS_DES_C)
782 if( type == PSA_KEY_TYPE_DES )
783 {
784 /* Check the parity bits. */
785 unsigned i;
786 for( i = 0; i < bits / 8; i++ )
787 {
788 unsigned bit_count = 0;
789 unsigned m;
790 for( m = 1; m <= 0x100; m <<= 1 )
791 {
792 if( exported[i] & m )
793 ++bit_count;
794 }
795 TEST_ASSERT( bit_count % 2 != 0 );
796 }
797 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200798 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200799#endif
800
801#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200802 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200803 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200804 uint8_t *p = exported;
805 uint8_t *end = exported + exported_length;
806 size_t len;
807 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200808 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200809 * modulus INTEGER, -- n
810 * publicExponent INTEGER, -- e
811 * privateExponent INTEGER, -- d
812 * prime1 INTEGER, -- p
813 * prime2 INTEGER, -- q
814 * exponent1 INTEGER, -- d mod (p-1)
815 * exponent2 INTEGER, -- d mod (q-1)
816 * coefficient INTEGER, -- (inverse of q) mod p
817 * }
818 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100819 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
820 MBEDTLS_ASN1_SEQUENCE |
821 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
822 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200823 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
824 goto exit;
825 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
826 goto exit;
827 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
828 goto exit;
829 /* Require d to be at least half the size of n. */
830 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
831 goto exit;
832 /* Require p and q to be at most half the size of n, rounded up. */
833 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
834 goto exit;
835 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
836 goto exit;
837 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
838 goto exit;
839 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
840 goto exit;
841 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
842 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100843 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100844 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200845 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200846#endif /* MBEDTLS_RSA_C */
847
848#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200849 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200850 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100851 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100852 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100853 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200854 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200855#endif /* MBEDTLS_ECP_C */
856
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200857 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
858 {
859 uint8_t *p = exported;
860 uint8_t *end = exported + exported_length;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200861#if defined(MBEDTLS_RSA_C)
862 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
863 {
Jaeden Amerof7dca862019-06-27 17:31:33 +0100864 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200865 /* RSAPublicKey ::= SEQUENCE {
866 * modulus INTEGER, -- n
867 * publicExponent INTEGER } -- e
868 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100869 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
870 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100871 MBEDTLS_ASN1_CONSTRUCTED ),
872 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100873 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200874 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
875 goto exit;
876 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
877 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100878 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200879 }
880 else
881#endif /* MBEDTLS_RSA_C */
882#if defined(MBEDTLS_ECP_C)
883 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
884 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000885 /* The representation of an ECC public key is:
886 * - The byte 0x04;
887 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
888 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
889 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000890 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100891 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
892 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200893 }
894 else
895#endif /* MBEDTLS_ECP_C */
896 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100897 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200898 mbedtls_snprintf( message, sizeof( message ),
899 "No sanity check for public key type=0x%08lx",
900 (unsigned long) type );
901 test_fail( message, __LINE__, __FILE__ );
902 return( 0 );
903 }
904 }
905 else
906
907 {
908 /* No sanity checks for other types */
909 }
910
911 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200912
913exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200914 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200915}
916
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100917static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200918 psa_key_usage_t usage )
919{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200920 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200921 uint8_t *exported = NULL;
922 size_t exported_size = 0;
923 size_t exported_length = 0;
924 int ok = 0;
925
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200926 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200927
928 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200929 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200930 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100931 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
932 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200933 ok = 1;
934 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200935 }
936
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200937 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
938 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200939 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200940
Gilles Peskine8817f612018-12-18 00:18:46 +0100941 PSA_ASSERT( psa_export_key( handle,
942 exported, exported_size,
943 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200944 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
945 psa_get_key_bits( &attributes ),
946 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200947
948exit:
949 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200950 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200951 return( ok );
952}
953
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100954static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200955{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200956 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200957 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200958 uint8_t *exported = NULL;
959 size_t exported_size = 0;
960 size_t exported_length = 0;
961 int ok = 0;
962
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200963 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
964 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200965 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100966 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100967 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200968 return( 1 );
969 }
970
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200971 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200972 psa_get_key_type( &attributes ) );
973 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
974 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200975 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200976
Gilles Peskine8817f612018-12-18 00:18:46 +0100977 PSA_ASSERT( psa_export_public_key( handle,
978 exported, exported_size,
979 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200980 ok = exported_key_sanity_check( public_type,
981 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200982 exported, exported_length );
983
984exit:
985 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200986 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200987 return( ok );
988}
989
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100990/** Do smoke tests on a key.
991 *
992 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
993 * sign/verify, or derivation) that is permitted according to \p usage.
994 * \p usage and \p alg should correspond to the expected policy on the
995 * key.
996 *
997 * Export the key if permitted by \p usage, and check that the output
998 * looks sensible. If \p usage forbids export, check that
999 * \p psa_export_key correctly rejects the attempt. If the key is
1000 * asymmetric, also check \p psa_export_public_key.
1001 *
1002 * If the key fails the tests, this function calls the test framework's
1003 * `test_fail` function and returns false. Otherwise this function returns
1004 * true. Therefore it should be used as follows:
1005 * ```
1006 * if( ! exercise_key( ... ) ) goto exit;
1007 * ```
1008 *
1009 * \param handle The key to exercise. It should be capable of performing
1010 * \p alg.
1011 * \param usage The usage flags to assume.
1012 * \param alg The algorithm to exercise.
1013 *
1014 * \retval 0 The key failed the smoke tests.
1015 * \retval 1 The key passed the smoke tests.
1016 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001017static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001018 psa_key_usage_t usage,
1019 psa_algorithm_t alg )
1020{
1021 int ok;
1022 if( alg == 0 )
1023 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1024 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001025 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001026 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001027 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001028 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001029 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001030 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001031 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001032 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001033 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001034 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001035 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001036 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1037 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001038 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001039 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001040 else
1041 {
1042 char message[40];
1043 mbedtls_snprintf( message, sizeof( message ),
1044 "No code to exercise alg=0x%08lx",
1045 (unsigned long) alg );
1046 test_fail( message, __LINE__, __FILE__ );
1047 ok = 0;
1048 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001049
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001050 ok = ok && exercise_export_key( handle, usage );
1051 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001052
Gilles Peskine02b75072018-07-01 22:31:34 +02001053 return( ok );
1054}
1055
Gilles Peskine10df3412018-10-25 22:35:43 +02001056static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1057 psa_algorithm_t alg )
1058{
1059 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1060 {
1061 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1062 PSA_KEY_USAGE_VERIFY :
1063 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1064 }
1065 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1066 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1067 {
1068 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1069 PSA_KEY_USAGE_ENCRYPT :
1070 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1071 }
1072 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1073 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1074 {
1075 return( PSA_KEY_USAGE_DERIVE );
1076 }
1077 else
1078 {
1079 return( 0 );
1080 }
1081
1082}
Darryl Green0c6575a2018-11-07 16:05:30 +00001083
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001084static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1085{
1086 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1087 uint8_t buffer[1];
1088 size_t length;
1089 int ok = 0;
1090
Gilles Peskinec87af662019-05-15 16:12:22 +02001091 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001092 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1093 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1094 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1095 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1096 PSA_ERROR_INVALID_HANDLE );
1097 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001098 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001099 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1100 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1101 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1102 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1103
1104 TEST_EQUAL( psa_export_key( handle,
1105 buffer, sizeof( buffer ), &length ),
1106 PSA_ERROR_INVALID_HANDLE );
1107 TEST_EQUAL( psa_export_public_key( handle,
1108 buffer, sizeof( buffer ), &length ),
1109 PSA_ERROR_INVALID_HANDLE );
1110
1111 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1112 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1113
1114 ok = 1;
1115
1116exit:
1117 psa_reset_key_attributes( &attributes );
1118 return( ok );
1119}
1120
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001121/* Assert that a key isn't reported as having a slot number. */
1122#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1123#define ASSERT_NO_SLOT_NUMBER( attributes ) \
1124 do \
1125 { \
1126 psa_key_slot_number_t ASSERT_NO_SLOT_NUMBER_slot_number; \
1127 TEST_EQUAL( psa_get_key_slot_number( \
1128 attributes, \
1129 &ASSERT_NO_SLOT_NUMBER_slot_number ), \
1130 PSA_ERROR_INVALID_ARGUMENT ); \
1131 } \
1132 while( 0 )
1133#else /* MBEDTLS_PSA_CRYPTO_SE_C */
1134#define ASSERT_NO_SLOT_NUMBER( attributes ) \
1135 ( (void) 0 )
1136#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1137
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001138/* An overapproximation of the amount of storage needed for a key of the
1139 * given type and with the given content. The API doesn't make it easy
1140 * to find a good value for the size. The current implementation doesn't
1141 * care about the value anyway. */
1142#define KEY_BITS_FROM_DATA( type, data ) \
1143 ( data )->len
1144
Darryl Green0c6575a2018-11-07 16:05:30 +00001145typedef enum {
1146 IMPORT_KEY = 0,
1147 GENERATE_KEY = 1,
1148 DERIVE_KEY = 2
1149} generate_method;
1150
Gilles Peskinee59236f2018-01-27 23:32:46 +01001151/* END_HEADER */
1152
1153/* BEGIN_DEPENDENCIES
1154 * depends_on:MBEDTLS_PSA_CRYPTO_C
1155 * END_DEPENDENCIES
1156 */
1157
1158/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001159void static_checks( )
1160{
1161 size_t max_truncated_mac_size =
1162 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1163
1164 /* Check that the length for a truncated MAC always fits in the algorithm
1165 * encoding. The shifted mask is the maximum truncated value. The
1166 * untruncated algorithm may be one byte larger. */
1167 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1168}
1169/* END_CASE */
1170
1171/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001172void attributes_set_get( int id_arg, int lifetime_arg,
1173 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001174 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001175{
Gilles Peskine4747d192019-04-17 15:05:45 +02001176 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001177 psa_key_id_t id = id_arg;
1178 psa_key_lifetime_t lifetime = lifetime_arg;
1179 psa_key_usage_t usage_flags = usage_flags_arg;
1180 psa_algorithm_t alg = alg_arg;
1181 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001182 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001183
1184 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1185 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1186 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1187 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1188 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001189 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001190
Gilles Peskinec87af662019-05-15 16:12:22 +02001191 psa_set_key_id( &attributes, id );
1192 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001193 psa_set_key_usage_flags( &attributes, usage_flags );
1194 psa_set_key_algorithm( &attributes, alg );
1195 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001196 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001197
1198 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1199 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1200 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1201 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1202 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001203 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001204
1205 psa_reset_key_attributes( &attributes );
1206
1207 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1208 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1209 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1210 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1211 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001212 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001213}
1214/* END_CASE */
1215
1216/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001217void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1218 int expected_id_arg, int expected_lifetime_arg )
1219{
1220 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1221 psa_key_id_t id1 = id1_arg;
1222 psa_key_lifetime_t lifetime = lifetime_arg;
1223 psa_key_id_t id2 = id2_arg;
1224 psa_key_id_t expected_id = expected_id_arg;
1225 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1226
1227 if( id1_arg != -1 )
1228 psa_set_key_id( &attributes, id1 );
1229 if( lifetime_arg != -1 )
1230 psa_set_key_lifetime( &attributes, lifetime );
1231 if( id2_arg != -1 )
1232 psa_set_key_id( &attributes, id2 );
1233
1234 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1235 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1236}
1237/* END_CASE */
1238
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001239/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_SE_C */
1240void slot_number_attribute( )
1241{
1242 psa_key_slot_number_t slot_number = 0xdeadbeef;
1243 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1244
1245 /* Initially, there is no slot number. */
1246 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1247 PSA_ERROR_INVALID_ARGUMENT );
1248
1249 /* Test setting a slot number. */
1250 psa_set_key_slot_number( &attributes, 0 );
1251 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1252 TEST_EQUAL( slot_number, 0 );
1253
1254 /* Test changing the slot number. */
1255 psa_set_key_slot_number( &attributes, 42 );
1256 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1257 TEST_EQUAL( slot_number, 42 );
1258
1259 /* Test clearing the slot number. */
1260 psa_clear_key_slot_number( &attributes );
1261 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1262 PSA_ERROR_INVALID_ARGUMENT );
1263
1264 /* Clearing again should have no effect. */
1265 psa_clear_key_slot_number( &attributes );
1266 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1267 PSA_ERROR_INVALID_ARGUMENT );
1268
1269 /* Test that reset clears the slot number. */
1270 psa_set_key_slot_number( &attributes, 42 );
1271 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1272 TEST_EQUAL( slot_number, 42 );
1273 psa_reset_key_attributes( &attributes );
1274 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1275 PSA_ERROR_INVALID_ARGUMENT );
1276}
1277/* END_CASE */
1278
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001279/* BEGIN_CASE */
Gilles Peskine6edfa292019-07-31 15:53:45 +02001280void import_with_policy( int type_arg,
1281 int usage_arg, int alg_arg,
1282 int expected_status_arg )
1283{
1284 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1285 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1286 psa_key_handle_t handle = 0;
1287 psa_key_type_t type = type_arg;
1288 psa_key_usage_t usage = usage_arg;
1289 psa_algorithm_t alg = alg_arg;
1290 psa_status_t expected_status = expected_status_arg;
1291 const uint8_t key_material[16] = {0};
1292 psa_status_t status;
1293
1294 PSA_ASSERT( psa_crypto_init( ) );
1295
1296 psa_set_key_type( &attributes, type );
1297 psa_set_key_usage_flags( &attributes, usage );
1298 psa_set_key_algorithm( &attributes, alg );
1299
1300 status = psa_import_key( &attributes,
1301 key_material, sizeof( key_material ),
1302 &handle );
1303 TEST_EQUAL( status, expected_status );
1304 if( status != PSA_SUCCESS )
1305 goto exit;
1306
1307 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1308 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1309 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1310 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001311 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001312
1313 PSA_ASSERT( psa_destroy_key( handle ) );
1314 test_operations_on_invalid_handle( handle );
1315
1316exit:
1317 psa_destroy_key( handle );
1318 psa_reset_key_attributes( &got_attributes );
1319 PSA_DONE( );
1320}
1321/* END_CASE */
1322
1323/* BEGIN_CASE */
1324void import_with_data( data_t *data, int type_arg,
1325 int attr_bits_arg,
1326 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001327{
1328 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1329 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001330 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001331 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001332 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001333 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001334 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001335
Gilles Peskine8817f612018-12-18 00:18:46 +01001336 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001337
Gilles Peskine4747d192019-04-17 15:05:45 +02001338 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001339 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001340
Gilles Peskine73676cb2019-05-15 20:15:10 +02001341 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001342 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001343 if( status != PSA_SUCCESS )
1344 goto exit;
1345
1346 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1347 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001348 if( attr_bits != 0 )
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001349 TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001350 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001351
1352 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001353 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001354
1355exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001356 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001357 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001358 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001359}
1360/* END_CASE */
1361
1362/* BEGIN_CASE */
Gilles Peskinec744d992019-07-30 17:26:54 +02001363void import_large_key( int type_arg, int byte_size_arg,
1364 int expected_status_arg )
1365{
1366 psa_key_type_t type = type_arg;
1367 size_t byte_size = byte_size_arg;
1368 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1369 psa_status_t expected_status = expected_status_arg;
1370 psa_key_handle_t handle = 0;
1371 psa_status_t status;
1372 uint8_t *buffer = NULL;
1373 size_t buffer_size = byte_size + 1;
1374 size_t n;
1375
1376 /* It would be better to skip the test than fail it if the allocation
1377 * fails, but the test framework doesn't support this yet. */
1378 ASSERT_ALLOC( buffer, buffer_size );
1379 memset( buffer, 'K', byte_size );
1380
1381 PSA_ASSERT( psa_crypto_init( ) );
1382
1383 /* Try importing the key */
1384 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1385 psa_set_key_type( &attributes, type );
1386 status = psa_import_key( &attributes, buffer, byte_size, &handle );
1387 TEST_EQUAL( status, expected_status );
1388
1389 if( status == PSA_SUCCESS )
1390 {
1391 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1392 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1393 TEST_EQUAL( psa_get_key_bits( &attributes ),
1394 PSA_BYTES_TO_BITS( byte_size ) );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001395 ASSERT_NO_SLOT_NUMBER( &attributes );
Gilles Peskinec744d992019-07-30 17:26:54 +02001396 memset( buffer, 0, byte_size + 1 );
1397 PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) );
1398 for( n = 0; n < byte_size; n++ )
1399 TEST_EQUAL( buffer[n], 'K' );
1400 for( n = byte_size; n < buffer_size; n++ )
1401 TEST_EQUAL( buffer[n], 0 );
1402 }
1403
1404exit:
1405 psa_destroy_key( handle );
1406 PSA_DONE( );
1407 mbedtls_free( buffer );
1408}
1409/* END_CASE */
1410
1411/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001412void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1413{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001414 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001415 size_t bits = bits_arg;
1416 psa_status_t expected_status = expected_status_arg;
1417 psa_status_t status;
1418 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001419 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001420 size_t buffer_size = /* Slight overapproximations */
1421 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001422 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001423 unsigned char *p;
1424 int ret;
1425 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001426 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001427
Gilles Peskine8817f612018-12-18 00:18:46 +01001428 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001429 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001430
1431 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1432 bits, keypair ) ) >= 0 );
1433 length = ret;
1434
1435 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001436 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001437 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001438 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001439
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001440 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001441 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001442
1443exit:
1444 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001445 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001446}
1447/* END_CASE */
1448
1449/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001450void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001451 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001452 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001453 int expected_bits,
1454 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001455 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001456 int canonical_input )
1457{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001458 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001459 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001460 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001461 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001462 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001463 unsigned char *exported = NULL;
1464 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001465 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001466 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001467 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001468 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001469 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001470
Moran Pekercb088e72018-07-17 17:36:59 +03001471 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001472 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001473 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001474 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001475 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001476
Gilles Peskine4747d192019-04-17 15:05:45 +02001477 psa_set_key_usage_flags( &attributes, usage_arg );
1478 psa_set_key_algorithm( &attributes, alg );
1479 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001480
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001481 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001482 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001483
1484 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001485 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1486 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1487 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001488 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001489
1490 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001491 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001492 exported, export_size,
1493 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001494 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001495
1496 /* The exported length must be set by psa_export_key() to a value between 0
1497 * and export_size. On errors, the exported length must be 0. */
1498 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1499 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1500 TEST_ASSERT( exported_length <= export_size );
1501
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001502 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001503 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001504 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001505 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001506 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001507 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001508 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001509
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001510 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001511 goto exit;
1512
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001513 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001514 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001515 else
1516 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001517 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001518 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1519 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001520 PSA_ASSERT( psa_export_key( handle2,
1521 reexported,
1522 export_size,
1523 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001524 ASSERT_COMPARE( exported, exported_length,
1525 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001526 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001527 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001528 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001529
1530destroy:
1531 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001532 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001533 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001534
1535exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001536 mbedtls_free( exported );
1537 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001538 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001539 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001540}
1541/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001542
Moran Pekerf709f4a2018-06-06 17:26:04 +03001543/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001544void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001545{
Gilles Peskine8817f612018-12-18 00:18:46 +01001546 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001547 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001548
1549exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001550 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001551}
1552/* END_CASE */
1553
1554/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001555void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001556 int type_arg,
1557 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001558 int export_size_delta,
1559 int expected_export_status_arg,
1560 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001561{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001562 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001563 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001564 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001565 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001566 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001567 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001568 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001569 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001570 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001571
Gilles Peskine8817f612018-12-18 00:18:46 +01001572 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001573
Gilles Peskine4747d192019-04-17 15:05:45 +02001574 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1575 psa_set_key_algorithm( &attributes, alg );
1576 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001577
1578 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001579 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001580
Gilles Peskine49c25912018-10-29 15:15:31 +01001581 /* Export the public key */
1582 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001583 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001584 exported, export_size,
1585 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001586 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001587 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001588 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001589 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001590 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001591 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1592 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001593 TEST_ASSERT( expected_public_key->len <=
1594 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001595 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1596 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001597 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001598
1599exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001600 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001601 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001602 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001603 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001604}
1605/* END_CASE */
1606
Gilles Peskine20035e32018-02-03 22:44:14 +01001607/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001608void import_and_exercise_key( data_t *data,
1609 int type_arg,
1610 int bits_arg,
1611 int alg_arg )
1612{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001613 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001614 psa_key_type_t type = type_arg;
1615 size_t bits = bits_arg;
1616 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001617 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001618 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001619 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001620
Gilles Peskine8817f612018-12-18 00:18:46 +01001621 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001622
Gilles Peskine4747d192019-04-17 15:05:45 +02001623 psa_set_key_usage_flags( &attributes, usage );
1624 psa_set_key_algorithm( &attributes, alg );
1625 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001626
1627 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001628 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001629
1630 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001631 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1632 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1633 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001634
1635 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001636 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001637 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001638
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001639 PSA_ASSERT( psa_destroy_key( handle ) );
1640 test_operations_on_invalid_handle( handle );
1641
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001642exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001643 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001644 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001645 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001646}
1647/* END_CASE */
1648
1649/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001650void key_policy( int usage_arg, int alg_arg )
1651{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001652 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001653 psa_algorithm_t alg = alg_arg;
1654 psa_key_usage_t usage = usage_arg;
1655 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1656 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001657 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001658
1659 memset( key, 0x2a, sizeof( key ) );
1660
Gilles Peskine8817f612018-12-18 00:18:46 +01001661 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001662
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001663 psa_set_key_usage_flags( &attributes, usage );
1664 psa_set_key_algorithm( &attributes, alg );
1665 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001666
Gilles Peskine73676cb2019-05-15 20:15:10 +02001667 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001668
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001669 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1670 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1671 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1672 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001673
1674exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001675 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001676 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001677 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001678}
1679/* END_CASE */
1680
1681/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001682void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001683{
1684 /* Test each valid way of initializing the object, except for `= {0}`, as
1685 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1686 * though it's OK by the C standard. We could test for this, but we'd need
1687 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001688 psa_key_attributes_t func = psa_key_attributes_init( );
1689 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1690 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001691
1692 memset( &zero, 0, sizeof( zero ) );
1693
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001694 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1695 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1696 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001697
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001698 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1699 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1700 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1701
1702 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1703 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1704 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1705
1706 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1707 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1708 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1709
1710 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1711 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1712 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001713}
1714/* END_CASE */
1715
1716/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001717void mac_key_policy( int policy_usage,
1718 int policy_alg,
1719 int key_type,
1720 data_t *key_data,
1721 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001722{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001723 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001724 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001725 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001726 psa_status_t status;
1727 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001728
Gilles Peskine8817f612018-12-18 00:18:46 +01001729 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001730
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001731 psa_set_key_usage_flags( &attributes, policy_usage );
1732 psa_set_key_algorithm( &attributes, policy_alg );
1733 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001734
Gilles Peskine049c7532019-05-15 20:22:09 +02001735 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1736 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001737
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001738 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001739 if( policy_alg == exercise_alg &&
1740 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001741 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001742 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001743 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001744 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001745
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001746 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001747 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748 if( policy_alg == exercise_alg &&
1749 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001750 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001751 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001752 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001753
1754exit:
1755 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001756 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001757 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001758}
1759/* END_CASE */
1760
1761/* BEGIN_CASE */
1762void cipher_key_policy( int policy_usage,
1763 int policy_alg,
1764 int key_type,
1765 data_t *key_data,
1766 int exercise_alg )
1767{
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;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001770 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001771 psa_status_t status;
1772
Gilles Peskine8817f612018-12-18 00:18:46 +01001773 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001774
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001775 psa_set_key_usage_flags( &attributes, policy_usage );
1776 psa_set_key_algorithm( &attributes, policy_alg );
1777 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001778
Gilles Peskine049c7532019-05-15 20:22:09 +02001779 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1780 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001781
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001782 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001783 if( policy_alg == exercise_alg &&
1784 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001785 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001786 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001787 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001788 psa_cipher_abort( &operation );
1789
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001790 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001791 if( policy_alg == exercise_alg &&
1792 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001793 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001794 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001795 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796
1797exit:
1798 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001799 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001800 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001801}
1802/* END_CASE */
1803
1804/* BEGIN_CASE */
1805void aead_key_policy( int policy_usage,
1806 int policy_alg,
1807 int key_type,
1808 data_t *key_data,
1809 int nonce_length_arg,
1810 int tag_length_arg,
1811 int exercise_alg )
1812{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001813 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001814 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001815 psa_status_t status;
1816 unsigned char nonce[16] = {0};
1817 size_t nonce_length = nonce_length_arg;
1818 unsigned char tag[16];
1819 size_t tag_length = tag_length_arg;
1820 size_t output_length;
1821
1822 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1823 TEST_ASSERT( tag_length <= sizeof( tag ) );
1824
Gilles Peskine8817f612018-12-18 00:18:46 +01001825 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001826
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001827 psa_set_key_usage_flags( &attributes, policy_usage );
1828 psa_set_key_algorithm( &attributes, policy_alg );
1829 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001830
Gilles Peskine049c7532019-05-15 20:22:09 +02001831 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1832 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001833
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001834 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001835 nonce, nonce_length,
1836 NULL, 0,
1837 NULL, 0,
1838 tag, tag_length,
1839 &output_length );
1840 if( policy_alg == exercise_alg &&
1841 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001842 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001843 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001844 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001845
1846 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001847 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001848 nonce, nonce_length,
1849 NULL, 0,
1850 tag, tag_length,
1851 NULL, 0,
1852 &output_length );
1853 if( policy_alg == exercise_alg &&
1854 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001855 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001856 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001857 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001858
1859exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001860 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001861 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001862}
1863/* END_CASE */
1864
1865/* BEGIN_CASE */
1866void asymmetric_encryption_key_policy( int policy_usage,
1867 int policy_alg,
1868 int key_type,
1869 data_t *key_data,
1870 int exercise_alg )
1871{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001872 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001873 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001874 psa_status_t status;
1875 size_t key_bits;
1876 size_t buffer_length;
1877 unsigned char *buffer = NULL;
1878 size_t output_length;
1879
Gilles Peskine8817f612018-12-18 00:18:46 +01001880 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001881
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001882 psa_set_key_usage_flags( &attributes, policy_usage );
1883 psa_set_key_algorithm( &attributes, policy_alg );
1884 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001885
Gilles Peskine049c7532019-05-15 20:22:09 +02001886 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1887 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001888
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001889 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1890 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001891 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1892 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001893 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001894
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001895 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001896 NULL, 0,
1897 NULL, 0,
1898 buffer, buffer_length,
1899 &output_length );
1900 if( policy_alg == exercise_alg &&
1901 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001902 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001903 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001904 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001905
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001906 if( buffer_length != 0 )
1907 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001908 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001909 buffer, buffer_length,
1910 NULL, 0,
1911 buffer, buffer_length,
1912 &output_length );
1913 if( policy_alg == exercise_alg &&
1914 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001915 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001916 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001917 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001918
1919exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001920 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001921 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001922 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001923 mbedtls_free( buffer );
1924}
1925/* END_CASE */
1926
1927/* BEGIN_CASE */
1928void asymmetric_signature_key_policy( int policy_usage,
1929 int policy_alg,
1930 int key_type,
1931 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001932 int exercise_alg,
1933 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001934{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001935 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001936 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001937 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001938 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1939 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1940 * compatible with the policy and `payload_length_arg` is supposed to be
1941 * a valid input length to sign. If `payload_length_arg <= 0`,
1942 * `exercise_alg` is supposed to be forbidden by the policy. */
1943 int compatible_alg = payload_length_arg > 0;
1944 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001945 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1946 size_t signature_length;
1947
Gilles Peskine8817f612018-12-18 00:18:46 +01001948 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001949
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001950 psa_set_key_usage_flags( &attributes, policy_usage );
1951 psa_set_key_algorithm( &attributes, policy_alg );
1952 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001953
Gilles Peskine049c7532019-05-15 20:22:09 +02001954 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1955 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001956
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001957 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001958 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001959 signature, sizeof( signature ),
1960 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001961 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001962 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001963 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001964 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001965
1966 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001967 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001968 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001969 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001970 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001971 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001972 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001973 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001974
1975exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001976 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001977 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001978}
1979/* END_CASE */
1980
Janos Follathba3fab92019-06-11 14:50:16 +01001981/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001982void derive_key_policy( int policy_usage,
1983 int policy_alg,
1984 int key_type,
1985 data_t *key_data,
1986 int exercise_alg )
1987{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001988 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001989 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001990 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001991 psa_status_t status;
1992
Gilles Peskine8817f612018-12-18 00:18:46 +01001993 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001994
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001995 psa_set_key_usage_flags( &attributes, policy_usage );
1996 psa_set_key_algorithm( &attributes, policy_alg );
1997 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001998
Gilles Peskine049c7532019-05-15 20:22:09 +02001999 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2000 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002001
Janos Follathba3fab92019-06-11 14:50:16 +01002002 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
2003
2004 if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
2005 PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
Janos Follath0c1ed842019-06-28 13:35:36 +01002006 {
Janos Follathba3fab92019-06-11 14:50:16 +01002007 PSA_ASSERT( psa_key_derivation_input_bytes(
2008 &operation,
2009 PSA_KEY_DERIVATION_INPUT_SEED,
2010 (const uint8_t*) "", 0) );
Janos Follath0c1ed842019-06-28 13:35:36 +01002011 }
Janos Follathba3fab92019-06-11 14:50:16 +01002012
2013 status = psa_key_derivation_input_key( &operation,
2014 PSA_KEY_DERIVATION_INPUT_SECRET,
2015 handle );
2016
Gilles Peskineea0fb492018-07-12 17:17:20 +02002017 if( policy_alg == exercise_alg &&
2018 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002019 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002020 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002021 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002022
2023exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002024 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002025 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002026 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002027}
2028/* END_CASE */
2029
2030/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02002031void agreement_key_policy( int policy_usage,
2032 int policy_alg,
2033 int key_type_arg,
2034 data_t *key_data,
2035 int exercise_alg )
2036{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002037 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002038 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02002039 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002040 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02002041 psa_status_t status;
2042
Gilles Peskine8817f612018-12-18 00:18:46 +01002043 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002044
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002045 psa_set_key_usage_flags( &attributes, policy_usage );
2046 psa_set_key_algorithm( &attributes, policy_alg );
2047 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002048
Gilles Peskine049c7532019-05-15 20:22:09 +02002049 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2050 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002051
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002052 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
2053 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002054
Gilles Peskine01d718c2018-09-18 12:01:02 +02002055 if( policy_alg == exercise_alg &&
2056 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002057 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002058 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002059 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002060
2061exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002062 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002063 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002064 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002065}
2066/* END_CASE */
2067
2068/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002069void key_policy_alg2( int key_type_arg, data_t *key_data,
2070 int usage_arg, int alg_arg, int alg2_arg )
2071{
2072 psa_key_handle_t handle = 0;
2073 psa_key_type_t key_type = key_type_arg;
2074 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
2075 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
2076 psa_key_usage_t usage = usage_arg;
2077 psa_algorithm_t alg = alg_arg;
2078 psa_algorithm_t alg2 = alg2_arg;
2079
2080 PSA_ASSERT( psa_crypto_init( ) );
2081
2082 psa_set_key_usage_flags( &attributes, usage );
2083 psa_set_key_algorithm( &attributes, alg );
2084 psa_set_key_enrollment_algorithm( &attributes, alg2 );
2085 psa_set_key_type( &attributes, key_type );
2086 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2087 &handle ) );
2088
2089 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
2090 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
2091 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
2092 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
2093
2094 if( ! exercise_key( handle, usage, alg ) )
2095 goto exit;
2096 if( ! exercise_key( handle, usage, alg2 ) )
2097 goto exit;
2098
2099exit:
2100 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002101 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002102}
2103/* END_CASE */
2104
2105/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002106void raw_agreement_key_policy( int policy_usage,
2107 int policy_alg,
2108 int key_type_arg,
2109 data_t *key_data,
2110 int exercise_alg )
2111{
2112 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002113 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002114 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002115 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002116 psa_status_t status;
2117
2118 PSA_ASSERT( psa_crypto_init( ) );
2119
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002120 psa_set_key_usage_flags( &attributes, policy_usage );
2121 psa_set_key_algorithm( &attributes, policy_alg );
2122 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002123
Gilles Peskine049c7532019-05-15 20:22:09 +02002124 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2125 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002126
2127 status = raw_key_agreement_with_self( exercise_alg, handle );
2128
2129 if( policy_alg == exercise_alg &&
2130 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
2131 PSA_ASSERT( status );
2132 else
2133 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
2134
2135exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002136 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002137 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002138 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002139}
2140/* END_CASE */
2141
2142/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002143void copy_success( int source_usage_arg,
2144 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002145 int type_arg, data_t *material,
2146 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002147 int target_usage_arg,
2148 int target_alg_arg, int target_alg2_arg,
2149 int expected_usage_arg,
2150 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01002151{
Gilles Peskineca25db92019-04-19 11:43:08 +02002152 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2153 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002154 psa_key_usage_t expected_usage = expected_usage_arg;
2155 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002156 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002157 psa_key_handle_t source_handle = 0;
2158 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002159 uint8_t *export_buffer = NULL;
2160
Gilles Peskine57ab7212019-01-28 13:03:09 +01002161 PSA_ASSERT( psa_crypto_init( ) );
2162
Gilles Peskineca25db92019-04-19 11:43:08 +02002163 /* Prepare the source key. */
2164 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2165 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002166 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002167 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002168 PSA_ASSERT( psa_import_key( &source_attributes,
2169 material->x, material->len,
2170 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002171 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002172
Gilles Peskineca25db92019-04-19 11:43:08 +02002173 /* Prepare the target attributes. */
2174 if( copy_attributes )
2175 target_attributes = source_attributes;
2176 if( target_usage_arg != -1 )
2177 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2178 if( target_alg_arg != -1 )
2179 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002180 if( target_alg2_arg != -1 )
2181 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002182
2183 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002184 PSA_ASSERT( psa_copy_key( source_handle,
2185 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002186
2187 /* Destroy the source to ensure that this doesn't affect the target. */
2188 PSA_ASSERT( psa_destroy_key( source_handle ) );
2189
2190 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002191 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2192 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2193 psa_get_key_type( &target_attributes ) );
2194 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2195 psa_get_key_bits( &target_attributes ) );
2196 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2197 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002198 TEST_EQUAL( expected_alg2,
2199 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002200 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2201 {
2202 size_t length;
2203 ASSERT_ALLOC( export_buffer, material->len );
2204 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2205 material->len, &length ) );
2206 ASSERT_COMPARE( material->x, material->len,
2207 export_buffer, length );
2208 }
2209 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2210 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002211 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2212 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002213
2214 PSA_ASSERT( psa_close_key( target_handle ) );
2215
2216exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002217 psa_reset_key_attributes( &source_attributes );
2218 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002219 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002220 mbedtls_free( export_buffer );
2221}
2222/* END_CASE */
2223
2224/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002225void copy_fail( int source_usage_arg,
2226 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002227 int type_arg, data_t *material,
2228 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002229 int target_usage_arg,
2230 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002231 int expected_status_arg )
2232{
2233 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2234 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2235 psa_key_handle_t source_handle = 0;
2236 psa_key_handle_t target_handle = 0;
2237
2238 PSA_ASSERT( psa_crypto_init( ) );
2239
2240 /* Prepare the source key. */
2241 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2242 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002243 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002244 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002245 PSA_ASSERT( psa_import_key( &source_attributes,
2246 material->x, material->len,
2247 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002248
2249 /* Prepare the target attributes. */
2250 psa_set_key_type( &target_attributes, target_type_arg );
2251 psa_set_key_bits( &target_attributes, target_bits_arg );
2252 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2253 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002254 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002255
2256 /* Try to copy the key. */
2257 TEST_EQUAL( psa_copy_key( source_handle,
2258 &target_attributes, &target_handle ),
2259 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002260
2261 PSA_ASSERT( psa_destroy_key( source_handle ) );
2262
Gilles Peskine4a644642019-05-03 17:14:08 +02002263exit:
2264 psa_reset_key_attributes( &source_attributes );
2265 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002266 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002267}
2268/* END_CASE */
2269
2270/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002271void hash_operation_init( )
2272{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002273 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002274 /* Test each valid way of initializing the object, except for `= {0}`, as
2275 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2276 * though it's OK by the C standard. We could test for this, but we'd need
2277 * to supress the Clang warning for the test. */
2278 psa_hash_operation_t func = psa_hash_operation_init( );
2279 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2280 psa_hash_operation_t zero;
2281
2282 memset( &zero, 0, sizeof( zero ) );
2283
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002284 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002285 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2286 PSA_ERROR_BAD_STATE );
2287 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2288 PSA_ERROR_BAD_STATE );
2289 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2290 PSA_ERROR_BAD_STATE );
2291
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002292 /* A default hash operation should be abortable without error. */
2293 PSA_ASSERT( psa_hash_abort( &func ) );
2294 PSA_ASSERT( psa_hash_abort( &init ) );
2295 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002296}
2297/* END_CASE */
2298
2299/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002300void hash_setup( int alg_arg,
2301 int expected_status_arg )
2302{
2303 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002304 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002305 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002306 psa_status_t status;
2307
Gilles Peskine8817f612018-12-18 00:18:46 +01002308 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002309
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002310 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002311 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002312
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002313 /* Whether setup succeeded or failed, abort must succeed. */
2314 PSA_ASSERT( psa_hash_abort( &operation ) );
2315
2316 /* If setup failed, reproduce the failure, so as to
2317 * test the resulting state of the operation object. */
2318 if( status != PSA_SUCCESS )
2319 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2320
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002321 /* Now the operation object should be reusable. */
2322#if defined(KNOWN_SUPPORTED_HASH_ALG)
2323 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2324 PSA_ASSERT( psa_hash_abort( &operation ) );
2325#endif
2326
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002327exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002328 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002329}
2330/* END_CASE */
2331
2332/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002333void hash_bad_order( )
2334{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002335 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002336 unsigned char input[] = "";
2337 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002338 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002339 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2340 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2341 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002342 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002343 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002344 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002345
Gilles Peskine8817f612018-12-18 00:18:46 +01002346 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002347
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002348 /* Call setup twice in a row. */
2349 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2350 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2351 PSA_ERROR_BAD_STATE );
2352 PSA_ASSERT( psa_hash_abort( &operation ) );
2353
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002354 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002355 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002356 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002357 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002358
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002359 /* Call update after finish. */
2360 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2361 PSA_ASSERT( psa_hash_finish( &operation,
2362 hash, sizeof( hash ), &hash_len ) );
2363 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002364 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002365 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002366
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002367 /* Call verify without calling setup beforehand. */
2368 TEST_EQUAL( psa_hash_verify( &operation,
2369 valid_hash, sizeof( valid_hash ) ),
2370 PSA_ERROR_BAD_STATE );
2371 PSA_ASSERT( psa_hash_abort( &operation ) );
2372
2373 /* Call verify after finish. */
2374 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2375 PSA_ASSERT( psa_hash_finish( &operation,
2376 hash, sizeof( hash ), &hash_len ) );
2377 TEST_EQUAL( psa_hash_verify( &operation,
2378 valid_hash, sizeof( valid_hash ) ),
2379 PSA_ERROR_BAD_STATE );
2380 PSA_ASSERT( psa_hash_abort( &operation ) );
2381
2382 /* Call verify twice in a row. */
2383 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2384 PSA_ASSERT( psa_hash_verify( &operation,
2385 valid_hash, sizeof( valid_hash ) ) );
2386 TEST_EQUAL( psa_hash_verify( &operation,
2387 valid_hash, sizeof( valid_hash ) ),
2388 PSA_ERROR_BAD_STATE );
2389 PSA_ASSERT( psa_hash_abort( &operation ) );
2390
2391 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002392 TEST_EQUAL( psa_hash_finish( &operation,
2393 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002394 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002395 PSA_ASSERT( psa_hash_abort( &operation ) );
2396
2397 /* Call finish twice in a row. */
2398 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2399 PSA_ASSERT( psa_hash_finish( &operation,
2400 hash, sizeof( hash ), &hash_len ) );
2401 TEST_EQUAL( psa_hash_finish( &operation,
2402 hash, sizeof( hash ), &hash_len ),
2403 PSA_ERROR_BAD_STATE );
2404 PSA_ASSERT( psa_hash_abort( &operation ) );
2405
2406 /* Call finish after calling verify. */
2407 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2408 PSA_ASSERT( psa_hash_verify( &operation,
2409 valid_hash, sizeof( valid_hash ) ) );
2410 TEST_EQUAL( psa_hash_finish( &operation,
2411 hash, sizeof( hash ), &hash_len ),
2412 PSA_ERROR_BAD_STATE );
2413 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002414
2415exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002416 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002417}
2418/* END_CASE */
2419
itayzafrir27e69452018-11-01 14:26:34 +02002420/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2421void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002422{
2423 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002424 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2425 * appended to it */
2426 unsigned char hash[] = {
2427 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2428 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2429 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002430 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002431 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002432
Gilles Peskine8817f612018-12-18 00:18:46 +01002433 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002434
itayzafrir27e69452018-11-01 14:26:34 +02002435 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002436 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002437 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002438 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002439
itayzafrir27e69452018-11-01 14:26:34 +02002440 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002441 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002442 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002443 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002444
itayzafrir27e69452018-11-01 14:26:34 +02002445 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002446 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002447 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002448 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002449
itayzafrirec93d302018-10-18 18:01:10 +03002450exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002451 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002452}
2453/* END_CASE */
2454
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002455/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2456void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002457{
2458 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002459 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002460 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002461 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002462 size_t hash_len;
2463
Gilles Peskine8817f612018-12-18 00:18:46 +01002464 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002465
itayzafrir58028322018-10-25 10:22:01 +03002466 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002467 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002468 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002469 hash, expected_size - 1, &hash_len ),
2470 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002471
2472exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002473 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002474}
2475/* END_CASE */
2476
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002477/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2478void hash_clone_source_state( )
2479{
2480 psa_algorithm_t alg = PSA_ALG_SHA_256;
2481 unsigned char hash[PSA_HASH_MAX_SIZE];
2482 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2483 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2484 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2485 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2486 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2487 size_t hash_len;
2488
2489 PSA_ASSERT( psa_crypto_init( ) );
2490 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2491
2492 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2493 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2494 PSA_ASSERT( psa_hash_finish( &op_finished,
2495 hash, sizeof( hash ), &hash_len ) );
2496 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2497 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2498
2499 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2500 PSA_ERROR_BAD_STATE );
2501
2502 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2503 PSA_ASSERT( psa_hash_finish( &op_init,
2504 hash, sizeof( hash ), &hash_len ) );
2505 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2506 PSA_ASSERT( psa_hash_finish( &op_finished,
2507 hash, sizeof( hash ), &hash_len ) );
2508 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2509 PSA_ASSERT( psa_hash_finish( &op_aborted,
2510 hash, sizeof( hash ), &hash_len ) );
2511
2512exit:
2513 psa_hash_abort( &op_source );
2514 psa_hash_abort( &op_init );
2515 psa_hash_abort( &op_setup );
2516 psa_hash_abort( &op_finished );
2517 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002518 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002519}
2520/* END_CASE */
2521
2522/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2523void hash_clone_target_state( )
2524{
2525 psa_algorithm_t alg = PSA_ALG_SHA_256;
2526 unsigned char hash[PSA_HASH_MAX_SIZE];
2527 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2528 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2529 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2530 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2531 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2532 size_t hash_len;
2533
2534 PSA_ASSERT( psa_crypto_init( ) );
2535
2536 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2537 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2538 PSA_ASSERT( psa_hash_finish( &op_finished,
2539 hash, sizeof( hash ), &hash_len ) );
2540 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2541 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2542
2543 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2544 PSA_ASSERT( psa_hash_finish( &op_target,
2545 hash, sizeof( hash ), &hash_len ) );
2546
2547 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2548 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2549 PSA_ERROR_BAD_STATE );
2550 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2551 PSA_ERROR_BAD_STATE );
2552
2553exit:
2554 psa_hash_abort( &op_target );
2555 psa_hash_abort( &op_init );
2556 psa_hash_abort( &op_setup );
2557 psa_hash_abort( &op_finished );
2558 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002559 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002560}
2561/* END_CASE */
2562
itayzafrir58028322018-10-25 10:22:01 +03002563/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002564void mac_operation_init( )
2565{
Jaeden Amero252ef282019-02-15 14:05:35 +00002566 const uint8_t input[1] = { 0 };
2567
Jaeden Amero769ce272019-01-04 11:48:03 +00002568 /* Test each valid way of initializing the object, except for `= {0}`, as
2569 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2570 * though it's OK by the C standard. We could test for this, but we'd need
2571 * to supress the Clang warning for the test. */
2572 psa_mac_operation_t func = psa_mac_operation_init( );
2573 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2574 psa_mac_operation_t zero;
2575
2576 memset( &zero, 0, sizeof( zero ) );
2577
Jaeden Amero252ef282019-02-15 14:05:35 +00002578 /* A freshly-initialized MAC operation should not be usable. */
2579 TEST_EQUAL( psa_mac_update( &func,
2580 input, sizeof( input ) ),
2581 PSA_ERROR_BAD_STATE );
2582 TEST_EQUAL( psa_mac_update( &init,
2583 input, sizeof( input ) ),
2584 PSA_ERROR_BAD_STATE );
2585 TEST_EQUAL( psa_mac_update( &zero,
2586 input, sizeof( input ) ),
2587 PSA_ERROR_BAD_STATE );
2588
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002589 /* A default MAC operation should be abortable without error. */
2590 PSA_ASSERT( psa_mac_abort( &func ) );
2591 PSA_ASSERT( psa_mac_abort( &init ) );
2592 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002593}
2594/* END_CASE */
2595
2596/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002597void mac_setup( int key_type_arg,
2598 data_t *key,
2599 int alg_arg,
2600 int expected_status_arg )
2601{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002602 psa_key_type_t key_type = key_type_arg;
2603 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002604 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002605 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002606 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2607#if defined(KNOWN_SUPPORTED_MAC_ALG)
2608 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2609#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002610
Gilles Peskine8817f612018-12-18 00:18:46 +01002611 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002612
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002613 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2614 &operation, &status ) )
2615 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002616 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002617
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002618 /* The operation object should be reusable. */
2619#if defined(KNOWN_SUPPORTED_MAC_ALG)
2620 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2621 smoke_test_key_data,
2622 sizeof( smoke_test_key_data ),
2623 KNOWN_SUPPORTED_MAC_ALG,
2624 &operation, &status ) )
2625 goto exit;
2626 TEST_EQUAL( status, PSA_SUCCESS );
2627#endif
2628
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002629exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002630 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002631}
2632/* END_CASE */
2633
2634/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002635void mac_bad_order( )
2636{
2637 psa_key_handle_t handle = 0;
2638 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2639 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2640 const uint8_t key[] = {
2641 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2642 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2643 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002644 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002645 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2646 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2647 size_t sign_mac_length = 0;
2648 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2649 const uint8_t verify_mac[] = {
2650 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2651 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2652 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2653
2654 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002655 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2656 psa_set_key_algorithm( &attributes, alg );
2657 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002658
Gilles Peskine73676cb2019-05-15 20:15:10 +02002659 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002660
Jaeden Amero252ef282019-02-15 14:05:35 +00002661 /* Call update without calling setup beforehand. */
2662 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2663 PSA_ERROR_BAD_STATE );
2664 PSA_ASSERT( psa_mac_abort( &operation ) );
2665
2666 /* Call sign finish without calling setup beforehand. */
2667 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2668 &sign_mac_length),
2669 PSA_ERROR_BAD_STATE );
2670 PSA_ASSERT( psa_mac_abort( &operation ) );
2671
2672 /* Call verify finish without calling setup beforehand. */
2673 TEST_EQUAL( psa_mac_verify_finish( &operation,
2674 verify_mac, sizeof( verify_mac ) ),
2675 PSA_ERROR_BAD_STATE );
2676 PSA_ASSERT( psa_mac_abort( &operation ) );
2677
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002678 /* Call setup twice in a row. */
2679 PSA_ASSERT( psa_mac_sign_setup( &operation,
2680 handle, alg ) );
2681 TEST_EQUAL( psa_mac_sign_setup( &operation,
2682 handle, alg ),
2683 PSA_ERROR_BAD_STATE );
2684 PSA_ASSERT( psa_mac_abort( &operation ) );
2685
Jaeden Amero252ef282019-02-15 14:05:35 +00002686 /* Call update after sign finish. */
2687 PSA_ASSERT( psa_mac_sign_setup( &operation,
2688 handle, alg ) );
2689 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2690 PSA_ASSERT( psa_mac_sign_finish( &operation,
2691 sign_mac, sizeof( sign_mac ),
2692 &sign_mac_length ) );
2693 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2694 PSA_ERROR_BAD_STATE );
2695 PSA_ASSERT( psa_mac_abort( &operation ) );
2696
2697 /* Call update after verify finish. */
2698 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002699 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002700 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2701 PSA_ASSERT( psa_mac_verify_finish( &operation,
2702 verify_mac, sizeof( verify_mac ) ) );
2703 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2704 PSA_ERROR_BAD_STATE );
2705 PSA_ASSERT( psa_mac_abort( &operation ) );
2706
2707 /* Call sign finish twice in a row. */
2708 PSA_ASSERT( psa_mac_sign_setup( &operation,
2709 handle, alg ) );
2710 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2711 PSA_ASSERT( psa_mac_sign_finish( &operation,
2712 sign_mac, sizeof( sign_mac ),
2713 &sign_mac_length ) );
2714 TEST_EQUAL( psa_mac_sign_finish( &operation,
2715 sign_mac, sizeof( sign_mac ),
2716 &sign_mac_length ),
2717 PSA_ERROR_BAD_STATE );
2718 PSA_ASSERT( psa_mac_abort( &operation ) );
2719
2720 /* Call verify finish twice in a row. */
2721 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002722 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002723 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2724 PSA_ASSERT( psa_mac_verify_finish( &operation,
2725 verify_mac, sizeof( verify_mac ) ) );
2726 TEST_EQUAL( psa_mac_verify_finish( &operation,
2727 verify_mac, sizeof( verify_mac ) ),
2728 PSA_ERROR_BAD_STATE );
2729 PSA_ASSERT( psa_mac_abort( &operation ) );
2730
2731 /* Setup sign but try verify. */
2732 PSA_ASSERT( psa_mac_sign_setup( &operation,
2733 handle, alg ) );
2734 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2735 TEST_EQUAL( psa_mac_verify_finish( &operation,
2736 verify_mac, sizeof( verify_mac ) ),
2737 PSA_ERROR_BAD_STATE );
2738 PSA_ASSERT( psa_mac_abort( &operation ) );
2739
2740 /* Setup verify but try sign. */
2741 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002742 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002743 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2744 TEST_EQUAL( psa_mac_sign_finish( &operation,
2745 sign_mac, sizeof( sign_mac ),
2746 &sign_mac_length ),
2747 PSA_ERROR_BAD_STATE );
2748 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002749
Gilles Peskine76b29a72019-05-28 14:08:50 +02002750 PSA_ASSERT( psa_destroy_key( handle ) );
2751
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002752exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002753 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002754}
2755/* END_CASE */
2756
2757/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002758void mac_sign( int key_type_arg,
2759 data_t *key,
2760 int alg_arg,
2761 data_t *input,
2762 data_t *expected_mac )
2763{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002764 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002765 psa_key_type_t key_type = key_type_arg;
2766 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002767 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002768 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002769 /* Leave a little extra room in the output buffer. At the end of the
2770 * test, we'll check that the implementation didn't overwrite onto
2771 * this extra room. */
2772 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2773 size_t mac_buffer_size =
2774 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2775 size_t mac_length = 0;
2776
2777 memset( actual_mac, '+', sizeof( actual_mac ) );
2778 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2779 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2780
Gilles Peskine8817f612018-12-18 00:18:46 +01002781 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002782
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002783 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2784 psa_set_key_algorithm( &attributes, alg );
2785 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002786
Gilles Peskine73676cb2019-05-15 20:15:10 +02002787 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002788
2789 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002790 PSA_ASSERT( psa_mac_sign_setup( &operation,
2791 handle, alg ) );
2792 PSA_ASSERT( psa_mac_update( &operation,
2793 input->x, input->len ) );
2794 PSA_ASSERT( psa_mac_sign_finish( &operation,
2795 actual_mac, mac_buffer_size,
2796 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002797
2798 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002799 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2800 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002801
2802 /* Verify that the end of the buffer is untouched. */
2803 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2804 sizeof( actual_mac ) - mac_length ) );
2805
2806exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002807 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002808 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002809}
2810/* END_CASE */
2811
2812/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002813void mac_verify( int key_type_arg,
2814 data_t *key,
2815 int alg_arg,
2816 data_t *input,
2817 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002818{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002819 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002820 psa_key_type_t key_type = key_type_arg;
2821 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002822 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002823 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002824
Gilles Peskine69c12672018-06-28 00:07:19 +02002825 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2826
Gilles Peskine8817f612018-12-18 00:18:46 +01002827 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002828
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002829 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2830 psa_set_key_algorithm( &attributes, alg );
2831 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002832
Gilles Peskine73676cb2019-05-15 20:15:10 +02002833 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002834
Gilles Peskine8817f612018-12-18 00:18:46 +01002835 PSA_ASSERT( psa_mac_verify_setup( &operation,
2836 handle, alg ) );
2837 PSA_ASSERT( psa_destroy_key( handle ) );
2838 PSA_ASSERT( psa_mac_update( &operation,
2839 input->x, input->len ) );
2840 PSA_ASSERT( psa_mac_verify_finish( &operation,
2841 expected_mac->x,
2842 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002843
2844exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002845 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002846 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002847}
2848/* END_CASE */
2849
2850/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002851void cipher_operation_init( )
2852{
Jaeden Ameroab439972019-02-15 14:12:05 +00002853 const uint8_t input[1] = { 0 };
2854 unsigned char output[1] = { 0 };
2855 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002856 /* Test each valid way of initializing the object, except for `= {0}`, as
2857 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2858 * though it's OK by the C standard. We could test for this, but we'd need
2859 * to supress the Clang warning for the test. */
2860 psa_cipher_operation_t func = psa_cipher_operation_init( );
2861 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2862 psa_cipher_operation_t zero;
2863
2864 memset( &zero, 0, sizeof( zero ) );
2865
Jaeden Ameroab439972019-02-15 14:12:05 +00002866 /* A freshly-initialized cipher operation should not be usable. */
2867 TEST_EQUAL( psa_cipher_update( &func,
2868 input, sizeof( input ),
2869 output, sizeof( output ),
2870 &output_length ),
2871 PSA_ERROR_BAD_STATE );
2872 TEST_EQUAL( psa_cipher_update( &init,
2873 input, sizeof( input ),
2874 output, sizeof( output ),
2875 &output_length ),
2876 PSA_ERROR_BAD_STATE );
2877 TEST_EQUAL( psa_cipher_update( &zero,
2878 input, sizeof( input ),
2879 output, sizeof( output ),
2880 &output_length ),
2881 PSA_ERROR_BAD_STATE );
2882
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002883 /* A default cipher operation should be abortable without error. */
2884 PSA_ASSERT( psa_cipher_abort( &func ) );
2885 PSA_ASSERT( psa_cipher_abort( &init ) );
2886 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002887}
2888/* END_CASE */
2889
2890/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002891void cipher_setup( int key_type_arg,
2892 data_t *key,
2893 int alg_arg,
2894 int expected_status_arg )
2895{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002896 psa_key_type_t key_type = key_type_arg;
2897 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002898 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002899 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002900 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002901#if defined(KNOWN_SUPPORTED_MAC_ALG)
2902 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2903#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002904
Gilles Peskine8817f612018-12-18 00:18:46 +01002905 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002906
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002907 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2908 &operation, &status ) )
2909 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002910 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002911
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002912 /* The operation object should be reusable. */
2913#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2914 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2915 smoke_test_key_data,
2916 sizeof( smoke_test_key_data ),
2917 KNOWN_SUPPORTED_CIPHER_ALG,
2918 &operation, &status ) )
2919 goto exit;
2920 TEST_EQUAL( status, PSA_SUCCESS );
2921#endif
2922
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002923exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002924 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002925}
2926/* END_CASE */
2927
2928/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002929void cipher_bad_order( )
2930{
2931 psa_key_handle_t handle = 0;
2932 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2933 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002934 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002935 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2936 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2937 const uint8_t key[] = {
2938 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2939 0xaa, 0xaa, 0xaa, 0xaa };
2940 const uint8_t text[] = {
2941 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2942 0xbb, 0xbb, 0xbb, 0xbb };
2943 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2944 size_t length = 0;
2945
2946 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002947 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2948 psa_set_key_algorithm( &attributes, alg );
2949 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002950 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002951
2952
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002953 /* Call encrypt setup twice in a row. */
2954 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2955 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2956 PSA_ERROR_BAD_STATE );
2957 PSA_ASSERT( psa_cipher_abort( &operation ) );
2958
2959 /* Call decrypt setup twice in a row. */
2960 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2961 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2962 PSA_ERROR_BAD_STATE );
2963 PSA_ASSERT( psa_cipher_abort( &operation ) );
2964
Jaeden Ameroab439972019-02-15 14:12:05 +00002965 /* Generate an IV without calling setup beforehand. */
2966 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2967 buffer, sizeof( buffer ),
2968 &length ),
2969 PSA_ERROR_BAD_STATE );
2970 PSA_ASSERT( psa_cipher_abort( &operation ) );
2971
2972 /* Generate an IV twice in a row. */
2973 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2974 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2975 buffer, sizeof( buffer ),
2976 &length ) );
2977 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2978 buffer, sizeof( buffer ),
2979 &length ),
2980 PSA_ERROR_BAD_STATE );
2981 PSA_ASSERT( psa_cipher_abort( &operation ) );
2982
2983 /* Generate an IV after it's already set. */
2984 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2985 PSA_ASSERT( psa_cipher_set_iv( &operation,
2986 iv, sizeof( iv ) ) );
2987 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2988 buffer, sizeof( buffer ),
2989 &length ),
2990 PSA_ERROR_BAD_STATE );
2991 PSA_ASSERT( psa_cipher_abort( &operation ) );
2992
2993 /* Set an IV without calling setup beforehand. */
2994 TEST_EQUAL( psa_cipher_set_iv( &operation,
2995 iv, sizeof( iv ) ),
2996 PSA_ERROR_BAD_STATE );
2997 PSA_ASSERT( psa_cipher_abort( &operation ) );
2998
2999 /* Set an IV after it's already set. */
3000 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3001 PSA_ASSERT( psa_cipher_set_iv( &operation,
3002 iv, sizeof( iv ) ) );
3003 TEST_EQUAL( psa_cipher_set_iv( &operation,
3004 iv, sizeof( iv ) ),
3005 PSA_ERROR_BAD_STATE );
3006 PSA_ASSERT( psa_cipher_abort( &operation ) );
3007
3008 /* Set an IV after it's already generated. */
3009 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3010 PSA_ASSERT( psa_cipher_generate_iv( &operation,
3011 buffer, sizeof( buffer ),
3012 &length ) );
3013 TEST_EQUAL( psa_cipher_set_iv( &operation,
3014 iv, sizeof( iv ) ),
3015 PSA_ERROR_BAD_STATE );
3016 PSA_ASSERT( psa_cipher_abort( &operation ) );
3017
3018 /* Call update without calling setup beforehand. */
3019 TEST_EQUAL( psa_cipher_update( &operation,
3020 text, sizeof( text ),
3021 buffer, sizeof( buffer ),
3022 &length ),
3023 PSA_ERROR_BAD_STATE );
3024 PSA_ASSERT( psa_cipher_abort( &operation ) );
3025
3026 /* Call update without an IV where an IV is required. */
3027 TEST_EQUAL( psa_cipher_update( &operation,
3028 text, sizeof( text ),
3029 buffer, sizeof( buffer ),
3030 &length ),
3031 PSA_ERROR_BAD_STATE );
3032 PSA_ASSERT( psa_cipher_abort( &operation ) );
3033
3034 /* Call update after finish. */
3035 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3036 PSA_ASSERT( psa_cipher_set_iv( &operation,
3037 iv, sizeof( iv ) ) );
3038 PSA_ASSERT( psa_cipher_finish( &operation,
3039 buffer, sizeof( buffer ), &length ) );
3040 TEST_EQUAL( psa_cipher_update( &operation,
3041 text, sizeof( text ),
3042 buffer, sizeof( buffer ),
3043 &length ),
3044 PSA_ERROR_BAD_STATE );
3045 PSA_ASSERT( psa_cipher_abort( &operation ) );
3046
3047 /* Call finish without calling setup beforehand. */
3048 TEST_EQUAL( psa_cipher_finish( &operation,
3049 buffer, sizeof( buffer ), &length ),
3050 PSA_ERROR_BAD_STATE );
3051 PSA_ASSERT( psa_cipher_abort( &operation ) );
3052
3053 /* Call finish without an IV where an IV is required. */
3054 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3055 /* Not calling update means we are encrypting an empty buffer, which is OK
3056 * for cipher modes with padding. */
3057 TEST_EQUAL( psa_cipher_finish( &operation,
3058 buffer, sizeof( buffer ), &length ),
3059 PSA_ERROR_BAD_STATE );
3060 PSA_ASSERT( psa_cipher_abort( &operation ) );
3061
3062 /* Call finish twice in a row. */
3063 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3064 PSA_ASSERT( psa_cipher_set_iv( &operation,
3065 iv, sizeof( iv ) ) );
3066 PSA_ASSERT( psa_cipher_finish( &operation,
3067 buffer, sizeof( buffer ), &length ) );
3068 TEST_EQUAL( psa_cipher_finish( &operation,
3069 buffer, sizeof( buffer ), &length ),
3070 PSA_ERROR_BAD_STATE );
3071 PSA_ASSERT( psa_cipher_abort( &operation ) );
3072
Gilles Peskine76b29a72019-05-28 14:08:50 +02003073 PSA_ASSERT( psa_destroy_key( handle ) );
3074
Jaeden Ameroab439972019-02-15 14:12:05 +00003075exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003076 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003077}
3078/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003079
Gilles Peskine50e586b2018-06-08 14:28:46 +02003080/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003081void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003082 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003083 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003084 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003085{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003086 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003087 psa_status_t status;
3088 psa_key_type_t key_type = key_type_arg;
3089 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003090 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003091 unsigned char *output = NULL;
3092 size_t output_buffer_size = 0;
3093 size_t function_output_length = 0;
3094 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003095 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003096 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003097
Gilles Peskine8817f612018-12-18 00:18:46 +01003098 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003099
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003100 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3101 psa_set_key_algorithm( &attributes, alg );
3102 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003103
Gilles Peskine73676cb2019-05-15 20:15:10 +02003104 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003105
Gilles Peskine8817f612018-12-18 00:18:46 +01003106 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3107 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003108
Gilles Peskine423005e2019-05-06 15:22:57 +02003109 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003110 output_buffer_size = ( (size_t) input->len +
3111 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003112 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003113
Gilles Peskine8817f612018-12-18 00:18:46 +01003114 PSA_ASSERT( psa_cipher_update( &operation,
3115 input->x, input->len,
3116 output, output_buffer_size,
3117 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003118 total_output_length += function_output_length;
3119 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003120 output + total_output_length,
3121 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003122 &function_output_length );
3123 total_output_length += function_output_length;
3124
Gilles Peskinefe11b722018-12-18 00:24:04 +01003125 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003126 if( expected_status == PSA_SUCCESS )
3127 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003128 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003129 ASSERT_COMPARE( expected_output->x, expected_output->len,
3130 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003131 }
3132
3133exit:
3134 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003135 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003136 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003137}
3138/* END_CASE */
3139
3140/* BEGIN_CASE */
3141void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003142 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003143 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003144 int first_part_size_arg,
3145 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003146 data_t *expected_output )
3147{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003148 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003149 psa_key_type_t key_type = key_type_arg;
3150 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003151 size_t first_part_size = first_part_size_arg;
3152 size_t output1_length = output1_length_arg;
3153 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003154 unsigned char *output = NULL;
3155 size_t output_buffer_size = 0;
3156 size_t function_output_length = 0;
3157 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003158 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003159 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003160
Gilles Peskine8817f612018-12-18 00:18:46 +01003161 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003162
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003163 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3164 psa_set_key_algorithm( &attributes, alg );
3165 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003166
Gilles Peskine73676cb2019-05-15 20:15:10 +02003167 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003168
Gilles Peskine8817f612018-12-18 00:18:46 +01003169 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3170 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003171
Gilles Peskine423005e2019-05-06 15:22:57 +02003172 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003173 output_buffer_size = ( (size_t) input->len +
3174 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003175 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003176
Gilles Peskinee0866522019-02-19 19:44:00 +01003177 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003178 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3179 output, output_buffer_size,
3180 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003181 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003182 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003183 PSA_ASSERT( psa_cipher_update( &operation,
3184 input->x + first_part_size,
3185 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003186 output + total_output_length,
3187 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003188 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003189 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003190 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003191 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003192 output + total_output_length,
3193 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003194 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003195 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003196 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003197
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003198 ASSERT_COMPARE( expected_output->x, expected_output->len,
3199 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003200
3201exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003202 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003203 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003204 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003205}
3206/* END_CASE */
3207
3208/* BEGIN_CASE */
3209void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003210 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003211 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003212 int first_part_size_arg,
3213 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003214 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003215{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003216 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003217
3218 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;
3221 size_t output1_length = output1_length_arg;
3222 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003223 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003224 size_t output_buffer_size = 0;
3225 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003226 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003227 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003228 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003229
Gilles Peskine8817f612018-12-18 00:18:46 +01003230 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003231
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003232 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3233 psa_set_key_algorithm( &attributes, alg );
3234 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003235
Gilles Peskine73676cb2019-05-15 20:15:10 +02003236 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003237
Gilles Peskine8817f612018-12-18 00:18:46 +01003238 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3239 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003240
Gilles Peskine423005e2019-05-06 15:22:57 +02003241 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003242
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003243 output_buffer_size = ( (size_t) input->len +
3244 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003245 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003246
Gilles Peskinee0866522019-02-19 19:44:00 +01003247 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003248 PSA_ASSERT( psa_cipher_update( &operation,
3249 input->x, first_part_size,
3250 output, output_buffer_size,
3251 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003252 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003253 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003254 PSA_ASSERT( psa_cipher_update( &operation,
3255 input->x + first_part_size,
3256 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003257 output + total_output_length,
3258 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003259 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003260 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003261 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003262 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003263 output + total_output_length,
3264 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003265 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003266 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003267 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003268
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003269 ASSERT_COMPARE( expected_output->x, expected_output->len,
3270 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003271
3272exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003273 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003274 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003275 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003276}
3277/* END_CASE */
3278
Gilles Peskine50e586b2018-06-08 14:28:46 +02003279/* BEGIN_CASE */
3280void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003281 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003282 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003283 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003284{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003285 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003286 psa_status_t status;
3287 psa_key_type_t key_type = key_type_arg;
3288 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003289 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003290 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003291 size_t output_buffer_size = 0;
3292 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003293 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003294 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003295 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003296
Gilles Peskine8817f612018-12-18 00:18:46 +01003297 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003298
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003299 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3300 psa_set_key_algorithm( &attributes, alg );
3301 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003302
Gilles Peskine73676cb2019-05-15 20:15:10 +02003303 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003304
Gilles Peskine8817f612018-12-18 00:18:46 +01003305 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3306 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003307
Gilles Peskine423005e2019-05-06 15:22:57 +02003308 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003309
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003310 output_buffer_size = ( (size_t) input->len +
3311 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003312 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003313
Gilles Peskine8817f612018-12-18 00:18:46 +01003314 PSA_ASSERT( psa_cipher_update( &operation,
3315 input->x, input->len,
3316 output, output_buffer_size,
3317 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003318 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003319 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003320 output + total_output_length,
3321 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003322 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003323 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003324 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003325
3326 if( expected_status == PSA_SUCCESS )
3327 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003328 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003329 ASSERT_COMPARE( expected_output->x, expected_output->len,
3330 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003331 }
3332
Gilles Peskine50e586b2018-06-08 14:28:46 +02003333exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003334 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003335 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003336 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003337}
3338/* END_CASE */
3339
Gilles Peskine50e586b2018-06-08 14:28:46 +02003340/* BEGIN_CASE */
3341void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003342 data_t *key,
3343 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003344{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003345 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003346 psa_key_type_t key_type = key_type_arg;
3347 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003348 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003349 size_t iv_size = 16;
3350 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003351 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003352 size_t output1_size = 0;
3353 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003354 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003355 size_t output2_size = 0;
3356 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003357 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003358 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3359 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003360 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003361
Gilles Peskine8817f612018-12-18 00:18:46 +01003362 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003363
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003364 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3365 psa_set_key_algorithm( &attributes, alg );
3366 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003367
Gilles Peskine73676cb2019-05-15 20:15:10 +02003368 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003369
Gilles Peskine8817f612018-12-18 00:18:46 +01003370 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3371 handle, alg ) );
3372 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3373 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003374
Gilles Peskine8817f612018-12-18 00:18:46 +01003375 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3376 iv, iv_size,
3377 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003378 output1_size = ( (size_t) input->len +
3379 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003380 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003381
Gilles Peskine8817f612018-12-18 00:18:46 +01003382 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3383 output1, output1_size,
3384 &output1_length ) );
3385 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003386 output1 + output1_length,
3387 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003388 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003389
Gilles Peskine048b7f02018-06-08 14:20:49 +02003390 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003391
Gilles Peskine8817f612018-12-18 00:18:46 +01003392 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003393
3394 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003395 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003396
Gilles Peskine8817f612018-12-18 00:18:46 +01003397 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3398 iv, iv_length ) );
3399 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3400 output2, output2_size,
3401 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003402 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003403 PSA_ASSERT( psa_cipher_finish( &operation2,
3404 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003405 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003406 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003407
Gilles Peskine048b7f02018-06-08 14:20:49 +02003408 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003409
Gilles Peskine8817f612018-12-18 00:18:46 +01003410 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003411
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003412 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003413
3414exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003415 mbedtls_free( output1 );
3416 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003417 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003418 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003419}
3420/* END_CASE */
3421
3422/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003423void cipher_verify_output_multipart( int alg_arg,
3424 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003425 data_t *key,
3426 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003427 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003428{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003429 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003430 psa_key_type_t key_type = key_type_arg;
3431 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003432 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003433 unsigned char iv[16] = {0};
3434 size_t iv_size = 16;
3435 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003436 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003437 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003438 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003439 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003440 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003441 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003442 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003443 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3444 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003445 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003446
Gilles Peskine8817f612018-12-18 00:18:46 +01003447 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003448
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003449 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3450 psa_set_key_algorithm( &attributes, alg );
3451 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003452
Gilles Peskine73676cb2019-05-15 20:15:10 +02003453 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003454
Gilles Peskine8817f612018-12-18 00:18:46 +01003455 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3456 handle, alg ) );
3457 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3458 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003459
Gilles Peskine8817f612018-12-18 00:18:46 +01003460 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3461 iv, iv_size,
3462 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003463 output1_buffer_size = ( (size_t) input->len +
3464 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003465 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003466
Gilles Peskinee0866522019-02-19 19:44:00 +01003467 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003468
Gilles Peskine8817f612018-12-18 00:18:46 +01003469 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3470 output1, output1_buffer_size,
3471 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003472 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003473
Gilles Peskine8817f612018-12-18 00:18:46 +01003474 PSA_ASSERT( psa_cipher_update( &operation1,
3475 input->x + first_part_size,
3476 input->len - first_part_size,
3477 output1, output1_buffer_size,
3478 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003479 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003480
Gilles Peskine8817f612018-12-18 00:18:46 +01003481 PSA_ASSERT( psa_cipher_finish( &operation1,
3482 output1 + output1_length,
3483 output1_buffer_size - output1_length,
3484 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003485 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003486
Gilles Peskine8817f612018-12-18 00:18:46 +01003487 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003488
Gilles Peskine048b7f02018-06-08 14:20:49 +02003489 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003490 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003491
Gilles Peskine8817f612018-12-18 00:18:46 +01003492 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3493 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003494
Gilles Peskine8817f612018-12-18 00:18:46 +01003495 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3496 output2, output2_buffer_size,
3497 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003498 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003499
Gilles Peskine8817f612018-12-18 00:18:46 +01003500 PSA_ASSERT( psa_cipher_update( &operation2,
3501 output1 + first_part_size,
3502 output1_length - first_part_size,
3503 output2, output2_buffer_size,
3504 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003505 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003506
Gilles Peskine8817f612018-12-18 00:18:46 +01003507 PSA_ASSERT( psa_cipher_finish( &operation2,
3508 output2 + output2_length,
3509 output2_buffer_size - output2_length,
3510 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003511 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003512
Gilles Peskine8817f612018-12-18 00:18:46 +01003513 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003514
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003515 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003516
3517exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003518 mbedtls_free( output1 );
3519 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003520 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003521 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003522}
3523/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003524
Gilles Peskine20035e32018-02-03 22:44:14 +01003525/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003526void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003527 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003528 data_t *nonce,
3529 data_t *additional_data,
3530 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003531 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003532{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003533 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003534 psa_key_type_t key_type = key_type_arg;
3535 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003536 unsigned char *output_data = NULL;
3537 size_t output_size = 0;
3538 size_t output_length = 0;
3539 unsigned char *output_data2 = NULL;
3540 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003541 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003542 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003543 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003544
Gilles Peskine4abf7412018-06-18 16:35:34 +02003545 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003546 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3547 * should be exact. */
3548 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3549 TEST_EQUAL( output_size,
3550 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003551 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003552
Gilles Peskine8817f612018-12-18 00:18:46 +01003553 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003554
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003555 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3556 psa_set_key_algorithm( &attributes, alg );
3557 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003558
Gilles Peskine049c7532019-05-15 20:22:09 +02003559 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3560 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003561
Gilles Peskinefe11b722018-12-18 00:24:04 +01003562 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3563 nonce->x, nonce->len,
3564 additional_data->x,
3565 additional_data->len,
3566 input_data->x, input_data->len,
3567 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003568 &output_length ),
3569 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003570
3571 if( PSA_SUCCESS == expected_result )
3572 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003573 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003574
Gilles Peskine003a4a92019-05-14 16:09:40 +02003575 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3576 * should be exact. */
3577 TEST_EQUAL( input_data->len,
3578 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3579
Gilles Peskinefe11b722018-12-18 00:24:04 +01003580 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3581 nonce->x, nonce->len,
3582 additional_data->x,
3583 additional_data->len,
3584 output_data, output_length,
3585 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003586 &output_length2 ),
3587 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003588
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003589 ASSERT_COMPARE( input_data->x, input_data->len,
3590 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003591 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003592
Gilles Peskinea1cac842018-06-11 19:33:02 +02003593exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003594 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003595 mbedtls_free( output_data );
3596 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003597 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003598}
3599/* END_CASE */
3600
3601/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003602void aead_encrypt( int key_type_arg, data_t *key_data,
3603 int alg_arg,
3604 data_t *nonce,
3605 data_t *additional_data,
3606 data_t *input_data,
3607 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003608{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003609 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003610 psa_key_type_t key_type = key_type_arg;
3611 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003612 unsigned char *output_data = NULL;
3613 size_t output_size = 0;
3614 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003615 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003616 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003617
Gilles Peskine4abf7412018-06-18 16:35:34 +02003618 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003619 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3620 * should be exact. */
3621 TEST_EQUAL( output_size,
3622 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003623 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003624
Gilles Peskine8817f612018-12-18 00:18:46 +01003625 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003626
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003627 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3628 psa_set_key_algorithm( &attributes, alg );
3629 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003630
Gilles Peskine049c7532019-05-15 20:22:09 +02003631 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3632 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003633
Gilles Peskine8817f612018-12-18 00:18:46 +01003634 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3635 nonce->x, nonce->len,
3636 additional_data->x, additional_data->len,
3637 input_data->x, input_data->len,
3638 output_data, output_size,
3639 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003640
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003641 ASSERT_COMPARE( expected_result->x, expected_result->len,
3642 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003643
Gilles Peskinea1cac842018-06-11 19:33:02 +02003644exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003645 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003646 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003647 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003648}
3649/* END_CASE */
3650
3651/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003652void aead_decrypt( int key_type_arg, data_t *key_data,
3653 int alg_arg,
3654 data_t *nonce,
3655 data_t *additional_data,
3656 data_t *input_data,
3657 data_t *expected_data,
3658 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003659{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003660 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003661 psa_key_type_t key_type = key_type_arg;
3662 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003663 unsigned char *output_data = NULL;
3664 size_t output_size = 0;
3665 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003666 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003667 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003668 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003669
Gilles Peskine003a4a92019-05-14 16:09:40 +02003670 output_size = input_data->len - tag_length;
3671 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3672 * should be exact. */
3673 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3674 TEST_EQUAL( output_size,
3675 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003676 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003677
Gilles Peskine8817f612018-12-18 00:18:46 +01003678 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003679
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003680 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3681 psa_set_key_algorithm( &attributes, alg );
3682 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003683
Gilles Peskine049c7532019-05-15 20:22:09 +02003684 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3685 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003686
Gilles Peskinefe11b722018-12-18 00:24:04 +01003687 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3688 nonce->x, nonce->len,
3689 additional_data->x,
3690 additional_data->len,
3691 input_data->x, input_data->len,
3692 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003693 &output_length ),
3694 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003695
Gilles Peskine2d277862018-06-18 15:41:12 +02003696 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003697 ASSERT_COMPARE( expected_data->x, expected_data->len,
3698 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003699
Gilles Peskinea1cac842018-06-11 19:33:02 +02003700exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003701 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003702 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003703 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003704}
3705/* END_CASE */
3706
3707/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003708void signature_size( int type_arg,
3709 int bits,
3710 int alg_arg,
3711 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003712{
3713 psa_key_type_t type = type_arg;
3714 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003715 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003716 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003717exit:
3718 ;
3719}
3720/* END_CASE */
3721
3722/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003723void sign_deterministic( int key_type_arg, data_t *key_data,
3724 int alg_arg, data_t *input_data,
3725 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003726{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003727 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003728 psa_key_type_t key_type = key_type_arg;
3729 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003730 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003731 unsigned char *signature = NULL;
3732 size_t signature_size;
3733 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003734 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003735
Gilles Peskine8817f612018-12-18 00:18:46 +01003736 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003737
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003738 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3739 psa_set_key_algorithm( &attributes, alg );
3740 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003741
Gilles Peskine049c7532019-05-15 20:22:09 +02003742 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3743 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003744 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3745 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003746
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003747 /* Allocate a buffer which has the size advertized by the
3748 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003749 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3750 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003751 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003752 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003753 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003754
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003755 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003756 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3757 input_data->x, input_data->len,
3758 signature, signature_size,
3759 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003760 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003761 ASSERT_COMPARE( output_data->x, output_data->len,
3762 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003763
3764exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003765 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003766 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003767 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003768 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003769}
3770/* END_CASE */
3771
3772/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003773void sign_fail( int key_type_arg, data_t *key_data,
3774 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003775 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003776{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003777 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003778 psa_key_type_t key_type = key_type_arg;
3779 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003780 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003781 psa_status_t actual_status;
3782 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003783 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003784 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003785 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003786
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003787 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003788
Gilles Peskine8817f612018-12-18 00:18:46 +01003789 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003790
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003791 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3792 psa_set_key_algorithm( &attributes, alg );
3793 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003794
Gilles Peskine049c7532019-05-15 20:22:09 +02003795 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3796 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003797
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003798 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003799 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003800 signature, signature_size,
3801 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003802 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003803 /* The value of *signature_length is unspecified on error, but
3804 * whatever it is, it should be less than signature_size, so that
3805 * if the caller tries to read *signature_length bytes without
3806 * checking the error code then they don't overflow a buffer. */
3807 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003808
3809exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003810 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003811 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003812 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003813 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003814}
3815/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003816
3817/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003818void sign_verify( int key_type_arg, data_t *key_data,
3819 int alg_arg, data_t *input_data )
3820{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003821 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003822 psa_key_type_t key_type = key_type_arg;
3823 psa_algorithm_t alg = alg_arg;
3824 size_t key_bits;
3825 unsigned char *signature = NULL;
3826 size_t signature_size;
3827 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003828 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003829
Gilles Peskine8817f612018-12-18 00:18:46 +01003830 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003831
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003832 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3833 psa_set_key_algorithm( &attributes, alg );
3834 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003835
Gilles Peskine049c7532019-05-15 20:22:09 +02003836 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3837 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003838 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3839 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003840
3841 /* Allocate a buffer which has the size advertized by the
3842 * library. */
3843 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3844 key_bits, alg );
3845 TEST_ASSERT( signature_size != 0 );
3846 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003847 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003848
3849 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003850 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3851 input_data->x, input_data->len,
3852 signature, signature_size,
3853 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003854 /* Check that the signature length looks sensible. */
3855 TEST_ASSERT( signature_length <= signature_size );
3856 TEST_ASSERT( signature_length > 0 );
3857
3858 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003859 PSA_ASSERT( psa_asymmetric_verify(
3860 handle, alg,
3861 input_data->x, input_data->len,
3862 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003863
3864 if( input_data->len != 0 )
3865 {
3866 /* Flip a bit in the input and verify that the signature is now
3867 * detected as invalid. Flip a bit at the beginning, not at the end,
3868 * because ECDSA may ignore the last few bits of the input. */
3869 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003870 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3871 input_data->x, input_data->len,
3872 signature, signature_length ),
3873 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003874 }
3875
3876exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003877 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003878 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003879 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003880 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003881}
3882/* END_CASE */
3883
3884/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003885void asymmetric_verify( int key_type_arg, data_t *key_data,
3886 int alg_arg, data_t *hash_data,
3887 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003888{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003889 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003890 psa_key_type_t key_type = key_type_arg;
3891 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003892 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003893
Gilles Peskine69c12672018-06-28 00:07:19 +02003894 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3895
Gilles Peskine8817f612018-12-18 00:18:46 +01003896 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003897
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003898 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3899 psa_set_key_algorithm( &attributes, alg );
3900 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003901
Gilles Peskine049c7532019-05-15 20:22:09 +02003902 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3903 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003904
Gilles Peskine8817f612018-12-18 00:18:46 +01003905 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3906 hash_data->x, hash_data->len,
3907 signature_data->x,
3908 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +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 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003912 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003913}
3914/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003915
3916/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003917void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3918 int alg_arg, data_t *hash_data,
3919 data_t *signature_data,
3920 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003921{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003922 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003923 psa_key_type_t key_type = key_type_arg;
3924 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003925 psa_status_t actual_status;
3926 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003927 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003928
Gilles Peskine8817f612018-12-18 00:18:46 +01003929 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003930
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003931 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3932 psa_set_key_algorithm( &attributes, alg );
3933 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003934
Gilles Peskine049c7532019-05-15 20:22:09 +02003935 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3936 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003937
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003938 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003939 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003940 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003941 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003942
Gilles Peskinefe11b722018-12-18 00:24:04 +01003943 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003944
3945exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003946 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003947 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003948 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003949}
3950/* END_CASE */
3951
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003952/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003953void asymmetric_encrypt( int key_type_arg,
3954 data_t *key_data,
3955 int alg_arg,
3956 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003957 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003958 int expected_output_length_arg,
3959 int expected_status_arg )
3960{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003961 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003962 psa_key_type_t key_type = key_type_arg;
3963 psa_algorithm_t alg = alg_arg;
3964 size_t expected_output_length = expected_output_length_arg;
3965 size_t key_bits;
3966 unsigned char *output = NULL;
3967 size_t output_size;
3968 size_t output_length = ~0;
3969 psa_status_t actual_status;
3970 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003971 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003972
Gilles Peskine8817f612018-12-18 00:18:46 +01003973 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003974
Gilles Peskine656896e2018-06-29 19:12:28 +02003975 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003976 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3977 psa_set_key_algorithm( &attributes, alg );
3978 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003979 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3980 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003981
3982 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003983 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3984 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003985 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003986 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003987
3988 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003989 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003990 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003991 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003992 output, output_size,
3993 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003994 TEST_EQUAL( actual_status, expected_status );
3995 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003996
Gilles Peskine68428122018-06-30 18:42:41 +02003997 /* If the label is empty, the test framework puts a non-null pointer
3998 * in label->x. Test that a null pointer works as well. */
3999 if( label->len == 0 )
4000 {
4001 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004002 if( output_size != 0 )
4003 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004004 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004005 input_data->x, input_data->len,
4006 NULL, label->len,
4007 output, output_size,
4008 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004009 TEST_EQUAL( actual_status, expected_status );
4010 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004011 }
4012
Gilles Peskine656896e2018-06-29 19:12:28 +02004013exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004014 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004015 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02004016 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004017 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02004018}
4019/* END_CASE */
4020
4021/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004022void asymmetric_encrypt_decrypt( int key_type_arg,
4023 data_t *key_data,
4024 int alg_arg,
4025 data_t *input_data,
4026 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004027{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004028 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004029 psa_key_type_t key_type = key_type_arg;
4030 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004031 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004032 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004033 size_t output_size;
4034 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03004035 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004036 size_t output2_size;
4037 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004038 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004039
Gilles Peskine8817f612018-12-18 00:18:46 +01004040 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004041
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004042 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
4043 psa_set_key_algorithm( &attributes, alg );
4044 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004045
Gilles Peskine049c7532019-05-15 20:22:09 +02004046 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4047 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004048
4049 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004050 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4051 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004052 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004053 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004054 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004055 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004056
Gilles Peskineeebd7382018-06-08 18:11:54 +02004057 /* We test encryption by checking that encrypt-then-decrypt gives back
4058 * the original plaintext because of the non-optional random
4059 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004060 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
4061 input_data->x, input_data->len,
4062 label->x, label->len,
4063 output, output_size,
4064 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004065 /* We don't know what ciphertext length to expect, but check that
4066 * it looks sensible. */
4067 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03004068
Gilles Peskine8817f612018-12-18 00:18:46 +01004069 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4070 output, output_length,
4071 label->x, label->len,
4072 output2, output2_size,
4073 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004074 ASSERT_COMPARE( input_data->x, input_data->len,
4075 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004076
4077exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004078 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004079 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004080 mbedtls_free( output );
4081 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004082 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004083}
4084/* END_CASE */
4085
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004086/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004087void asymmetric_decrypt( int key_type_arg,
4088 data_t *key_data,
4089 int alg_arg,
4090 data_t *input_data,
4091 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02004092 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004093{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004094 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004095 psa_key_type_t key_type = key_type_arg;
4096 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004097 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03004098 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004099 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004100 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004101
Jaeden Amero412654a2019-02-06 12:57:46 +00004102 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004103 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004104
Gilles Peskine8817f612018-12-18 00:18:46 +01004105 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004106
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004107 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4108 psa_set_key_algorithm( &attributes, alg );
4109 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004110
Gilles Peskine049c7532019-05-15 20:22:09 +02004111 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4112 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004113
Gilles Peskine8817f612018-12-18 00:18:46 +01004114 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4115 input_data->x, input_data->len,
4116 label->x, label->len,
4117 output,
4118 output_size,
4119 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004120 ASSERT_COMPARE( expected_data->x, expected_data->len,
4121 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004122
Gilles Peskine68428122018-06-30 18:42:41 +02004123 /* If the label is empty, the test framework puts a non-null pointer
4124 * in label->x. Test that a null pointer works as well. */
4125 if( label->len == 0 )
4126 {
4127 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004128 if( output_size != 0 )
4129 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004130 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4131 input_data->x, input_data->len,
4132 NULL, label->len,
4133 output,
4134 output_size,
4135 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004136 ASSERT_COMPARE( expected_data->x, expected_data->len,
4137 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004138 }
4139
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004140exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004141 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004142 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004143 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004144 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004145}
4146/* END_CASE */
4147
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004148/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004149void asymmetric_decrypt_fail( int key_type_arg,
4150 data_t *key_data,
4151 int alg_arg,
4152 data_t *input_data,
4153 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00004154 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02004155 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004156{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004157 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004158 psa_key_type_t key_type = key_type_arg;
4159 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004160 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004161 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004162 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004163 psa_status_t actual_status;
4164 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004165 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004166
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004167 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004168
Gilles Peskine8817f612018-12-18 00:18:46 +01004169 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004170
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004171 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4172 psa_set_key_algorithm( &attributes, alg );
4173 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004174
Gilles Peskine049c7532019-05-15 20:22:09 +02004175 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4176 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004177
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004178 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004179 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004180 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004181 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004182 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004183 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004184 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004185
Gilles Peskine68428122018-06-30 18:42:41 +02004186 /* If the label is empty, the test framework puts a non-null pointer
4187 * in label->x. Test that a null pointer works as well. */
4188 if( label->len == 0 )
4189 {
4190 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004191 if( output_size != 0 )
4192 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004193 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004194 input_data->x, input_data->len,
4195 NULL, label->len,
4196 output, output_size,
4197 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004198 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004199 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004200 }
4201
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004202exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004203 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004204 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004205 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004206 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004207}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004208/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004209
4210/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004211void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004212{
4213 /* Test each valid way of initializing the object, except for `= {0}`, as
4214 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4215 * though it's OK by the C standard. We could test for this, but we'd need
4216 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004217 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004218 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4219 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4220 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004221
4222 memset( &zero, 0, sizeof( zero ) );
4223
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004224 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004225 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004226 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004227 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004228 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004229 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004230 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004231
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004232 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004233 PSA_ASSERT( psa_key_derivation_abort(&func) );
4234 PSA_ASSERT( psa_key_derivation_abort(&init) );
4235 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004236}
4237/* END_CASE */
4238
Janos Follath16de4a42019-06-13 16:32:24 +01004239/* BEGIN_CASE */
4240void derive_setup( int alg_arg, int expected_status_arg )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004241{
Gilles Peskineea0fb492018-07-12 17:17:20 +02004242 psa_algorithm_t alg = alg_arg;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004243 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004244 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004245
Gilles Peskine8817f612018-12-18 00:18:46 +01004246 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004247
Janos Follath16de4a42019-06-13 16:32:24 +01004248 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004249 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004250
4251exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004252 psa_key_derivation_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004253 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004254}
4255/* END_CASE */
4256
Janos Follathaf3c2a02019-06-12 12:34:34 +01004257/* BEGIN_CASE */
Janos Follatha27c9272019-06-14 09:59:36 +01004258void derive_set_capacity( int alg_arg, int capacity_arg,
4259 int expected_status_arg )
4260{
4261 psa_algorithm_t alg = alg_arg;
4262 size_t capacity = capacity_arg;
4263 psa_status_t expected_status = expected_status_arg;
4264 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4265
4266 PSA_ASSERT( psa_crypto_init( ) );
4267
4268 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4269
4270 TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
4271 expected_status );
4272
4273exit:
4274 psa_key_derivation_abort( &operation );
4275 PSA_DONE( );
4276}
4277/* END_CASE */
4278
4279/* BEGIN_CASE */
Janos Follathaf3c2a02019-06-12 12:34:34 +01004280void derive_input( int alg_arg,
4281 int key_type_arg,
4282 int step1_arg, data_t *input1,
4283 int step2_arg, data_t *input2,
4284 int step3_arg, data_t *input3,
4285 int expected_status_arg1,
4286 int expected_status_arg2,
4287 int expected_status_arg3 )
4288{
4289 psa_algorithm_t alg = alg_arg;
4290 size_t key_type = key_type_arg;
4291 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4292 psa_status_t expected_statuses[] = {expected_status_arg1,
4293 expected_status_arg2,
4294 expected_status_arg3};
4295 data_t *inputs[] = {input1, input2, input3};
4296 psa_key_handle_t handles[] = {0, 0, 0};
4297 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4298 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4299 size_t i;
4300
4301 PSA_ASSERT( psa_crypto_init( ) );
4302
4303 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4304 psa_set_key_algorithm( &attributes, alg );
4305 psa_set_key_type( &attributes, key_type );
4306
4307 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4308
4309 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
4310 {
4311 switch( steps[i] )
4312 {
4313 case PSA_KEY_DERIVATION_INPUT_SECRET:
4314 PSA_ASSERT( psa_import_key( &attributes,
4315 inputs[i]->x, inputs[i]->len,
4316 &handles[i] ) );
4317 TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
4318 handles[i] ),
4319 expected_statuses[i] );
4320 break;
4321 default:
4322 TEST_EQUAL( psa_key_derivation_input_bytes(
4323 &operation, steps[i],
4324 inputs[i]->x, inputs[i]->len ),
4325 expected_statuses[i] );
4326 break;
4327 }
4328 }
4329
4330exit:
4331 psa_key_derivation_abort( &operation );
4332 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4333 psa_destroy_key( handles[i] );
4334 PSA_DONE( );
4335}
4336/* END_CASE */
4337
Janos Follathd958bb72019-07-03 15:02:16 +01004338/* BEGIN_CASE */
4339void test_derive_invalid_key_derivation_state( int alg_arg )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004340{
Janos Follathd958bb72019-07-03 15:02:16 +01004341 psa_algorithm_t alg = alg_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004342 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004343 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004344 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathd958bb72019-07-03 15:02:16 +01004345 unsigned char input1[] = "Input 1";
4346 size_t input1_length = sizeof( input1 );
4347 unsigned char input2[] = "Input 2";
4348 size_t input2_length = sizeof( input2 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004349 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004350 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004351 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4352 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4353 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004354 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004355
Gilles Peskine8817f612018-12-18 00:18:46 +01004356 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004357
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004358 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4359 psa_set_key_algorithm( &attributes, alg );
4360 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004361
Gilles Peskine73676cb2019-05-15 20:15:10 +02004362 PSA_ASSERT( psa_import_key( &attributes,
4363 key_data, sizeof( key_data ),
4364 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004365
4366 /* valid key derivation */
Janos Follathd958bb72019-07-03 15:02:16 +01004367 if( !setup_key_derivation_wrap( &operation, handle, alg,
4368 input1, input1_length,
4369 input2, input2_length,
4370 capacity ) )
4371 goto exit;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004372
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004373 /* state of operation shouldn't allow additional generation */
Janos Follathd958bb72019-07-03 15:02:16 +01004374 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004375 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004376
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004377 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004378
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004379 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004380 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004381
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004382exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004383 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004384 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004385 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004386}
4387/* END_CASE */
4388
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004389/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004390void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004391{
4392 uint8_t output_buffer[16];
4393 size_t buffer_size = 16;
4394 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004395 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004396
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004397 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4398 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004399 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004400
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004401 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004402 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004403
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004404 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004405
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004406 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4407 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004408 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004409
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004410 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004411 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004412
4413exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004414 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004415}
4416/* END_CASE */
4417
4418/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004419void derive_output( int alg_arg,
Gilles Peskine1468da72019-05-29 17:35:49 +02004420 int step1_arg, data_t *input1,
4421 int step2_arg, data_t *input2,
4422 int step3_arg, data_t *input3,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004423 int requested_capacity_arg,
4424 data_t *expected_output1,
4425 data_t *expected_output2 )
4426{
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004427 psa_algorithm_t alg = alg_arg;
Gilles Peskine1468da72019-05-29 17:35:49 +02004428 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4429 data_t *inputs[] = {input1, input2, input3};
4430 psa_key_handle_t handles[] = {0, 0, 0};
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004431 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004432 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004433 uint8_t *expected_outputs[2] =
4434 {expected_output1->x, expected_output2->x};
4435 size_t output_sizes[2] =
4436 {expected_output1->len, expected_output2->len};
4437 size_t output_buffer_size = 0;
4438 uint8_t *output_buffer = NULL;
4439 size_t expected_capacity;
4440 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004441 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004442 psa_status_t status;
Gilles Peskine1468da72019-05-29 17:35:49 +02004443 size_t i;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004444
4445 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4446 {
4447 if( output_sizes[i] > output_buffer_size )
4448 output_buffer_size = output_sizes[i];
4449 if( output_sizes[i] == 0 )
4450 expected_outputs[i] = NULL;
4451 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004452 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004453 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004454
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004455 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4456 psa_set_key_algorithm( &attributes, alg );
4457 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004458
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004459 /* Extraction phase. */
Gilles Peskine1468da72019-05-29 17:35:49 +02004460 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4461 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4462 requested_capacity ) );
4463 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004464 {
Gilles Peskine1468da72019-05-29 17:35:49 +02004465 switch( steps[i] )
4466 {
4467 case 0:
4468 break;
4469 case PSA_KEY_DERIVATION_INPUT_SECRET:
4470 PSA_ASSERT( psa_import_key( &attributes,
4471 inputs[i]->x, inputs[i]->len,
4472 &handles[i] ) );
4473 PSA_ASSERT( psa_key_derivation_input_key(
4474 &operation, steps[i],
4475 handles[i] ) );
4476 break;
4477 default:
4478 PSA_ASSERT( psa_key_derivation_input_bytes(
4479 &operation, steps[i],
4480 inputs[i]->x, inputs[i]->len ) );
4481 break;
4482 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004483 }
Gilles Peskine1468da72019-05-29 17:35:49 +02004484
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004485 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004486 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004487 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004488 expected_capacity = requested_capacity;
4489
4490 /* Expansion phase. */
4491 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4492 {
4493 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004494 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004495 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004496 if( expected_capacity == 0 && output_sizes[i] == 0 )
4497 {
4498 /* Reading 0 bytes when 0 bytes are available can go either way. */
4499 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004500 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004501 continue;
4502 }
4503 else if( expected_capacity == 0 ||
4504 output_sizes[i] > expected_capacity )
4505 {
4506 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004507 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004508 expected_capacity = 0;
4509 continue;
4510 }
4511 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004512 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004513 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004514 ASSERT_COMPARE( output_buffer, output_sizes[i],
4515 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004516 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004517 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004518 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004519 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004520 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004521 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004522 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004523
4524exit:
4525 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004526 psa_key_derivation_abort( &operation );
Gilles Peskine1468da72019-05-29 17:35:49 +02004527 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4528 psa_destroy_key( handles[i] );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004529 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004530}
4531/* END_CASE */
4532
4533/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004534void derive_full( int alg_arg,
4535 data_t *key_data,
Janos Follath47f27ed2019-06-25 13:24:52 +01004536 data_t *input1,
4537 data_t *input2,
Gilles Peskined54931c2018-07-17 21:06:59 +02004538 int requested_capacity_arg )
4539{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004540 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004541 psa_algorithm_t alg = alg_arg;
4542 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004543 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004544 unsigned char output_buffer[16];
4545 size_t expected_capacity = requested_capacity;
4546 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004547 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004548
Gilles Peskine8817f612018-12-18 00:18:46 +01004549 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004550
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004551 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4552 psa_set_key_algorithm( &attributes, alg );
4553 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004554
Gilles Peskine049c7532019-05-15 20:22:09 +02004555 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4556 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004557
Janos Follathf2815ea2019-07-03 12:41:36 +01004558 if( !setup_key_derivation_wrap( &operation, handle, alg,
4559 input1->x, input1->len,
4560 input2->x, input2->len,
4561 requested_capacity ) )
4562 goto exit;
Janos Follath47f27ed2019-06-25 13:24:52 +01004563
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004564 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004565 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004566 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004567
4568 /* Expansion phase. */
4569 while( current_capacity > 0 )
4570 {
4571 size_t read_size = sizeof( output_buffer );
4572 if( read_size > current_capacity )
4573 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004574 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004575 output_buffer,
4576 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004577 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004578 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004579 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004580 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004581 }
4582
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004583 /* Check that the operation refuses to go over capacity. */
4584 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004585 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004586
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004587 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004588
4589exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004590 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004591 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004592 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004593}
4594/* END_CASE */
4595
Janos Follathe60c9052019-07-03 13:51:30 +01004596/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004597void derive_key_exercise( int alg_arg,
4598 data_t *key_data,
Janos Follathe60c9052019-07-03 13:51:30 +01004599 data_t *input1,
4600 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004601 int derived_type_arg,
4602 int derived_bits_arg,
4603 int derived_usage_arg,
4604 int derived_alg_arg )
4605{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004606 psa_key_handle_t base_handle = 0;
4607 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004608 psa_algorithm_t alg = alg_arg;
4609 psa_key_type_t derived_type = derived_type_arg;
4610 size_t derived_bits = derived_bits_arg;
4611 psa_key_usage_t derived_usage = derived_usage_arg;
4612 psa_algorithm_t derived_alg = derived_alg_arg;
4613 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004614 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004615 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004616 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004617
Gilles Peskine8817f612018-12-18 00:18:46 +01004618 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004619
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004620 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4621 psa_set_key_algorithm( &attributes, alg );
4622 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004623 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4624 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004625
4626 /* Derive a key. */
Janos Follathe60c9052019-07-03 13:51:30 +01004627 if ( setup_key_derivation_wrap( &operation, base_handle, alg,
4628 input1->x, input1->len,
4629 input2->x, input2->len, capacity ) )
4630 goto exit;
4631
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004632 psa_set_key_usage_flags( &attributes, derived_usage );
4633 psa_set_key_algorithm( &attributes, derived_alg );
4634 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004635 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004636 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004637 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004638
4639 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004640 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4641 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4642 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004643
4644 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004645 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004646 goto exit;
4647
4648exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004649 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004650 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004651 psa_destroy_key( base_handle );
4652 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004653 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004654}
4655/* END_CASE */
4656
Janos Follath42fd8882019-07-03 14:17:09 +01004657/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004658void derive_key_export( int alg_arg,
4659 data_t *key_data,
Janos Follath42fd8882019-07-03 14:17:09 +01004660 data_t *input1,
4661 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004662 int bytes1_arg,
4663 int bytes2_arg )
4664{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004665 psa_key_handle_t base_handle = 0;
4666 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004667 psa_algorithm_t alg = alg_arg;
4668 size_t bytes1 = bytes1_arg;
4669 size_t bytes2 = bytes2_arg;
4670 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004671 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004672 uint8_t *output_buffer = NULL;
4673 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004674 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4675 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004676 size_t length;
4677
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004678 ASSERT_ALLOC( output_buffer, capacity );
4679 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004680 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004681
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004682 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4683 psa_set_key_algorithm( &base_attributes, alg );
4684 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004685 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4686 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004687
4688 /* Derive some material and output it. */
Janos Follath42fd8882019-07-03 14:17:09 +01004689 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4690 input1->x, input1->len,
4691 input2->x, input2->len, capacity ) )
4692 goto exit;
4693
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004694 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004695 output_buffer,
4696 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004697 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004698
4699 /* Derive the same output again, but this time store it in key objects. */
Janos Follath42fd8882019-07-03 14:17:09 +01004700 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4701 input1->x, input1->len,
4702 input2->x, input2->len, capacity ) )
4703 goto exit;
4704
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004705 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4706 psa_set_key_algorithm( &derived_attributes, 0 );
4707 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004708 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004709 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004710 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004711 PSA_ASSERT( psa_export_key( derived_handle,
4712 export_buffer, bytes1,
4713 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004714 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004715 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004716 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004717 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004718 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004719 PSA_ASSERT( psa_export_key( derived_handle,
4720 export_buffer + bytes1, bytes2,
4721 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004722 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004723
4724 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004725 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4726 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004727
4728exit:
4729 mbedtls_free( output_buffer );
4730 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004731 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004732 psa_destroy_key( base_handle );
4733 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004734 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004735}
4736/* END_CASE */
4737
4738/* BEGIN_CASE */
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004739void derive_key( int alg_arg,
4740 data_t *key_data, data_t *input1, data_t *input2,
4741 int type_arg, int bits_arg,
4742 int expected_status_arg )
Gilles Peskinec744d992019-07-30 17:26:54 +02004743{
4744 psa_key_handle_t base_handle = 0;
4745 psa_key_handle_t derived_handle = 0;
4746 psa_algorithm_t alg = alg_arg;
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004747 psa_key_type_t type = type_arg;
Gilles Peskinec744d992019-07-30 17:26:54 +02004748 size_t bits = bits_arg;
4749 psa_status_t expected_status = expected_status_arg;
4750 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4751 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4752 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
4753
4754 PSA_ASSERT( psa_crypto_init( ) );
4755
4756 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4757 psa_set_key_algorithm( &base_attributes, alg );
4758 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4759 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4760 &base_handle ) );
4761
4762 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4763 input1->x, input1->len,
4764 input2->x, input2->len, SIZE_MAX ) )
4765 goto exit;
4766
4767 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4768 psa_set_key_algorithm( &derived_attributes, 0 );
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004769 psa_set_key_type( &derived_attributes, type );
Gilles Peskinec744d992019-07-30 17:26:54 +02004770 psa_set_key_bits( &derived_attributes, bits );
4771 TEST_EQUAL( psa_key_derivation_output_key( &derived_attributes, &operation,
4772 &derived_handle ),
4773 expected_status );
4774
4775exit:
4776 psa_key_derivation_abort( &operation );
4777 psa_destroy_key( base_handle );
4778 psa_destroy_key( derived_handle );
4779 PSA_DONE( );
4780}
4781/* END_CASE */
4782
4783/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004784void key_agreement_setup( int alg_arg,
4785 int our_key_type_arg, data_t *our_key_data,
4786 data_t *peer_key_data,
4787 int expected_status_arg )
4788{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004789 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004790 psa_algorithm_t alg = alg_arg;
4791 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004792 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004793 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004794 psa_status_t expected_status = expected_status_arg;
4795 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004796
Gilles Peskine8817f612018-12-18 00:18:46 +01004797 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004798
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004799 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4800 psa_set_key_algorithm( &attributes, alg );
4801 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004802 PSA_ASSERT( psa_import_key( &attributes,
4803 our_key_data->x, our_key_data->len,
4804 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004805
Gilles Peskine77f40d82019-04-11 21:27:06 +02004806 /* The tests currently include inputs that should fail at either step.
4807 * Test cases that fail at the setup step should be changed to call
4808 * key_derivation_setup instead, and this function should be renamed
4809 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004810 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004811 if( status == PSA_SUCCESS )
4812 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004813 TEST_EQUAL( psa_key_derivation_key_agreement(
4814 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4815 our_key,
4816 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004817 expected_status );
4818 }
4819 else
4820 {
4821 TEST_ASSERT( status == expected_status );
4822 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004823
4824exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004825 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004826 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004827 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004828}
4829/* END_CASE */
4830
4831/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004832void raw_key_agreement( int alg_arg,
4833 int our_key_type_arg, data_t *our_key_data,
4834 data_t *peer_key_data,
4835 data_t *expected_output )
4836{
4837 psa_key_handle_t our_key = 0;
4838 psa_algorithm_t alg = alg_arg;
4839 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004840 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004841 unsigned char *output = NULL;
4842 size_t output_length = ~0;
4843
4844 ASSERT_ALLOC( output, expected_output->len );
4845 PSA_ASSERT( psa_crypto_init( ) );
4846
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004847 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4848 psa_set_key_algorithm( &attributes, alg );
4849 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004850 PSA_ASSERT( psa_import_key( &attributes,
4851 our_key_data->x, our_key_data->len,
4852 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004853
Gilles Peskinebe697d82019-05-16 18:00:41 +02004854 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4855 peer_key_data->x, peer_key_data->len,
4856 output, expected_output->len,
4857 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004858 ASSERT_COMPARE( output, output_length,
4859 expected_output->x, expected_output->len );
4860
4861exit:
4862 mbedtls_free( output );
4863 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004864 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004865}
4866/* END_CASE */
4867
4868/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004869void key_agreement_capacity( int alg_arg,
4870 int our_key_type_arg, data_t *our_key_data,
4871 data_t *peer_key_data,
4872 int expected_capacity_arg )
4873{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004874 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004875 psa_algorithm_t alg = alg_arg;
4876 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004877 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004878 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004879 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004880 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004881
Gilles Peskine8817f612018-12-18 00:18:46 +01004882 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004883
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004884 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4885 psa_set_key_algorithm( &attributes, alg );
4886 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004887 PSA_ASSERT( psa_import_key( &attributes,
4888 our_key_data->x, our_key_data->len,
4889 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004890
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004891 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004892 PSA_ASSERT( psa_key_derivation_key_agreement(
4893 &operation,
4894 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4895 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004896 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4897 {
4898 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004899 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004900 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004901 NULL, 0 ) );
4902 }
Gilles Peskine59685592018-09-18 12:11:34 +02004903
Gilles Peskinebf491972018-10-25 22:36:12 +02004904 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004905 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004906 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004907 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004908
Gilles Peskinebf491972018-10-25 22:36:12 +02004909 /* Test the actual capacity by reading the output. */
4910 while( actual_capacity > sizeof( output ) )
4911 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004912 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004913 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004914 actual_capacity -= sizeof( output );
4915 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004916 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004917 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004918 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004919 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004920
Gilles Peskine59685592018-09-18 12:11:34 +02004921exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004922 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004923 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004924 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004925}
4926/* END_CASE */
4927
4928/* BEGIN_CASE */
4929void key_agreement_output( int alg_arg,
4930 int our_key_type_arg, data_t *our_key_data,
4931 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004932 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004933{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004934 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004935 psa_algorithm_t alg = alg_arg;
4936 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004937 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004938 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004939 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004940
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004941 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4942 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004943
Gilles Peskine8817f612018-12-18 00:18:46 +01004944 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004945
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004946 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4947 psa_set_key_algorithm( &attributes, alg );
4948 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004949 PSA_ASSERT( psa_import_key( &attributes,
4950 our_key_data->x, our_key_data->len,
4951 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004952
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004953 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004954 PSA_ASSERT( psa_key_derivation_key_agreement(
4955 &operation,
4956 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4957 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004958 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4959 {
4960 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004961 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004962 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004963 NULL, 0 ) );
4964 }
Gilles Peskine59685592018-09-18 12:11:34 +02004965
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004966 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004967 actual_output,
4968 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004969 ASSERT_COMPARE( actual_output, expected_output1->len,
4970 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004971 if( expected_output2->len != 0 )
4972 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004973 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004974 actual_output,
4975 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004976 ASSERT_COMPARE( actual_output, expected_output2->len,
4977 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004978 }
Gilles Peskine59685592018-09-18 12:11:34 +02004979
4980exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004981 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004982 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004983 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004984 mbedtls_free( actual_output );
4985}
4986/* END_CASE */
4987
4988/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004989void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004990{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004991 size_t bytes = bytes_arg;
4992 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004993 unsigned char *output = NULL;
4994 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004995 size_t i;
4996 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004997
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004998 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4999 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005000 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02005001
Gilles Peskine8817f612018-12-18 00:18:46 +01005002 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02005003
Gilles Peskinea50d7392018-06-21 10:22:13 +02005004 /* Run several times, to ensure that every output byte will be
5005 * nonzero at least once with overwhelming probability
5006 * (2^(-8*number_of_runs)). */
5007 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02005008 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02005009 if( bytes != 0 )
5010 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01005011 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005012
5013 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01005014 ASSERT_COMPARE( output + bytes, sizeof( trail ),
5015 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005016
5017 for( i = 0; i < bytes; i++ )
5018 {
5019 if( output[i] != 0 )
5020 ++changed[i];
5021 }
Gilles Peskine05d69892018-06-19 22:00:52 +02005022 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02005023
5024 /* Check that every byte was changed to nonzero at least once. This
5025 * validates that psa_generate_random is overwriting every byte of
5026 * the output buffer. */
5027 for( i = 0; i < bytes; i++ )
5028 {
5029 TEST_ASSERT( changed[i] != 0 );
5030 }
Gilles Peskine05d69892018-06-19 22:00:52 +02005031
5032exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005033 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005034 mbedtls_free( output );
5035 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02005036}
5037/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02005038
5039/* BEGIN_CASE */
5040void generate_key( int type_arg,
5041 int bits_arg,
5042 int usage_arg,
5043 int alg_arg,
5044 int expected_status_arg )
5045{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005046 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005047 psa_key_type_t type = type_arg;
5048 psa_key_usage_t usage = usage_arg;
5049 size_t bits = bits_arg;
5050 psa_algorithm_t alg = alg_arg;
5051 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005052 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005053 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005054
Gilles Peskine8817f612018-12-18 00:18:46 +01005055 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005056
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005057 psa_set_key_usage_flags( &attributes, usage );
5058 psa_set_key_algorithm( &attributes, alg );
5059 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005060 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005061
5062 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005063 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005064 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005065 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005066
5067 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005068 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
5069 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
5070 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005071
Gilles Peskine818ca122018-06-20 18:16:48 +02005072 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005073 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02005074 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005075
5076exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005077 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005078 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005079 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005080}
5081/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03005082
Gilles Peskinee56e8782019-04-26 17:34:02 +02005083/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
5084void generate_key_rsa( int bits_arg,
5085 data_t *e_arg,
5086 int expected_status_arg )
5087{
5088 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02005089 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02005090 size_t bits = bits_arg;
5091 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
5092 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
5093 psa_status_t expected_status = expected_status_arg;
5094 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5095 uint8_t *exported = NULL;
5096 size_t exported_size =
5097 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
5098 size_t exported_length = SIZE_MAX;
5099 uint8_t *e_read_buffer = NULL;
5100 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02005101 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005102 size_t e_read_length = SIZE_MAX;
5103
5104 if( e_arg->len == 0 ||
5105 ( e_arg->len == 3 &&
5106 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
5107 {
5108 is_default_public_exponent = 1;
5109 e_read_size = 0;
5110 }
5111 ASSERT_ALLOC( e_read_buffer, e_read_size );
5112 ASSERT_ALLOC( exported, exported_size );
5113
5114 PSA_ASSERT( psa_crypto_init( ) );
5115
5116 psa_set_key_usage_flags( &attributes, usage );
5117 psa_set_key_algorithm( &attributes, alg );
5118 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
5119 e_arg->x, e_arg->len ) );
5120 psa_set_key_bits( &attributes, bits );
5121
5122 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005123 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005124 if( expected_status != PSA_SUCCESS )
5125 goto exit;
5126
5127 /* Test the key information */
5128 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5129 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5130 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5131 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
5132 e_read_buffer, e_read_size,
5133 &e_read_length ) );
5134 if( is_default_public_exponent )
5135 TEST_EQUAL( e_read_length, 0 );
5136 else
5137 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
5138
5139 /* Do something with the key according to its type and permitted usage. */
5140 if( ! exercise_key( handle, usage, alg ) )
5141 goto exit;
5142
5143 /* Export the key and check the public exponent. */
5144 PSA_ASSERT( psa_export_public_key( handle,
5145 exported, exported_size,
5146 &exported_length ) );
5147 {
5148 uint8_t *p = exported;
5149 uint8_t *end = exported + exported_length;
5150 size_t len;
5151 /* RSAPublicKey ::= SEQUENCE {
5152 * modulus INTEGER, -- n
5153 * publicExponent INTEGER } -- e
5154 */
5155 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005156 MBEDTLS_ASN1_SEQUENCE |
5157 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005158 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
5159 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
5160 MBEDTLS_ASN1_INTEGER ) );
5161 if( len >= 1 && p[0] == 0 )
5162 {
5163 ++p;
5164 --len;
5165 }
5166 if( e_arg->len == 0 )
5167 {
5168 TEST_EQUAL( len, 3 );
5169 TEST_EQUAL( p[0], 1 );
5170 TEST_EQUAL( p[1], 0 );
5171 TEST_EQUAL( p[2], 1 );
5172 }
5173 else
5174 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
5175 }
5176
5177exit:
5178 psa_reset_key_attributes( &attributes );
5179 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005180 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005181 mbedtls_free( e_read_buffer );
5182 mbedtls_free( exported );
5183}
5184/* END_CASE */
5185
Darryl Greend49a4992018-06-18 17:27:26 +01005186/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005187void persistent_key_load_key_from_storage( data_t *data,
5188 int type_arg, int bits_arg,
5189 int usage_flags_arg, int alg_arg,
5190 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01005191{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005192 psa_key_id_t key_id = 1;
5193 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005194 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005195 psa_key_handle_t base_key = 0;
5196 psa_key_type_t type = type_arg;
5197 size_t bits = bits_arg;
5198 psa_key_usage_t usage_flags = usage_flags_arg;
5199 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005200 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01005201 unsigned char *first_export = NULL;
5202 unsigned char *second_export = NULL;
5203 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
5204 size_t first_exported_length;
5205 size_t second_exported_length;
5206
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005207 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5208 {
5209 ASSERT_ALLOC( first_export, export_size );
5210 ASSERT_ALLOC( second_export, export_size );
5211 }
Darryl Greend49a4992018-06-18 17:27:26 +01005212
Gilles Peskine8817f612018-12-18 00:18:46 +01005213 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005214
Gilles Peskinec87af662019-05-15 16:12:22 +02005215 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005216 psa_set_key_usage_flags( &attributes, usage_flags );
5217 psa_set_key_algorithm( &attributes, alg );
5218 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005219 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01005220
Darryl Green0c6575a2018-11-07 16:05:30 +00005221 switch( generation_method )
5222 {
5223 case IMPORT_KEY:
5224 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02005225 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
5226 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005227 break;
Darryl Greend49a4992018-06-18 17:27:26 +01005228
Darryl Green0c6575a2018-11-07 16:05:30 +00005229 case GENERATE_KEY:
5230 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005231 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005232 break;
5233
5234 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005235 {
5236 /* Create base key */
5237 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
5238 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5239 psa_set_key_usage_flags( &base_attributes,
5240 PSA_KEY_USAGE_DERIVE );
5241 psa_set_key_algorithm( &base_attributes, derive_alg );
5242 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005243 PSA_ASSERT( psa_import_key( &base_attributes,
5244 data->x, data->len,
5245 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005246 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005247 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005248 PSA_ASSERT( psa_key_derivation_input_key(
5249 &operation,
5250 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005251 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005252 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005253 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005254 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5255 &operation,
5256 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005257 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005258 PSA_ASSERT( psa_destroy_key( base_key ) );
5259 base_key = 0;
5260 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005261 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005262 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005263 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005264
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005265 /* Export the key if permitted by the key policy. */
5266 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5267 {
5268 PSA_ASSERT( psa_export_key( handle,
5269 first_export, export_size,
5270 &first_exported_length ) );
5271 if( generation_method == IMPORT_KEY )
5272 ASSERT_COMPARE( data->x, data->len,
5273 first_export, first_exported_length );
5274 }
Darryl Greend49a4992018-06-18 17:27:26 +01005275
5276 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005277 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005278 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005279 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005280
Darryl Greend49a4992018-06-18 17:27:26 +01005281 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005282 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005283 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5284 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5285 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5286 PSA_KEY_LIFETIME_PERSISTENT );
5287 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5288 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5289 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5290 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005291
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005292 /* Export the key again if permitted by the key policy. */
5293 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005294 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005295 PSA_ASSERT( psa_export_key( handle,
5296 second_export, export_size,
5297 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005298 ASSERT_COMPARE( first_export, first_exported_length,
5299 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005300 }
5301
5302 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005303 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005304 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005305
5306exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005307 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005308 mbedtls_free( first_export );
5309 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005310 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005311 psa_destroy_key( base_key );
5312 if( handle == 0 )
5313 {
5314 /* In case there was a test failure after creating the persistent key
5315 * but while it was not open, try to re-open the persistent key
5316 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005317 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005318 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005319 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005320 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005321}
5322/* END_CASE */