blob: 79ef9a873319c417b22af3947173ca6e1bb4fb03 [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 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200739 /* Tolerate a slight departure from DER encoding:
740 * - 0 may be represented by an empty string or a 1-byte string.
741 * - The sign bit may be used as a value bit. */
742 if( ( len == 1 && ( *p )[0] == 0 ) ||
743 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
744 {
745 ++( *p );
746 --len;
747 }
748 if( min_bits == 0 && len == 0 )
749 return( 1 );
750 msb = ( *p )[0];
751 TEST_ASSERT( msb != 0 );
752 actual_bits = 8 * ( len - 1 );
753 while( msb != 0 )
754 {
755 msb >>= 1;
756 ++actual_bits;
757 }
758 TEST_ASSERT( actual_bits >= min_bits );
759 TEST_ASSERT( actual_bits <= max_bits );
760 if( must_be_odd )
761 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
762 *p += len;
763 return( 1 );
764exit:
765 return( 0 );
766}
767
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200768static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
769 uint8_t *exported, size_t exported_length )
770{
771 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100772 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200773 else
774 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200775
776#if defined(MBEDTLS_DES_C)
777 if( type == PSA_KEY_TYPE_DES )
778 {
779 /* Check the parity bits. */
780 unsigned i;
781 for( i = 0; i < bits / 8; i++ )
782 {
783 unsigned bit_count = 0;
784 unsigned m;
785 for( m = 1; m <= 0x100; m <<= 1 )
786 {
787 if( exported[i] & m )
788 ++bit_count;
789 }
790 TEST_ASSERT( bit_count % 2 != 0 );
791 }
792 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200793 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200794#endif
795
796#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200797 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200798 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200799 uint8_t *p = exported;
800 uint8_t *end = exported + exported_length;
801 size_t len;
802 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200803 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200804 * modulus INTEGER, -- n
805 * publicExponent INTEGER, -- e
806 * privateExponent INTEGER, -- d
807 * prime1 INTEGER, -- p
808 * prime2 INTEGER, -- q
809 * exponent1 INTEGER, -- d mod (p-1)
810 * exponent2 INTEGER, -- d mod (q-1)
811 * coefficient INTEGER, -- (inverse of q) mod p
812 * }
813 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100814 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
815 MBEDTLS_ASN1_SEQUENCE |
816 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
817 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200818 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
819 goto exit;
820 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
821 goto exit;
822 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
823 goto exit;
824 /* Require d to be at least half the size of n. */
825 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
826 goto exit;
827 /* Require p and q to be at most half the size of n, rounded up. */
828 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
829 goto exit;
830 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
831 goto exit;
832 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
833 goto exit;
834 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
835 goto exit;
836 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
837 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100838 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100839 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200840 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200841#endif /* MBEDTLS_RSA_C */
842
843#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200844 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200845 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100846 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100847 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100848 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200849 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200850#endif /* MBEDTLS_ECP_C */
851
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200852 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
853 {
854 uint8_t *p = exported;
855 uint8_t *end = exported + exported_length;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200856#if defined(MBEDTLS_RSA_C)
857 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
858 {
Jaeden Amerof7dca862019-06-27 17:31:33 +0100859 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200860 /* RSAPublicKey ::= SEQUENCE {
861 * modulus INTEGER, -- n
862 * publicExponent INTEGER } -- e
863 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100864 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
865 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100866 MBEDTLS_ASN1_CONSTRUCTED ),
867 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100868 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200869 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
870 goto exit;
871 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
872 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100873 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200874 }
875 else
876#endif /* MBEDTLS_RSA_C */
877#if defined(MBEDTLS_ECP_C)
878 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
879 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000880 /* The representation of an ECC public key is:
881 * - The byte 0x04;
882 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
883 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
884 * - where m is the bit size associated with the curve.
Jaeden Amero6b196002019-01-10 10:23:21 +0000885 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100886 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
887 TEST_EQUAL( p[0], 4 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200888 }
889 else
890#endif /* MBEDTLS_ECP_C */
891 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100892 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200893 mbedtls_snprintf( message, sizeof( message ),
894 "No sanity check for public key type=0x%08lx",
895 (unsigned long) type );
896 test_fail( message, __LINE__, __FILE__ );
897 return( 0 );
898 }
899 }
900 else
901
902 {
903 /* No sanity checks for other types */
904 }
905
906 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200907
908exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200909 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +0200910}
911
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100912static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +0200913 psa_key_usage_t usage )
914{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200915 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200916 uint8_t *exported = NULL;
917 size_t exported_size = 0;
918 size_t exported_length = 0;
919 int ok = 0;
920
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200921 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +0200922
923 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200924 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200925 {
Gilles Peskinefe11b722018-12-18 00:24:04 +0100926 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
927 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200928 ok = 1;
929 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +0200930 }
931
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200932 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
933 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200934 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200935
Gilles Peskine8817f612018-12-18 00:18:46 +0100936 PSA_ASSERT( psa_export_key( handle,
937 exported, exported_size,
938 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200939 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
940 psa_get_key_bits( &attributes ),
941 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +0200942
943exit:
944 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200945 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200946 return( ok );
947}
948
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100949static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +0200950{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200951 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +0200952 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +0200953 uint8_t *exported = NULL;
954 size_t exported_size = 0;
955 size_t exported_length = 0;
956 int ok = 0;
957
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200958 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
959 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200960 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100961 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100962 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +0200963 return( 1 );
964 }
965
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200966 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200967 psa_get_key_type( &attributes ) );
968 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
969 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +0200970 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +0200971
Gilles Peskine8817f612018-12-18 00:18:46 +0100972 PSA_ASSERT( psa_export_public_key( handle,
973 exported, exported_size,
974 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200975 ok = exported_key_sanity_check( public_type,
976 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +0200977 exported, exported_length );
978
979exit:
980 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200981 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +0200982 return( ok );
983}
984
Gilles Peskinec9516fb2019-02-05 20:32:06 +0100985/** Do smoke tests on a key.
986 *
987 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
988 * sign/verify, or derivation) that is permitted according to \p usage.
989 * \p usage and \p alg should correspond to the expected policy on the
990 * key.
991 *
992 * Export the key if permitted by \p usage, and check that the output
993 * looks sensible. If \p usage forbids export, check that
994 * \p psa_export_key correctly rejects the attempt. If the key is
995 * asymmetric, also check \p psa_export_public_key.
996 *
997 * If the key fails the tests, this function calls the test framework's
998 * `test_fail` function and returns false. Otherwise this function returns
999 * true. Therefore it should be used as follows:
1000 * ```
1001 * if( ! exercise_key( ... ) ) goto exit;
1002 * ```
1003 *
1004 * \param handle The key to exercise. It should be capable of performing
1005 * \p alg.
1006 * \param usage The usage flags to assume.
1007 * \param alg The algorithm to exercise.
1008 *
1009 * \retval 0 The key failed the smoke tests.
1010 * \retval 1 The key passed the smoke tests.
1011 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001012static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001013 psa_key_usage_t usage,
1014 psa_algorithm_t alg )
1015{
1016 int ok;
1017 if( alg == 0 )
1018 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1019 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001020 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001021 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001022 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001023 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001024 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001025 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001026 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001027 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001028 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001029 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001030 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001031 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1032 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001033 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001034 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001035 else
1036 {
1037 char message[40];
1038 mbedtls_snprintf( message, sizeof( message ),
1039 "No code to exercise alg=0x%08lx",
1040 (unsigned long) alg );
1041 test_fail( message, __LINE__, __FILE__ );
1042 ok = 0;
1043 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001044
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001045 ok = ok && exercise_export_key( handle, usage );
1046 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001047
Gilles Peskine02b75072018-07-01 22:31:34 +02001048 return( ok );
1049}
1050
Gilles Peskine10df3412018-10-25 22:35:43 +02001051static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1052 psa_algorithm_t alg )
1053{
1054 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1055 {
1056 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1057 PSA_KEY_USAGE_VERIFY :
1058 PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
1059 }
1060 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1061 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1062 {
1063 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1064 PSA_KEY_USAGE_ENCRYPT :
1065 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1066 }
1067 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1068 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1069 {
1070 return( PSA_KEY_USAGE_DERIVE );
1071 }
1072 else
1073 {
1074 return( 0 );
1075 }
1076
1077}
Darryl Green0c6575a2018-11-07 16:05:30 +00001078
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001079static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1080{
1081 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1082 uint8_t buffer[1];
1083 size_t length;
1084 int ok = 0;
1085
Gilles Peskinec87af662019-05-15 16:12:22 +02001086 psa_set_key_id( &attributes, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001087 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1088 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1089 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1090 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
1091 PSA_ERROR_INVALID_HANDLE );
1092 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001093 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001094 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1095 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1096 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
1097 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1098
1099 TEST_EQUAL( psa_export_key( handle,
1100 buffer, sizeof( buffer ), &length ),
1101 PSA_ERROR_INVALID_HANDLE );
1102 TEST_EQUAL( psa_export_public_key( handle,
1103 buffer, sizeof( buffer ), &length ),
1104 PSA_ERROR_INVALID_HANDLE );
1105
1106 TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
1107 TEST_EQUAL( psa_destroy_key( handle ), PSA_ERROR_INVALID_HANDLE );
1108
1109 ok = 1;
1110
1111exit:
1112 psa_reset_key_attributes( &attributes );
1113 return( ok );
1114}
1115
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001116/* Assert that a key isn't reported as having a slot number. */
1117#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1118#define ASSERT_NO_SLOT_NUMBER( attributes ) \
1119 do \
1120 { \
1121 psa_key_slot_number_t ASSERT_NO_SLOT_NUMBER_slot_number; \
1122 TEST_EQUAL( psa_get_key_slot_number( \
1123 attributes, \
1124 &ASSERT_NO_SLOT_NUMBER_slot_number ), \
1125 PSA_ERROR_INVALID_ARGUMENT ); \
1126 } \
1127 while( 0 )
1128#else /* MBEDTLS_PSA_CRYPTO_SE_C */
1129#define ASSERT_NO_SLOT_NUMBER( attributes ) \
1130 ( (void) 0 )
1131#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1132
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001133/* An overapproximation of the amount of storage needed for a key of the
1134 * given type and with the given content. The API doesn't make it easy
1135 * to find a good value for the size. The current implementation doesn't
1136 * care about the value anyway. */
1137#define KEY_BITS_FROM_DATA( type, data ) \
1138 ( data )->len
1139
Darryl Green0c6575a2018-11-07 16:05:30 +00001140typedef enum {
1141 IMPORT_KEY = 0,
1142 GENERATE_KEY = 1,
1143 DERIVE_KEY = 2
1144} generate_method;
1145
Gilles Peskinee59236f2018-01-27 23:32:46 +01001146/* END_HEADER */
1147
1148/* BEGIN_DEPENDENCIES
1149 * depends_on:MBEDTLS_PSA_CRYPTO_C
1150 * END_DEPENDENCIES
1151 */
1152
1153/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001154void static_checks( )
1155{
1156 size_t max_truncated_mac_size =
1157 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1158
1159 /* Check that the length for a truncated MAC always fits in the algorithm
1160 * encoding. The shifted mask is the maximum truncated value. The
1161 * untruncated algorithm may be one byte larger. */
1162 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
1163}
1164/* END_CASE */
1165
1166/* BEGIN_CASE */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001167void attributes_set_get( int id_arg, int lifetime_arg,
1168 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001169 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001170{
Gilles Peskine4747d192019-04-17 15:05:45 +02001171 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001172 psa_key_id_t id = id_arg;
1173 psa_key_lifetime_t lifetime = lifetime_arg;
1174 psa_key_usage_t usage_flags = usage_flags_arg;
1175 psa_algorithm_t alg = alg_arg;
1176 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001177 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001178
1179 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1180 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1181 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1182 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1183 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001184 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001185
Gilles Peskinec87af662019-05-15 16:12:22 +02001186 psa_set_key_id( &attributes, id );
1187 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001188 psa_set_key_usage_flags( &attributes, usage_flags );
1189 psa_set_key_algorithm( &attributes, alg );
1190 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001191 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001192
1193 TEST_EQUAL( psa_get_key_id( &attributes ), id );
1194 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1195 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1196 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1197 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001198 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001199
1200 psa_reset_key_attributes( &attributes );
1201
1202 TEST_EQUAL( psa_get_key_id( &attributes ), 0 );
1203 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1204 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1205 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1206 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001207 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001208}
1209/* END_CASE */
1210
1211/* BEGIN_CASE */
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001212void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg,
1213 int expected_id_arg, int expected_lifetime_arg )
1214{
1215 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1216 psa_key_id_t id1 = id1_arg;
1217 psa_key_lifetime_t lifetime = lifetime_arg;
1218 psa_key_id_t id2 = id2_arg;
1219 psa_key_id_t expected_id = expected_id_arg;
1220 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1221
1222 if( id1_arg != -1 )
1223 psa_set_key_id( &attributes, id1 );
1224 if( lifetime_arg != -1 )
1225 psa_set_key_lifetime( &attributes, lifetime );
1226 if( id2_arg != -1 )
1227 psa_set_key_id( &attributes, id2 );
1228
1229 TEST_EQUAL( psa_get_key_id( &attributes ), expected_id );
1230 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1231}
1232/* END_CASE */
1233
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001234/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_SE_C */
1235void slot_number_attribute( )
1236{
1237 psa_key_slot_number_t slot_number = 0xdeadbeef;
1238 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1239
1240 /* Initially, there is no slot number. */
1241 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1242 PSA_ERROR_INVALID_ARGUMENT );
1243
1244 /* Test setting a slot number. */
1245 psa_set_key_slot_number( &attributes, 0 );
1246 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1247 TEST_EQUAL( slot_number, 0 );
1248
1249 /* Test changing the slot number. */
1250 psa_set_key_slot_number( &attributes, 42 );
1251 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1252 TEST_EQUAL( slot_number, 42 );
1253
1254 /* Test clearing the slot number. */
1255 psa_clear_key_slot_number( &attributes );
1256 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1257 PSA_ERROR_INVALID_ARGUMENT );
1258
1259 /* Clearing again should have no effect. */
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 /* Test that reset clears the slot number. */
1265 psa_set_key_slot_number( &attributes, 42 );
1266 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1267 TEST_EQUAL( slot_number, 42 );
1268 psa_reset_key_attributes( &attributes );
1269 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1270 PSA_ERROR_INVALID_ARGUMENT );
1271}
1272/* END_CASE */
1273
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001274/* BEGIN_CASE */
Gilles Peskine6edfa292019-07-31 15:53:45 +02001275void import_with_policy( int type_arg,
1276 int usage_arg, int alg_arg,
1277 int expected_status_arg )
1278{
1279 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1280 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
1281 psa_key_handle_t handle = 0;
1282 psa_key_type_t type = type_arg;
1283 psa_key_usage_t usage = usage_arg;
1284 psa_algorithm_t alg = alg_arg;
1285 psa_status_t expected_status = expected_status_arg;
1286 const uint8_t key_material[16] = {0};
1287 psa_status_t status;
1288
1289 PSA_ASSERT( psa_crypto_init( ) );
1290
1291 psa_set_key_type( &attributes, type );
1292 psa_set_key_usage_flags( &attributes, usage );
1293 psa_set_key_algorithm( &attributes, alg );
1294
1295 status = psa_import_key( &attributes,
1296 key_material, sizeof( key_material ),
1297 &handle );
1298 TEST_EQUAL( status, expected_status );
1299 if( status != PSA_SUCCESS )
1300 goto exit;
1301
1302 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1303 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1304 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1305 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001306 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001307
1308 PSA_ASSERT( psa_destroy_key( handle ) );
1309 test_operations_on_invalid_handle( handle );
1310
1311exit:
1312 psa_destroy_key( handle );
1313 psa_reset_key_attributes( &got_attributes );
1314 PSA_DONE( );
1315}
1316/* END_CASE */
1317
1318/* BEGIN_CASE */
1319void import_with_data( data_t *data, int type_arg,
1320 int attr_bits_arg,
1321 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001322{
1323 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1324 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001325 psa_key_handle_t handle = 0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001326 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001327 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001328 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001329 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001330
Gilles Peskine8817f612018-12-18 00:18:46 +01001331 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001332
Gilles Peskine4747d192019-04-17 15:05:45 +02001333 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001334 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001335
Gilles Peskine73676cb2019-05-15 20:15:10 +02001336 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001337 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001338 if( status != PSA_SUCCESS )
1339 goto exit;
1340
1341 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1342 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001343 if( attr_bits != 0 )
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001344 TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001345 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001346
1347 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001348 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001349
1350exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001351 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001352 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001353 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001354}
1355/* END_CASE */
1356
1357/* BEGIN_CASE */
Gilles Peskinec744d992019-07-30 17:26:54 +02001358void import_large_key( int type_arg, int byte_size_arg,
1359 int expected_status_arg )
1360{
1361 psa_key_type_t type = type_arg;
1362 size_t byte_size = byte_size_arg;
1363 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1364 psa_status_t expected_status = expected_status_arg;
1365 psa_key_handle_t handle = 0;
1366 psa_status_t status;
1367 uint8_t *buffer = NULL;
1368 size_t buffer_size = byte_size + 1;
1369 size_t n;
1370
1371 /* It would be better to skip the test than fail it if the allocation
1372 * fails, but the test framework doesn't support this yet. */
1373 ASSERT_ALLOC( buffer, buffer_size );
1374 memset( buffer, 'K', byte_size );
1375
1376 PSA_ASSERT( psa_crypto_init( ) );
1377
1378 /* Try importing the key */
1379 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1380 psa_set_key_type( &attributes, type );
1381 status = psa_import_key( &attributes, buffer, byte_size, &handle );
1382 TEST_EQUAL( status, expected_status );
1383
1384 if( status == PSA_SUCCESS )
1385 {
1386 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1387 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1388 TEST_EQUAL( psa_get_key_bits( &attributes ),
1389 PSA_BYTES_TO_BITS( byte_size ) );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001390 ASSERT_NO_SLOT_NUMBER( &attributes );
Gilles Peskinec744d992019-07-30 17:26:54 +02001391 memset( buffer, 0, byte_size + 1 );
1392 PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) );
1393 for( n = 0; n < byte_size; n++ )
1394 TEST_EQUAL( buffer[n], 'K' );
1395 for( n = byte_size; n < buffer_size; n++ )
1396 TEST_EQUAL( buffer[n], 0 );
1397 }
1398
1399exit:
1400 psa_destroy_key( handle );
1401 PSA_DONE( );
1402 mbedtls_free( buffer );
1403}
1404/* END_CASE */
1405
1406/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001407void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1408{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001409 psa_key_handle_t handle = 0;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001410 size_t bits = bits_arg;
1411 psa_status_t expected_status = expected_status_arg;
1412 psa_status_t status;
1413 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001414 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001415 size_t buffer_size = /* Slight overapproximations */
1416 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001417 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001418 unsigned char *p;
1419 int ret;
1420 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001421 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001422
Gilles Peskine8817f612018-12-18 00:18:46 +01001423 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001424 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001425
1426 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1427 bits, keypair ) ) >= 0 );
1428 length = ret;
1429
1430 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001431 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001432 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001433 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001434
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001435 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001436 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001437
1438exit:
1439 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001440 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001441}
1442/* END_CASE */
1443
1444/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001445void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001446 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001447 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001448 int expected_bits,
1449 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001450 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001451 int canonical_input )
1452{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001453 psa_key_handle_t handle = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001454 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001455 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001456 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001457 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001458 unsigned char *exported = NULL;
1459 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001460 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001461 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001462 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001463 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001464 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001465
Moran Pekercb088e72018-07-17 17:36:59 +03001466 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001467 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001468 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001469 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001470 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001471
Gilles Peskine4747d192019-04-17 15:05:45 +02001472 psa_set_key_usage_flags( &attributes, usage_arg );
1473 psa_set_key_algorithm( &attributes, alg );
1474 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001475
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001476 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001477 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001478
1479 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001480 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1481 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1482 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001483 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001484
1485 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001486 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001487 exported, export_size,
1488 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001489 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001490
1491 /* The exported length must be set by psa_export_key() to a value between 0
1492 * and export_size. On errors, the exported length must be 0. */
1493 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1494 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1495 TEST_ASSERT( exported_length <= export_size );
1496
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001497 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001498 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001499 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001500 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001501 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001502 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001503 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001504
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001505 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001506 goto exit;
1507
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001508 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001509 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001510 else
1511 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001512 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001513 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1514 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001515 PSA_ASSERT( psa_export_key( handle2,
1516 reexported,
1517 export_size,
1518 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001519 ASSERT_COMPARE( exported, exported_length,
1520 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001521 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001522 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001523 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001524
1525destroy:
1526 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001527 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001528 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001529
1530exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001531 mbedtls_free( exported );
1532 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001533 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001534 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001535}
1536/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001537
Moran Pekerf709f4a2018-06-06 17:26:04 +03001538/* BEGIN_CASE */
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001539void invalid_handle( int handle )
Moran Peker28a38e62018-11-07 16:18:24 +02001540{
Gilles Peskine8817f612018-12-18 00:18:46 +01001541 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001542 test_operations_on_invalid_handle( handle );
Moran Peker28a38e62018-11-07 16:18:24 +02001543
1544exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001545 PSA_DONE( );
Moran Peker28a38e62018-11-07 16:18:24 +02001546}
1547/* END_CASE */
1548
1549/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001550void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001551 int type_arg,
1552 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001553 int export_size_delta,
1554 int expected_export_status_arg,
1555 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001556{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001557 psa_key_handle_t handle = 0;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001558 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001559 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001560 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001561 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001562 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001563 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001564 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001565 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001566
Gilles Peskine8817f612018-12-18 00:18:46 +01001567 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001568
Gilles Peskine4747d192019-04-17 15:05:45 +02001569 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1570 psa_set_key_algorithm( &attributes, alg );
1571 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001572
1573 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001574 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001575
Gilles Peskine49c25912018-10-29 15:15:31 +01001576 /* Export the public key */
1577 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001578 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001579 exported, export_size,
1580 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001581 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001582 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001583 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001584 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001585 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001586 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1587 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001588 TEST_ASSERT( expected_public_key->len <=
1589 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001590 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1591 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001592 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001593
1594exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001595 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001596 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001597 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001598 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001599}
1600/* END_CASE */
1601
Gilles Peskine20035e32018-02-03 22:44:14 +01001602/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001603void import_and_exercise_key( data_t *data,
1604 int type_arg,
1605 int bits_arg,
1606 int alg_arg )
1607{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001608 psa_key_handle_t handle = 0;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001609 psa_key_type_t type = type_arg;
1610 size_t bits = bits_arg;
1611 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001612 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001613 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001614 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001615
Gilles Peskine8817f612018-12-18 00:18:46 +01001616 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001617
Gilles Peskine4747d192019-04-17 15:05:45 +02001618 psa_set_key_usage_flags( &attributes, usage );
1619 psa_set_key_algorithm( &attributes, alg );
1620 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001621
1622 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001623 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001624
1625 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001626 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1627 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1628 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001629
1630 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001631 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001632 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001633
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001634 PSA_ASSERT( psa_destroy_key( handle ) );
1635 test_operations_on_invalid_handle( handle );
1636
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001637exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001638 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001639 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001640 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001641}
1642/* END_CASE */
1643
1644/* BEGIN_CASE */
Gilles Peskined5b33222018-06-18 22:20:03 +02001645void key_policy( int usage_arg, int alg_arg )
1646{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001647 psa_key_handle_t handle = 0;
Gilles Peskined5b33222018-06-18 22:20:03 +02001648 psa_algorithm_t alg = alg_arg;
1649 psa_key_usage_t usage = usage_arg;
1650 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
1651 unsigned char key[32] = {0};
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001652 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001653
1654 memset( key, 0x2a, sizeof( key ) );
1655
Gilles Peskine8817f612018-12-18 00:18:46 +01001656 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001657
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001658 psa_set_key_usage_flags( &attributes, usage );
1659 psa_set_key_algorithm( &attributes, alg );
1660 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001661
Gilles Peskine73676cb2019-05-15 20:15:10 +02001662 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001663
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001664 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1665 TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
1666 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage );
1667 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001668
1669exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001670 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001671 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001672 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001673}
1674/* END_CASE */
1675
1676/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001677void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001678{
1679 /* Test each valid way of initializing the object, except for `= {0}`, as
1680 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1681 * though it's OK by the C standard. We could test for this, but we'd need
1682 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001683 psa_key_attributes_t func = psa_key_attributes_init( );
1684 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1685 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001686
1687 memset( &zero, 0, sizeof( zero ) );
1688
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001689 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1690 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1691 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001692
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001693 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1694 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1695 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1696
1697 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1698 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1699 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1700
1701 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1702 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1703 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1704
1705 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1706 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1707 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001708}
1709/* END_CASE */
1710
1711/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001712void mac_key_policy( int policy_usage,
1713 int policy_alg,
1714 int key_type,
1715 data_t *key_data,
1716 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001717{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001718 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001719 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001720 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001721 psa_status_t status;
1722 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001723
Gilles Peskine8817f612018-12-18 00:18:46 +01001724 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001725
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001726 psa_set_key_usage_flags( &attributes, policy_usage );
1727 psa_set_key_algorithm( &attributes, policy_alg );
1728 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001729
Gilles Peskine049c7532019-05-15 20:22:09 +02001730 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1731 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001732
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001733 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001734 if( policy_alg == exercise_alg &&
1735 ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001736 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001737 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001738 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001739 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001740
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001741 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001742 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001743 if( policy_alg == exercise_alg &&
1744 ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001745 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001746 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001747 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001748
1749exit:
1750 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001751 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001752 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001753}
1754/* END_CASE */
1755
1756/* BEGIN_CASE */
1757void cipher_key_policy( int policy_usage,
1758 int policy_alg,
1759 int key_type,
1760 data_t *key_data,
1761 int exercise_alg )
1762{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001763 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001764 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001765 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001766 psa_status_t status;
1767
Gilles Peskine8817f612018-12-18 00:18:46 +01001768 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001769
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001770 psa_set_key_usage_flags( &attributes, policy_usage );
1771 psa_set_key_algorithm( &attributes, policy_alg );
1772 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001773
Gilles Peskine049c7532019-05-15 20:22:09 +02001774 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1775 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001776
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001777 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001778 if( policy_alg == exercise_alg &&
1779 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001780 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001781 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001782 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001783 psa_cipher_abort( &operation );
1784
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001785 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001786 if( policy_alg == exercise_alg &&
1787 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001788 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001789 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001790 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001791
1792exit:
1793 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001794 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001795 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001796}
1797/* END_CASE */
1798
1799/* BEGIN_CASE */
1800void aead_key_policy( int policy_usage,
1801 int policy_alg,
1802 int key_type,
1803 data_t *key_data,
1804 int nonce_length_arg,
1805 int tag_length_arg,
1806 int exercise_alg )
1807{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001808 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001809 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001810 psa_status_t status;
1811 unsigned char nonce[16] = {0};
1812 size_t nonce_length = nonce_length_arg;
1813 unsigned char tag[16];
1814 size_t tag_length = tag_length_arg;
1815 size_t output_length;
1816
1817 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
1818 TEST_ASSERT( tag_length <= sizeof( tag ) );
1819
Gilles Peskine8817f612018-12-18 00:18:46 +01001820 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001821
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001822 psa_set_key_usage_flags( &attributes, policy_usage );
1823 psa_set_key_algorithm( &attributes, policy_alg );
1824 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001825
Gilles Peskine049c7532019-05-15 20:22:09 +02001826 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1827 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001828
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001829 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001830 nonce, nonce_length,
1831 NULL, 0,
1832 NULL, 0,
1833 tag, tag_length,
1834 &output_length );
1835 if( policy_alg == exercise_alg &&
1836 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001837 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001838 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001839 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001840
1841 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001842 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001843 nonce, nonce_length,
1844 NULL, 0,
1845 tag, tag_length,
1846 NULL, 0,
1847 &output_length );
1848 if( policy_alg == exercise_alg &&
1849 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001850 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001851 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001852 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001853
1854exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001855 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001856 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001857}
1858/* END_CASE */
1859
1860/* BEGIN_CASE */
1861void asymmetric_encryption_key_policy( int policy_usage,
1862 int policy_alg,
1863 int key_type,
1864 data_t *key_data,
1865 int exercise_alg )
1866{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001867 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001868 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001869 psa_status_t status;
1870 size_t key_bits;
1871 size_t buffer_length;
1872 unsigned char *buffer = NULL;
1873 size_t output_length;
1874
Gilles Peskine8817f612018-12-18 00:18:46 +01001875 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001876
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001877 psa_set_key_usage_flags( &attributes, policy_usage );
1878 psa_set_key_algorithm( &attributes, policy_alg );
1879 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001880
Gilles Peskine049c7532019-05-15 20:22:09 +02001881 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1882 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001883
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001884 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1885 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001886 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
1887 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001888 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001889
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001890 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001891 NULL, 0,
1892 NULL, 0,
1893 buffer, buffer_length,
1894 &output_length );
1895 if( policy_alg == exercise_alg &&
1896 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001897 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001898 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001899 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001900
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02001901 if( buffer_length != 0 )
1902 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001903 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001904 buffer, buffer_length,
1905 NULL, 0,
1906 buffer, buffer_length,
1907 &output_length );
1908 if( policy_alg == exercise_alg &&
1909 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001910 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001911 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001912 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001913
1914exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001915 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001916 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001917 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001918 mbedtls_free( buffer );
1919}
1920/* END_CASE */
1921
1922/* BEGIN_CASE */
1923void asymmetric_signature_key_policy( int policy_usage,
1924 int policy_alg,
1925 int key_type,
1926 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001927 int exercise_alg,
1928 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001929{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001930 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001931 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001932 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001933 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
1934 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
1935 * compatible with the policy and `payload_length_arg` is supposed to be
1936 * a valid input length to sign. If `payload_length_arg <= 0`,
1937 * `exercise_alg` is supposed to be forbidden by the policy. */
1938 int compatible_alg = payload_length_arg > 0;
1939 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001940 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
1941 size_t signature_length;
1942
Gilles Peskine8817f612018-12-18 00:18:46 +01001943 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001944
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001945 psa_set_key_usage_flags( &attributes, policy_usage );
1946 psa_set_key_algorithm( &attributes, policy_alg );
1947 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001948
Gilles Peskine049c7532019-05-15 20:22:09 +02001949 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1950 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001951
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001952 status = psa_asymmetric_sign( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001953 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001954 signature, sizeof( signature ),
1955 &signature_length );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001956 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001957 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001958 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001959 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001960
1961 memset( signature, 0, sizeof( signature ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001962 status = psa_asymmetric_verify( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001963 payload, payload_length,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001964 signature, sizeof( signature ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +01001965 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01001966 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001967 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001968 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02001969
1970exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001971 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001972 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001973}
1974/* END_CASE */
1975
Janos Follathba3fab92019-06-11 14:50:16 +01001976/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02001977void derive_key_policy( int policy_usage,
1978 int policy_alg,
1979 int key_type,
1980 data_t *key_data,
1981 int exercise_alg )
1982{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001983 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001984 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02001985 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02001986 psa_status_t status;
1987
Gilles Peskine8817f612018-12-18 00:18:46 +01001988 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001989
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001990 psa_set_key_usage_flags( &attributes, policy_usage );
1991 psa_set_key_algorithm( &attributes, policy_alg );
1992 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001993
Gilles Peskine049c7532019-05-15 20:22:09 +02001994 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1995 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001996
Janos Follathba3fab92019-06-11 14:50:16 +01001997 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
1998
1999 if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
2000 PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
Janos Follath0c1ed842019-06-28 13:35:36 +01002001 {
Janos Follathba3fab92019-06-11 14:50:16 +01002002 PSA_ASSERT( psa_key_derivation_input_bytes(
2003 &operation,
2004 PSA_KEY_DERIVATION_INPUT_SEED,
2005 (const uint8_t*) "", 0) );
Janos Follath0c1ed842019-06-28 13:35:36 +01002006 }
Janos Follathba3fab92019-06-11 14:50:16 +01002007
2008 status = psa_key_derivation_input_key( &operation,
2009 PSA_KEY_DERIVATION_INPUT_SECRET,
2010 handle );
2011
Gilles Peskineea0fb492018-07-12 17:17:20 +02002012 if( policy_alg == exercise_alg &&
2013 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002014 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002015 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002016 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002017
2018exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002019 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002020 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002021 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002022}
2023/* END_CASE */
2024
2025/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02002026void agreement_key_policy( int policy_usage,
2027 int policy_alg,
2028 int key_type_arg,
2029 data_t *key_data,
2030 int exercise_alg )
2031{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002032 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002033 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02002034 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002035 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02002036 psa_status_t status;
2037
Gilles Peskine8817f612018-12-18 00:18:46 +01002038 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002039
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002040 psa_set_key_usage_flags( &attributes, policy_usage );
2041 psa_set_key_algorithm( &attributes, policy_alg );
2042 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002043
Gilles Peskine049c7532019-05-15 20:22:09 +02002044 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2045 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002046
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002047 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
2048 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002049
Gilles Peskine01d718c2018-09-18 12:01:02 +02002050 if( policy_alg == exercise_alg &&
2051 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002052 PSA_ASSERT( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002053 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002054 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002055
2056exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002057 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002058 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002059 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002060}
2061/* END_CASE */
2062
2063/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002064void key_policy_alg2( int key_type_arg, data_t *key_data,
2065 int usage_arg, int alg_arg, int alg2_arg )
2066{
2067 psa_key_handle_t handle = 0;
2068 psa_key_type_t key_type = key_type_arg;
2069 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
2070 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
2071 psa_key_usage_t usage = usage_arg;
2072 psa_algorithm_t alg = alg_arg;
2073 psa_algorithm_t alg2 = alg2_arg;
2074
2075 PSA_ASSERT( psa_crypto_init( ) );
2076
2077 psa_set_key_usage_flags( &attributes, usage );
2078 psa_set_key_algorithm( &attributes, alg );
2079 psa_set_key_enrollment_algorithm( &attributes, alg2 );
2080 psa_set_key_type( &attributes, key_type );
2081 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2082 &handle ) );
2083
2084 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
2085 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
2086 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
2087 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
2088
2089 if( ! exercise_key( handle, usage, alg ) )
2090 goto exit;
2091 if( ! exercise_key( handle, usage, alg2 ) )
2092 goto exit;
2093
2094exit:
2095 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002096 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002097}
2098/* END_CASE */
2099
2100/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002101void raw_agreement_key_policy( int policy_usage,
2102 int policy_alg,
2103 int key_type_arg,
2104 data_t *key_data,
2105 int exercise_alg )
2106{
2107 psa_key_handle_t handle = 0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002108 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002109 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002110 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002111 psa_status_t status;
2112
2113 PSA_ASSERT( psa_crypto_init( ) );
2114
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002115 psa_set_key_usage_flags( &attributes, policy_usage );
2116 psa_set_key_algorithm( &attributes, policy_alg );
2117 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002118
Gilles Peskine049c7532019-05-15 20:22:09 +02002119 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2120 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002121
2122 status = raw_key_agreement_with_self( exercise_alg, handle );
2123
2124 if( policy_alg == exercise_alg &&
2125 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
2126 PSA_ASSERT( status );
2127 else
2128 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
2129
2130exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002131 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002132 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002133 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002134}
2135/* END_CASE */
2136
2137/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002138void copy_success( int source_usage_arg,
2139 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002140 int type_arg, data_t *material,
2141 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002142 int target_usage_arg,
2143 int target_alg_arg, int target_alg2_arg,
2144 int expected_usage_arg,
2145 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01002146{
Gilles Peskineca25db92019-04-19 11:43:08 +02002147 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2148 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002149 psa_key_usage_t expected_usage = expected_usage_arg;
2150 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002151 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Gilles Peskineca25db92019-04-19 11:43:08 +02002152 psa_key_handle_t source_handle = 0;
2153 psa_key_handle_t target_handle = 0;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002154 uint8_t *export_buffer = NULL;
2155
Gilles Peskine57ab7212019-01-28 13:03:09 +01002156 PSA_ASSERT( psa_crypto_init( ) );
2157
Gilles Peskineca25db92019-04-19 11:43:08 +02002158 /* Prepare the source key. */
2159 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2160 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002161 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002162 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002163 PSA_ASSERT( psa_import_key( &source_attributes,
2164 material->x, material->len,
2165 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002166 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002167
Gilles Peskineca25db92019-04-19 11:43:08 +02002168 /* Prepare the target attributes. */
2169 if( copy_attributes )
2170 target_attributes = source_attributes;
2171 if( target_usage_arg != -1 )
2172 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2173 if( target_alg_arg != -1 )
2174 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002175 if( target_alg2_arg != -1 )
2176 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002177
2178 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002179 PSA_ASSERT( psa_copy_key( source_handle,
2180 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002181
2182 /* Destroy the source to ensure that this doesn't affect the target. */
2183 PSA_ASSERT( psa_destroy_key( source_handle ) );
2184
2185 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002186 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2187 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2188 psa_get_key_type( &target_attributes ) );
2189 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2190 psa_get_key_bits( &target_attributes ) );
2191 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2192 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002193 TEST_EQUAL( expected_alg2,
2194 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002195 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2196 {
2197 size_t length;
2198 ASSERT_ALLOC( export_buffer, material->len );
2199 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2200 material->len, &length ) );
2201 ASSERT_COMPARE( material->x, material->len,
2202 export_buffer, length );
2203 }
2204 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2205 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002206 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2207 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002208
2209 PSA_ASSERT( psa_close_key( target_handle ) );
2210
2211exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002212 psa_reset_key_attributes( &source_attributes );
2213 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002214 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002215 mbedtls_free( export_buffer );
2216}
2217/* END_CASE */
2218
2219/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002220void copy_fail( int source_usage_arg,
2221 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002222 int type_arg, data_t *material,
2223 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002224 int target_usage_arg,
2225 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002226 int expected_status_arg )
2227{
2228 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2229 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
2230 psa_key_handle_t source_handle = 0;
2231 psa_key_handle_t target_handle = 0;
2232
2233 PSA_ASSERT( psa_crypto_init( ) );
2234
2235 /* Prepare the source key. */
2236 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2237 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002238 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002239 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002240 PSA_ASSERT( psa_import_key( &source_attributes,
2241 material->x, material->len,
2242 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002243
2244 /* Prepare the target attributes. */
2245 psa_set_key_type( &target_attributes, target_type_arg );
2246 psa_set_key_bits( &target_attributes, target_bits_arg );
2247 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2248 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002249 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002250
2251 /* Try to copy the key. */
2252 TEST_EQUAL( psa_copy_key( source_handle,
2253 &target_attributes, &target_handle ),
2254 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002255
2256 PSA_ASSERT( psa_destroy_key( source_handle ) );
2257
Gilles Peskine4a644642019-05-03 17:14:08 +02002258exit:
2259 psa_reset_key_attributes( &source_attributes );
2260 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002261 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002262}
2263/* END_CASE */
2264
2265/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002266void hash_operation_init( )
2267{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002268 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002269 /* Test each valid way of initializing the object, except for `= {0}`, as
2270 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2271 * though it's OK by the C standard. We could test for this, but we'd need
2272 * to supress the Clang warning for the test. */
2273 psa_hash_operation_t func = psa_hash_operation_init( );
2274 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2275 psa_hash_operation_t zero;
2276
2277 memset( &zero, 0, sizeof( zero ) );
2278
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002279 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002280 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2281 PSA_ERROR_BAD_STATE );
2282 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2283 PSA_ERROR_BAD_STATE );
2284 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2285 PSA_ERROR_BAD_STATE );
2286
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002287 /* A default hash operation should be abortable without error. */
2288 PSA_ASSERT( psa_hash_abort( &func ) );
2289 PSA_ASSERT( psa_hash_abort( &init ) );
2290 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002291}
2292/* END_CASE */
2293
2294/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002295void hash_setup( int alg_arg,
2296 int expected_status_arg )
2297{
2298 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002299 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002300 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002301 psa_status_t status;
2302
Gilles Peskine8817f612018-12-18 00:18:46 +01002303 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002304
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002305 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002306 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002307
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002308 /* Whether setup succeeded or failed, abort must succeed. */
2309 PSA_ASSERT( psa_hash_abort( &operation ) );
2310
2311 /* If setup failed, reproduce the failure, so as to
2312 * test the resulting state of the operation object. */
2313 if( status != PSA_SUCCESS )
2314 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2315
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002316 /* Now the operation object should be reusable. */
2317#if defined(KNOWN_SUPPORTED_HASH_ALG)
2318 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2319 PSA_ASSERT( psa_hash_abort( &operation ) );
2320#endif
2321
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002322exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002323 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002324}
2325/* END_CASE */
2326
2327/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002328void hash_bad_order( )
2329{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002330 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002331 unsigned char input[] = "";
2332 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002333 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002334 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2335 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2336 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002337 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002338 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002339 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002340
Gilles Peskine8817f612018-12-18 00:18:46 +01002341 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002342
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002343 /* Call setup twice in a row. */
2344 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2345 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2346 PSA_ERROR_BAD_STATE );
2347 PSA_ASSERT( psa_hash_abort( &operation ) );
2348
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002349 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002350 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002351 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002352 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002353
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002354 /* Call update after finish. */
2355 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2356 PSA_ASSERT( psa_hash_finish( &operation,
2357 hash, sizeof( hash ), &hash_len ) );
2358 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002359 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002360 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002361
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002362 /* Call verify without calling setup beforehand. */
2363 TEST_EQUAL( psa_hash_verify( &operation,
2364 valid_hash, sizeof( valid_hash ) ),
2365 PSA_ERROR_BAD_STATE );
2366 PSA_ASSERT( psa_hash_abort( &operation ) );
2367
2368 /* Call verify after finish. */
2369 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2370 PSA_ASSERT( psa_hash_finish( &operation,
2371 hash, sizeof( hash ), &hash_len ) );
2372 TEST_EQUAL( psa_hash_verify( &operation,
2373 valid_hash, sizeof( valid_hash ) ),
2374 PSA_ERROR_BAD_STATE );
2375 PSA_ASSERT( psa_hash_abort( &operation ) );
2376
2377 /* Call verify twice in a row. */
2378 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2379 PSA_ASSERT( psa_hash_verify( &operation,
2380 valid_hash, sizeof( valid_hash ) ) );
2381 TEST_EQUAL( psa_hash_verify( &operation,
2382 valid_hash, sizeof( valid_hash ) ),
2383 PSA_ERROR_BAD_STATE );
2384 PSA_ASSERT( psa_hash_abort( &operation ) );
2385
2386 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002387 TEST_EQUAL( psa_hash_finish( &operation,
2388 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002389 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002390 PSA_ASSERT( psa_hash_abort( &operation ) );
2391
2392 /* Call finish twice in a row. */
2393 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2394 PSA_ASSERT( psa_hash_finish( &operation,
2395 hash, sizeof( hash ), &hash_len ) );
2396 TEST_EQUAL( psa_hash_finish( &operation,
2397 hash, sizeof( hash ), &hash_len ),
2398 PSA_ERROR_BAD_STATE );
2399 PSA_ASSERT( psa_hash_abort( &operation ) );
2400
2401 /* Call finish after calling verify. */
2402 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2403 PSA_ASSERT( psa_hash_verify( &operation,
2404 valid_hash, sizeof( valid_hash ) ) );
2405 TEST_EQUAL( psa_hash_finish( &operation,
2406 hash, sizeof( hash ), &hash_len ),
2407 PSA_ERROR_BAD_STATE );
2408 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002409
2410exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002411 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002412}
2413/* END_CASE */
2414
itayzafrir27e69452018-11-01 14:26:34 +02002415/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2416void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002417{
2418 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002419 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2420 * appended to it */
2421 unsigned char hash[] = {
2422 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2423 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2424 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002425 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002426 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002427
Gilles Peskine8817f612018-12-18 00:18:46 +01002428 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002429
itayzafrir27e69452018-11-01 14:26:34 +02002430 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002431 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002432 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002433 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002434
itayzafrir27e69452018-11-01 14:26:34 +02002435 /* psa_hash_verify with a non-matching hash */
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 + 1, expected_size ),
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 hash longer than expected */
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, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002443 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002444
itayzafrirec93d302018-10-18 18:01:10 +03002445exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002446 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002447}
2448/* END_CASE */
2449
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002450/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2451void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002452{
2453 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002454 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002455 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002456 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002457 size_t hash_len;
2458
Gilles Peskine8817f612018-12-18 00:18:46 +01002459 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002460
itayzafrir58028322018-10-25 10:22:01 +03002461 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002462 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002463 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002464 hash, expected_size - 1, &hash_len ),
2465 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002466
2467exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002468 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002469}
2470/* END_CASE */
2471
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002472/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2473void hash_clone_source_state( )
2474{
2475 psa_algorithm_t alg = PSA_ALG_SHA_256;
2476 unsigned char hash[PSA_HASH_MAX_SIZE];
2477 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2478 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2479 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2480 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2481 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2482 size_t hash_len;
2483
2484 PSA_ASSERT( psa_crypto_init( ) );
2485 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2486
2487 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2488 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2489 PSA_ASSERT( psa_hash_finish( &op_finished,
2490 hash, sizeof( hash ), &hash_len ) );
2491 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2492 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2493
2494 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2495 PSA_ERROR_BAD_STATE );
2496
2497 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2498 PSA_ASSERT( psa_hash_finish( &op_init,
2499 hash, sizeof( hash ), &hash_len ) );
2500 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2501 PSA_ASSERT( psa_hash_finish( &op_finished,
2502 hash, sizeof( hash ), &hash_len ) );
2503 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2504 PSA_ASSERT( psa_hash_finish( &op_aborted,
2505 hash, sizeof( hash ), &hash_len ) );
2506
2507exit:
2508 psa_hash_abort( &op_source );
2509 psa_hash_abort( &op_init );
2510 psa_hash_abort( &op_setup );
2511 psa_hash_abort( &op_finished );
2512 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002513 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002514}
2515/* END_CASE */
2516
2517/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2518void hash_clone_target_state( )
2519{
2520 psa_algorithm_t alg = PSA_ALG_SHA_256;
2521 unsigned char hash[PSA_HASH_MAX_SIZE];
2522 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2523 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2524 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2525 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2526 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2527 size_t hash_len;
2528
2529 PSA_ASSERT( psa_crypto_init( ) );
2530
2531 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2532 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2533 PSA_ASSERT( psa_hash_finish( &op_finished,
2534 hash, sizeof( hash ), &hash_len ) );
2535 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2536 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2537
2538 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2539 PSA_ASSERT( psa_hash_finish( &op_target,
2540 hash, sizeof( hash ), &hash_len ) );
2541
2542 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2543 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2544 PSA_ERROR_BAD_STATE );
2545 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2546 PSA_ERROR_BAD_STATE );
2547
2548exit:
2549 psa_hash_abort( &op_target );
2550 psa_hash_abort( &op_init );
2551 psa_hash_abort( &op_setup );
2552 psa_hash_abort( &op_finished );
2553 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002554 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002555}
2556/* END_CASE */
2557
itayzafrir58028322018-10-25 10:22:01 +03002558/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002559void mac_operation_init( )
2560{
Jaeden Amero252ef282019-02-15 14:05:35 +00002561 const uint8_t input[1] = { 0 };
2562
Jaeden Amero769ce272019-01-04 11:48:03 +00002563 /* Test each valid way of initializing the object, except for `= {0}`, as
2564 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2565 * though it's OK by the C standard. We could test for this, but we'd need
2566 * to supress the Clang warning for the test. */
2567 psa_mac_operation_t func = psa_mac_operation_init( );
2568 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2569 psa_mac_operation_t zero;
2570
2571 memset( &zero, 0, sizeof( zero ) );
2572
Jaeden Amero252ef282019-02-15 14:05:35 +00002573 /* A freshly-initialized MAC operation should not be usable. */
2574 TEST_EQUAL( psa_mac_update( &func,
2575 input, sizeof( input ) ),
2576 PSA_ERROR_BAD_STATE );
2577 TEST_EQUAL( psa_mac_update( &init,
2578 input, sizeof( input ) ),
2579 PSA_ERROR_BAD_STATE );
2580 TEST_EQUAL( psa_mac_update( &zero,
2581 input, sizeof( input ) ),
2582 PSA_ERROR_BAD_STATE );
2583
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002584 /* A default MAC operation should be abortable without error. */
2585 PSA_ASSERT( psa_mac_abort( &func ) );
2586 PSA_ASSERT( psa_mac_abort( &init ) );
2587 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002588}
2589/* END_CASE */
2590
2591/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002592void mac_setup( int key_type_arg,
2593 data_t *key,
2594 int alg_arg,
2595 int expected_status_arg )
2596{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002597 psa_key_type_t key_type = key_type_arg;
2598 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002599 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002600 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002601 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2602#if defined(KNOWN_SUPPORTED_MAC_ALG)
2603 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2604#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002605
Gilles Peskine8817f612018-12-18 00:18:46 +01002606 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002607
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002608 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2609 &operation, &status ) )
2610 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002611 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002612
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002613 /* The operation object should be reusable. */
2614#if defined(KNOWN_SUPPORTED_MAC_ALG)
2615 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2616 smoke_test_key_data,
2617 sizeof( smoke_test_key_data ),
2618 KNOWN_SUPPORTED_MAC_ALG,
2619 &operation, &status ) )
2620 goto exit;
2621 TEST_EQUAL( status, PSA_SUCCESS );
2622#endif
2623
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002624exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002625 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002626}
2627/* END_CASE */
2628
2629/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002630void mac_bad_order( )
2631{
2632 psa_key_handle_t handle = 0;
2633 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2634 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2635 const uint8_t key[] = {
2636 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2637 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2638 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002639 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002640 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2641 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2642 size_t sign_mac_length = 0;
2643 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2644 const uint8_t verify_mac[] = {
2645 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2646 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2647 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2648
2649 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002650 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
2651 psa_set_key_algorithm( &attributes, alg );
2652 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002653
Gilles Peskine73676cb2019-05-15 20:15:10 +02002654 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002655
Jaeden Amero252ef282019-02-15 14:05:35 +00002656 /* Call update without calling setup beforehand. */
2657 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2658 PSA_ERROR_BAD_STATE );
2659 PSA_ASSERT( psa_mac_abort( &operation ) );
2660
2661 /* Call sign finish without calling setup beforehand. */
2662 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2663 &sign_mac_length),
2664 PSA_ERROR_BAD_STATE );
2665 PSA_ASSERT( psa_mac_abort( &operation ) );
2666
2667 /* Call verify finish without calling setup beforehand. */
2668 TEST_EQUAL( psa_mac_verify_finish( &operation,
2669 verify_mac, sizeof( verify_mac ) ),
2670 PSA_ERROR_BAD_STATE );
2671 PSA_ASSERT( psa_mac_abort( &operation ) );
2672
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002673 /* Call setup twice in a row. */
2674 PSA_ASSERT( psa_mac_sign_setup( &operation,
2675 handle, alg ) );
2676 TEST_EQUAL( psa_mac_sign_setup( &operation,
2677 handle, alg ),
2678 PSA_ERROR_BAD_STATE );
2679 PSA_ASSERT( psa_mac_abort( &operation ) );
2680
Jaeden Amero252ef282019-02-15 14:05:35 +00002681 /* Call update after sign finish. */
2682 PSA_ASSERT( psa_mac_sign_setup( &operation,
2683 handle, alg ) );
2684 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2685 PSA_ASSERT( psa_mac_sign_finish( &operation,
2686 sign_mac, sizeof( sign_mac ),
2687 &sign_mac_length ) );
2688 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2689 PSA_ERROR_BAD_STATE );
2690 PSA_ASSERT( psa_mac_abort( &operation ) );
2691
2692 /* Call update after verify finish. */
2693 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002694 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002695 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2696 PSA_ASSERT( psa_mac_verify_finish( &operation,
2697 verify_mac, sizeof( verify_mac ) ) );
2698 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2699 PSA_ERROR_BAD_STATE );
2700 PSA_ASSERT( psa_mac_abort( &operation ) );
2701
2702 /* Call sign finish twice in a row. */
2703 PSA_ASSERT( psa_mac_sign_setup( &operation,
2704 handle, alg ) );
2705 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2706 PSA_ASSERT( psa_mac_sign_finish( &operation,
2707 sign_mac, sizeof( sign_mac ),
2708 &sign_mac_length ) );
2709 TEST_EQUAL( psa_mac_sign_finish( &operation,
2710 sign_mac, sizeof( sign_mac ),
2711 &sign_mac_length ),
2712 PSA_ERROR_BAD_STATE );
2713 PSA_ASSERT( psa_mac_abort( &operation ) );
2714
2715 /* Call verify finish twice in a row. */
2716 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002717 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002718 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2719 PSA_ASSERT( psa_mac_verify_finish( &operation,
2720 verify_mac, sizeof( verify_mac ) ) );
2721 TEST_EQUAL( psa_mac_verify_finish( &operation,
2722 verify_mac, sizeof( verify_mac ) ),
2723 PSA_ERROR_BAD_STATE );
2724 PSA_ASSERT( psa_mac_abort( &operation ) );
2725
2726 /* Setup sign but try verify. */
2727 PSA_ASSERT( psa_mac_sign_setup( &operation,
2728 handle, alg ) );
2729 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2730 TEST_EQUAL( psa_mac_verify_finish( &operation,
2731 verify_mac, sizeof( verify_mac ) ),
2732 PSA_ERROR_BAD_STATE );
2733 PSA_ASSERT( psa_mac_abort( &operation ) );
2734
2735 /* Setup verify but try sign. */
2736 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002737 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002738 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2739 TEST_EQUAL( psa_mac_sign_finish( &operation,
2740 sign_mac, sizeof( sign_mac ),
2741 &sign_mac_length ),
2742 PSA_ERROR_BAD_STATE );
2743 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002744
Gilles Peskine76b29a72019-05-28 14:08:50 +02002745 PSA_ASSERT( psa_destroy_key( handle ) );
2746
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002747exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002748 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002749}
2750/* END_CASE */
2751
2752/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002753void mac_sign( int key_type_arg,
2754 data_t *key,
2755 int alg_arg,
2756 data_t *input,
2757 data_t *expected_mac )
2758{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002759 psa_key_handle_t handle = 0;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002760 psa_key_type_t key_type = key_type_arg;
2761 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002762 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002763 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002764 /* Leave a little extra room in the output buffer. At the end of the
2765 * test, we'll check that the implementation didn't overwrite onto
2766 * this extra room. */
2767 uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
2768 size_t mac_buffer_size =
2769 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
2770 size_t mac_length = 0;
2771
2772 memset( actual_mac, '+', sizeof( actual_mac ) );
2773 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
2774 TEST_ASSERT( expected_mac->len <= mac_buffer_size );
2775
Gilles Peskine8817f612018-12-18 00:18:46 +01002776 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002777
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002778 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
2779 psa_set_key_algorithm( &attributes, alg );
2780 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002781
Gilles Peskine73676cb2019-05-15 20:15:10 +02002782 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002783
2784 /* Calculate the MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01002785 PSA_ASSERT( psa_mac_sign_setup( &operation,
2786 handle, alg ) );
2787 PSA_ASSERT( psa_mac_update( &operation,
2788 input->x, input->len ) );
2789 PSA_ASSERT( psa_mac_sign_finish( &operation,
2790 actual_mac, mac_buffer_size,
2791 &mac_length ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002792
2793 /* Compare with the expected value. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01002794 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
2795 actual_mac, mac_length );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002796
2797 /* Verify that the end of the buffer is untouched. */
2798 TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
2799 sizeof( actual_mac ) - mac_length ) );
2800
2801exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002802 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002803 PSA_DONE( );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02002804}
2805/* END_CASE */
2806
2807/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002808void mac_verify( int key_type_arg,
2809 data_t *key,
2810 int alg_arg,
2811 data_t *input,
2812 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002813{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002814 psa_key_handle_t handle = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002815 psa_key_type_t key_type = key_type_arg;
2816 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002817 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002818 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002819
Gilles Peskine69c12672018-06-28 00:07:19 +02002820 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
2821
Gilles Peskine8817f612018-12-18 00:18:46 +01002822 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002823
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002824 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
2825 psa_set_key_algorithm( &attributes, alg );
2826 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07002827
Gilles Peskine73676cb2019-05-15 20:15:10 +02002828 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02002829
Gilles Peskine8817f612018-12-18 00:18:46 +01002830 PSA_ASSERT( psa_mac_verify_setup( &operation,
2831 handle, alg ) );
2832 PSA_ASSERT( psa_destroy_key( handle ) );
2833 PSA_ASSERT( psa_mac_update( &operation,
2834 input->x, input->len ) );
2835 PSA_ASSERT( psa_mac_verify_finish( &operation,
2836 expected_mac->x,
2837 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002838
2839exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002840 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002841 PSA_DONE( );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002842}
2843/* END_CASE */
2844
2845/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00002846void cipher_operation_init( )
2847{
Jaeden Ameroab439972019-02-15 14:12:05 +00002848 const uint8_t input[1] = { 0 };
2849 unsigned char output[1] = { 0 };
2850 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002851 /* Test each valid way of initializing the object, except for `= {0}`, as
2852 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2853 * though it's OK by the C standard. We could test for this, but we'd need
2854 * to supress the Clang warning for the test. */
2855 psa_cipher_operation_t func = psa_cipher_operation_init( );
2856 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
2857 psa_cipher_operation_t zero;
2858
2859 memset( &zero, 0, sizeof( zero ) );
2860
Jaeden Ameroab439972019-02-15 14:12:05 +00002861 /* A freshly-initialized cipher operation should not be usable. */
2862 TEST_EQUAL( psa_cipher_update( &func,
2863 input, sizeof( input ),
2864 output, sizeof( output ),
2865 &output_length ),
2866 PSA_ERROR_BAD_STATE );
2867 TEST_EQUAL( psa_cipher_update( &init,
2868 input, sizeof( input ),
2869 output, sizeof( output ),
2870 &output_length ),
2871 PSA_ERROR_BAD_STATE );
2872 TEST_EQUAL( psa_cipher_update( &zero,
2873 input, sizeof( input ),
2874 output, sizeof( output ),
2875 &output_length ),
2876 PSA_ERROR_BAD_STATE );
2877
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002878 /* A default cipher operation should be abortable without error. */
2879 PSA_ASSERT( psa_cipher_abort( &func ) );
2880 PSA_ASSERT( psa_cipher_abort( &init ) );
2881 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00002882}
2883/* END_CASE */
2884
2885/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002886void cipher_setup( int key_type_arg,
2887 data_t *key,
2888 int alg_arg,
2889 int expected_status_arg )
2890{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002891 psa_key_type_t key_type = key_type_arg;
2892 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002893 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00002894 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002895 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002896#if defined(KNOWN_SUPPORTED_MAC_ALG)
2897 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2898#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002899
Gilles Peskine8817f612018-12-18 00:18:46 +01002900 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002901
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002902 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
2903 &operation, &status ) )
2904 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002905 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002906
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002907 /* The operation object should be reusable. */
2908#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
2909 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
2910 smoke_test_key_data,
2911 sizeof( smoke_test_key_data ),
2912 KNOWN_SUPPORTED_CIPHER_ALG,
2913 &operation, &status ) )
2914 goto exit;
2915 TEST_EQUAL( status, PSA_SUCCESS );
2916#endif
2917
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002918exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002919 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002920}
2921/* END_CASE */
2922
2923/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00002924void cipher_bad_order( )
2925{
2926 psa_key_handle_t handle = 0;
2927 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2928 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002929 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00002930 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2931 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2932 const uint8_t key[] = {
2933 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2934 0xaa, 0xaa, 0xaa, 0xaa };
2935 const uint8_t text[] = {
2936 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2937 0xbb, 0xbb, 0xbb, 0xbb };
2938 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2939 size_t length = 0;
2940
2941 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002942 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
2943 psa_set_key_algorithm( &attributes, alg );
2944 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02002945 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00002946
2947
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002948 /* Call encrypt setup twice in a row. */
2949 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2950 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
2951 PSA_ERROR_BAD_STATE );
2952 PSA_ASSERT( psa_cipher_abort( &operation ) );
2953
2954 /* Call decrypt setup twice in a row. */
2955 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
2956 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
2957 PSA_ERROR_BAD_STATE );
2958 PSA_ASSERT( psa_cipher_abort( &operation ) );
2959
Jaeden Ameroab439972019-02-15 14:12:05 +00002960 /* Generate an IV without calling setup beforehand. */
2961 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2962 buffer, sizeof( buffer ),
2963 &length ),
2964 PSA_ERROR_BAD_STATE );
2965 PSA_ASSERT( psa_cipher_abort( &operation ) );
2966
2967 /* Generate an IV twice in a row. */
2968 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2969 PSA_ASSERT( psa_cipher_generate_iv( &operation,
2970 buffer, sizeof( buffer ),
2971 &length ) );
2972 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2973 buffer, sizeof( buffer ),
2974 &length ),
2975 PSA_ERROR_BAD_STATE );
2976 PSA_ASSERT( psa_cipher_abort( &operation ) );
2977
2978 /* Generate an IV after it's already set. */
2979 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2980 PSA_ASSERT( psa_cipher_set_iv( &operation,
2981 iv, sizeof( iv ) ) );
2982 TEST_EQUAL( psa_cipher_generate_iv( &operation,
2983 buffer, sizeof( buffer ),
2984 &length ),
2985 PSA_ERROR_BAD_STATE );
2986 PSA_ASSERT( psa_cipher_abort( &operation ) );
2987
2988 /* Set an IV without calling setup beforehand. */
2989 TEST_EQUAL( psa_cipher_set_iv( &operation,
2990 iv, sizeof( iv ) ),
2991 PSA_ERROR_BAD_STATE );
2992 PSA_ASSERT( psa_cipher_abort( &operation ) );
2993
2994 /* Set an IV after it's already set. */
2995 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2996 PSA_ASSERT( psa_cipher_set_iv( &operation,
2997 iv, sizeof( iv ) ) );
2998 TEST_EQUAL( psa_cipher_set_iv( &operation,
2999 iv, sizeof( iv ) ),
3000 PSA_ERROR_BAD_STATE );
3001 PSA_ASSERT( psa_cipher_abort( &operation ) );
3002
3003 /* Set an IV after it's already generated. */
3004 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3005 PSA_ASSERT( psa_cipher_generate_iv( &operation,
3006 buffer, sizeof( buffer ),
3007 &length ) );
3008 TEST_EQUAL( psa_cipher_set_iv( &operation,
3009 iv, sizeof( iv ) ),
3010 PSA_ERROR_BAD_STATE );
3011 PSA_ASSERT( psa_cipher_abort( &operation ) );
3012
3013 /* Call update without calling setup beforehand. */
3014 TEST_EQUAL( psa_cipher_update( &operation,
3015 text, sizeof( text ),
3016 buffer, sizeof( buffer ),
3017 &length ),
3018 PSA_ERROR_BAD_STATE );
3019 PSA_ASSERT( psa_cipher_abort( &operation ) );
3020
3021 /* Call update without an IV where an IV is required. */
3022 TEST_EQUAL( psa_cipher_update( &operation,
3023 text, sizeof( text ),
3024 buffer, sizeof( buffer ),
3025 &length ),
3026 PSA_ERROR_BAD_STATE );
3027 PSA_ASSERT( psa_cipher_abort( &operation ) );
3028
3029 /* Call update after finish. */
3030 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3031 PSA_ASSERT( psa_cipher_set_iv( &operation,
3032 iv, sizeof( iv ) ) );
3033 PSA_ASSERT( psa_cipher_finish( &operation,
3034 buffer, sizeof( buffer ), &length ) );
3035 TEST_EQUAL( psa_cipher_update( &operation,
3036 text, sizeof( text ),
3037 buffer, sizeof( buffer ),
3038 &length ),
3039 PSA_ERROR_BAD_STATE );
3040 PSA_ASSERT( psa_cipher_abort( &operation ) );
3041
3042 /* Call finish without calling setup beforehand. */
3043 TEST_EQUAL( psa_cipher_finish( &operation,
3044 buffer, sizeof( buffer ), &length ),
3045 PSA_ERROR_BAD_STATE );
3046 PSA_ASSERT( psa_cipher_abort( &operation ) );
3047
3048 /* Call finish without an IV where an IV is required. */
3049 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3050 /* Not calling update means we are encrypting an empty buffer, which is OK
3051 * for cipher modes with padding. */
3052 TEST_EQUAL( psa_cipher_finish( &operation,
3053 buffer, sizeof( buffer ), &length ),
3054 PSA_ERROR_BAD_STATE );
3055 PSA_ASSERT( psa_cipher_abort( &operation ) );
3056
3057 /* Call finish twice in a row. */
3058 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3059 PSA_ASSERT( psa_cipher_set_iv( &operation,
3060 iv, sizeof( iv ) ) );
3061 PSA_ASSERT( psa_cipher_finish( &operation,
3062 buffer, sizeof( buffer ), &length ) );
3063 TEST_EQUAL( psa_cipher_finish( &operation,
3064 buffer, sizeof( buffer ), &length ),
3065 PSA_ERROR_BAD_STATE );
3066 PSA_ASSERT( psa_cipher_abort( &operation ) );
3067
Gilles Peskine76b29a72019-05-28 14:08:50 +02003068 PSA_ASSERT( psa_destroy_key( handle ) );
3069
Jaeden Ameroab439972019-02-15 14:12:05 +00003070exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003071 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003072}
3073/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003074
Gilles Peskine50e586b2018-06-08 14:28:46 +02003075/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003076void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003077 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003078 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003079 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003080{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003081 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003082 psa_status_t status;
3083 psa_key_type_t key_type = key_type_arg;
3084 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003085 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003086 unsigned char *output = NULL;
3087 size_t output_buffer_size = 0;
3088 size_t function_output_length = 0;
3089 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003090 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003091 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003092
Gilles Peskine8817f612018-12-18 00:18:46 +01003093 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003094
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003095 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3096 psa_set_key_algorithm( &attributes, alg );
3097 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003098
Gilles Peskine73676cb2019-05-15 20:15:10 +02003099 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003100
Gilles Peskine8817f612018-12-18 00:18:46 +01003101 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3102 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003103
Gilles Peskine423005e2019-05-06 15:22:57 +02003104 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003105 output_buffer_size = ( (size_t) input->len +
3106 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003107 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003108
Gilles Peskine8817f612018-12-18 00:18:46 +01003109 PSA_ASSERT( psa_cipher_update( &operation,
3110 input->x, input->len,
3111 output, output_buffer_size,
3112 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003113 total_output_length += function_output_length;
3114 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003115 output + total_output_length,
3116 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003117 &function_output_length );
3118 total_output_length += function_output_length;
3119
Gilles Peskinefe11b722018-12-18 00:24:04 +01003120 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003121 if( expected_status == PSA_SUCCESS )
3122 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003123 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003124 ASSERT_COMPARE( expected_output->x, expected_output->len,
3125 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003126 }
3127
3128exit:
3129 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003130 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003131 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003132}
3133/* END_CASE */
3134
3135/* BEGIN_CASE */
3136void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003137 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003138 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003139 int first_part_size_arg,
3140 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003141 data_t *expected_output )
3142{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003143 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003144 psa_key_type_t key_type = key_type_arg;
3145 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003146 size_t first_part_size = first_part_size_arg;
3147 size_t output1_length = output1_length_arg;
3148 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003149 unsigned char *output = NULL;
3150 size_t output_buffer_size = 0;
3151 size_t function_output_length = 0;
3152 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003153 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003154 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003155
Gilles Peskine8817f612018-12-18 00:18:46 +01003156 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003157
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003158 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3159 psa_set_key_algorithm( &attributes, alg );
3160 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003161
Gilles Peskine73676cb2019-05-15 20:15:10 +02003162 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003163
Gilles Peskine8817f612018-12-18 00:18:46 +01003164 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3165 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003166
Gilles Peskine423005e2019-05-06 15:22:57 +02003167 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003168 output_buffer_size = ( (size_t) input->len +
3169 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003170 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003171
Gilles Peskinee0866522019-02-19 19:44:00 +01003172 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003173 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3174 output, output_buffer_size,
3175 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003176 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003177 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003178 PSA_ASSERT( psa_cipher_update( &operation,
3179 input->x + first_part_size,
3180 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003181 output + total_output_length,
3182 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003183 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003184 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003185 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003186 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003187 output + total_output_length,
3188 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003189 &function_output_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_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003192
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003193 ASSERT_COMPARE( expected_output->x, expected_output->len,
3194 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003195
3196exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003197 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003198 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003199 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003200}
3201/* END_CASE */
3202
3203/* BEGIN_CASE */
3204void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003205 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003206 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003207 int first_part_size_arg,
3208 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003209 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003210{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003211 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003212
3213 psa_key_type_t key_type = key_type_arg;
3214 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003215 size_t first_part_size = first_part_size_arg;
3216 size_t output1_length = output1_length_arg;
3217 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003218 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003219 size_t output_buffer_size = 0;
3220 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003221 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003222 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003223 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003224
Gilles Peskine8817f612018-12-18 00:18:46 +01003225 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003226
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003227 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3228 psa_set_key_algorithm( &attributes, alg );
3229 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003230
Gilles Peskine73676cb2019-05-15 20:15:10 +02003231 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003232
Gilles Peskine8817f612018-12-18 00:18:46 +01003233 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3234 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003235
Gilles Peskine423005e2019-05-06 15:22:57 +02003236 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003237
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003238 output_buffer_size = ( (size_t) input->len +
3239 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003240 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003241
Gilles Peskinee0866522019-02-19 19:44:00 +01003242 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003243 PSA_ASSERT( psa_cipher_update( &operation,
3244 input->x, first_part_size,
3245 output, output_buffer_size,
3246 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003247 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003248 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003249 PSA_ASSERT( psa_cipher_update( &operation,
3250 input->x + first_part_size,
3251 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003252 output + total_output_length,
3253 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003254 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003255 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003256 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003257 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003258 output + total_output_length,
3259 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003260 &function_output_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_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003263
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003264 ASSERT_COMPARE( expected_output->x, expected_output->len,
3265 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003266
3267exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003268 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003269 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003270 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003271}
3272/* END_CASE */
3273
Gilles Peskine50e586b2018-06-08 14:28:46 +02003274/* BEGIN_CASE */
3275void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003276 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003277 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003278 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003279{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003280 psa_key_handle_t handle = 0;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003281 psa_status_t status;
3282 psa_key_type_t key_type = key_type_arg;
3283 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003284 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003285 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003286 size_t output_buffer_size = 0;
3287 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003288 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003289 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003290 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003291
Gilles Peskine8817f612018-12-18 00:18:46 +01003292 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003293
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003294 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3295 psa_set_key_algorithm( &attributes, alg );
3296 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003297
Gilles Peskine73676cb2019-05-15 20:15:10 +02003298 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003299
Gilles Peskine8817f612018-12-18 00:18:46 +01003300 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3301 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003302
Gilles Peskine423005e2019-05-06 15:22:57 +02003303 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003304
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003305 output_buffer_size = ( (size_t) input->len +
3306 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003307 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003308
Gilles Peskine8817f612018-12-18 00:18:46 +01003309 PSA_ASSERT( psa_cipher_update( &operation,
3310 input->x, input->len,
3311 output, output_buffer_size,
3312 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003313 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003314 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003315 output + total_output_length,
3316 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003317 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003318 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003319 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003320
3321 if( expected_status == PSA_SUCCESS )
3322 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003323 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003324 ASSERT_COMPARE( expected_output->x, expected_output->len,
3325 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003326 }
3327
Gilles Peskine50e586b2018-06-08 14:28:46 +02003328exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003329 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003330 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003331 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003332}
3333/* END_CASE */
3334
Gilles Peskine50e586b2018-06-08 14:28:46 +02003335/* BEGIN_CASE */
3336void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003337 data_t *key,
3338 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003339{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003340 psa_key_handle_t handle = 0;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003341 psa_key_type_t key_type = key_type_arg;
3342 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003343 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003344 size_t iv_size = 16;
3345 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003346 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003347 size_t output1_size = 0;
3348 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003349 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003350 size_t output2_size = 0;
3351 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003352 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003353 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3354 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003355 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003356
Gilles Peskine8817f612018-12-18 00:18:46 +01003357 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003358
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003359 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3360 psa_set_key_algorithm( &attributes, alg );
3361 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003362
Gilles Peskine73676cb2019-05-15 20:15:10 +02003363 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003364
Gilles Peskine8817f612018-12-18 00:18:46 +01003365 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3366 handle, alg ) );
3367 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3368 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003369
Gilles Peskine8817f612018-12-18 00:18:46 +01003370 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3371 iv, iv_size,
3372 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003373 output1_size = ( (size_t) input->len +
3374 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003375 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003376
Gilles Peskine8817f612018-12-18 00:18:46 +01003377 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3378 output1, output1_size,
3379 &output1_length ) );
3380 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003381 output1 + output1_length,
3382 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003383 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003384
Gilles Peskine048b7f02018-06-08 14:20:49 +02003385 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003386
Gilles Peskine8817f612018-12-18 00:18:46 +01003387 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003388
3389 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003390 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003391
Gilles Peskine8817f612018-12-18 00:18:46 +01003392 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3393 iv, iv_length ) );
3394 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3395 output2, output2_size,
3396 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003397 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003398 PSA_ASSERT( psa_cipher_finish( &operation2,
3399 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003400 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003401 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003402
Gilles Peskine048b7f02018-06-08 14:20:49 +02003403 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003404
Gilles Peskine8817f612018-12-18 00:18:46 +01003405 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003406
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003407 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003408
3409exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003410 mbedtls_free( output1 );
3411 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003412 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003413 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003414}
3415/* END_CASE */
3416
3417/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003418void cipher_verify_output_multipart( int alg_arg,
3419 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003420 data_t *key,
3421 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003422 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003423{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003424 psa_key_handle_t handle = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003425 psa_key_type_t key_type = key_type_arg;
3426 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003427 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003428 unsigned char iv[16] = {0};
3429 size_t iv_size = 16;
3430 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003431 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003432 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003433 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003434 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003435 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003436 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003437 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003438 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3439 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003440 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003441
Gilles Peskine8817f612018-12-18 00:18:46 +01003442 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003443
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003444 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3445 psa_set_key_algorithm( &attributes, alg );
3446 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003447
Gilles Peskine73676cb2019-05-15 20:15:10 +02003448 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003449
Gilles Peskine8817f612018-12-18 00:18:46 +01003450 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3451 handle, alg ) );
3452 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3453 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003454
Gilles Peskine8817f612018-12-18 00:18:46 +01003455 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3456 iv, iv_size,
3457 &iv_length ) );
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003458 output1_buffer_size = ( (size_t) input->len +
3459 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003460 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003461
Gilles Peskinee0866522019-02-19 19:44:00 +01003462 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003463
Gilles Peskine8817f612018-12-18 00:18:46 +01003464 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3465 output1, output1_buffer_size,
3466 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003467 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003468
Gilles Peskine8817f612018-12-18 00:18:46 +01003469 PSA_ASSERT( psa_cipher_update( &operation1,
3470 input->x + first_part_size,
3471 input->len - first_part_size,
3472 output1, output1_buffer_size,
3473 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003474 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003475
Gilles Peskine8817f612018-12-18 00:18:46 +01003476 PSA_ASSERT( psa_cipher_finish( &operation1,
3477 output1 + output1_length,
3478 output1_buffer_size - output1_length,
3479 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003480 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003481
Gilles Peskine8817f612018-12-18 00:18:46 +01003482 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003483
Gilles Peskine048b7f02018-06-08 14:20:49 +02003484 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003485 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003486
Gilles Peskine8817f612018-12-18 00:18:46 +01003487 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3488 iv, iv_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003489
Gilles Peskine8817f612018-12-18 00:18:46 +01003490 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3491 output2, output2_buffer_size,
3492 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003493 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003494
Gilles Peskine8817f612018-12-18 00:18:46 +01003495 PSA_ASSERT( psa_cipher_update( &operation2,
3496 output1 + first_part_size,
3497 output1_length - first_part_size,
3498 output2, output2_buffer_size,
3499 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003500 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003501
Gilles Peskine8817f612018-12-18 00:18:46 +01003502 PSA_ASSERT( psa_cipher_finish( &operation2,
3503 output2 + output2_length,
3504 output2_buffer_size - output2_length,
3505 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003506 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003507
Gilles Peskine8817f612018-12-18 00:18:46 +01003508 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003509
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003510 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003511
3512exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03003513 mbedtls_free( output1 );
3514 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003515 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003516 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003517}
3518/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003519
Gilles Peskine20035e32018-02-03 22:44:14 +01003520/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003521void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003522 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003523 data_t *nonce,
3524 data_t *additional_data,
3525 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003526 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003527{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003528 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003529 psa_key_type_t key_type = key_type_arg;
3530 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003531 unsigned char *output_data = NULL;
3532 size_t output_size = 0;
3533 size_t output_length = 0;
3534 unsigned char *output_data2 = NULL;
3535 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003536 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003537 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003538 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003539
Gilles Peskine4abf7412018-06-18 16:35:34 +02003540 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003541 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3542 * should be exact. */
3543 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3544 TEST_EQUAL( output_size,
3545 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003546 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003547
Gilles Peskine8817f612018-12-18 00:18:46 +01003548 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003549
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003550 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3551 psa_set_key_algorithm( &attributes, alg );
3552 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003553
Gilles Peskine049c7532019-05-15 20:22:09 +02003554 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3555 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003556
Gilles Peskinefe11b722018-12-18 00:24:04 +01003557 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3558 nonce->x, nonce->len,
3559 additional_data->x,
3560 additional_data->len,
3561 input_data->x, input_data->len,
3562 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003563 &output_length ),
3564 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003565
3566 if( PSA_SUCCESS == expected_result )
3567 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003568 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003569
Gilles Peskine003a4a92019-05-14 16:09:40 +02003570 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3571 * should be exact. */
3572 TEST_EQUAL( input_data->len,
3573 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3574
Gilles Peskinefe11b722018-12-18 00:24:04 +01003575 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3576 nonce->x, nonce->len,
3577 additional_data->x,
3578 additional_data->len,
3579 output_data, output_length,
3580 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003581 &output_length2 ),
3582 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003583
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003584 ASSERT_COMPARE( input_data->x, input_data->len,
3585 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003586 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003587
Gilles Peskinea1cac842018-06-11 19:33:02 +02003588exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003589 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003590 mbedtls_free( output_data );
3591 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003592 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003593}
3594/* END_CASE */
3595
3596/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003597void aead_encrypt( int key_type_arg, data_t *key_data,
3598 int alg_arg,
3599 data_t *nonce,
3600 data_t *additional_data,
3601 data_t *input_data,
3602 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003603{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003604 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003605 psa_key_type_t key_type = key_type_arg;
3606 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003607 unsigned char *output_data = NULL;
3608 size_t output_size = 0;
3609 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003610 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003611 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003612
Gilles Peskine4abf7412018-06-18 16:35:34 +02003613 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003614 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3615 * should be exact. */
3616 TEST_EQUAL( output_size,
3617 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003618 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003619
Gilles Peskine8817f612018-12-18 00:18:46 +01003620 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003621
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003622 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3623 psa_set_key_algorithm( &attributes, alg );
3624 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003625
Gilles Peskine049c7532019-05-15 20:22:09 +02003626 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3627 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003628
Gilles Peskine8817f612018-12-18 00:18:46 +01003629 PSA_ASSERT( psa_aead_encrypt( handle, alg,
3630 nonce->x, nonce->len,
3631 additional_data->x, additional_data->len,
3632 input_data->x, input_data->len,
3633 output_data, output_size,
3634 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003635
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003636 ASSERT_COMPARE( expected_result->x, expected_result->len,
3637 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02003638
Gilles Peskinea1cac842018-06-11 19:33:02 +02003639exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003640 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003641 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003642 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003643}
3644/* END_CASE */
3645
3646/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003647void aead_decrypt( int key_type_arg, data_t *key_data,
3648 int alg_arg,
3649 data_t *nonce,
3650 data_t *additional_data,
3651 data_t *input_data,
3652 data_t *expected_data,
3653 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003654{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003655 psa_key_handle_t handle = 0;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003656 psa_key_type_t key_type = key_type_arg;
3657 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003658 unsigned char *output_data = NULL;
3659 size_t output_size = 0;
3660 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003661 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003662 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02003663 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003664
Gilles Peskine003a4a92019-05-14 16:09:40 +02003665 output_size = input_data->len - tag_length;
3666 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3667 * should be exact. */
3668 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3669 TEST_EQUAL( output_size,
3670 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003671 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003672
Gilles Peskine8817f612018-12-18 00:18:46 +01003673 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003674
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003675 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3676 psa_set_key_algorithm( &attributes, alg );
3677 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003678
Gilles Peskine049c7532019-05-15 20:22:09 +02003679 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3680 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003681
Gilles Peskinefe11b722018-12-18 00:24:04 +01003682 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3683 nonce->x, nonce->len,
3684 additional_data->x,
3685 additional_data->len,
3686 input_data->x, input_data->len,
3687 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003688 &output_length ),
3689 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003690
Gilles Peskine2d277862018-06-18 15:41:12 +02003691 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003692 ASSERT_COMPARE( expected_data->x, expected_data->len,
3693 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003694
Gilles Peskinea1cac842018-06-11 19:33:02 +02003695exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003696 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003697 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003698 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003699}
3700/* END_CASE */
3701
3702/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003703void signature_size( int type_arg,
3704 int bits,
3705 int alg_arg,
3706 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003707{
3708 psa_key_type_t type = type_arg;
3709 psa_algorithm_t alg = alg_arg;
Gilles Peskine2d277862018-06-18 15:41:12 +02003710 size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003711 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003712exit:
3713 ;
3714}
3715/* END_CASE */
3716
3717/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003718void sign_deterministic( int key_type_arg, data_t *key_data,
3719 int alg_arg, data_t *input_data,
3720 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01003721{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003722 psa_key_handle_t handle = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01003723 psa_key_type_t key_type = key_type_arg;
3724 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003725 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01003726 unsigned char *signature = NULL;
3727 size_t signature_size;
3728 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003729 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003730
Gilles Peskine8817f612018-12-18 00:18:46 +01003731 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003732
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003733 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3734 psa_set_key_algorithm( &attributes, alg );
3735 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003736
Gilles Peskine049c7532019-05-15 20:22:09 +02003737 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3738 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003739 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3740 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01003741
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003742 /* Allocate a buffer which has the size advertized by the
3743 * library. */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003744 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3745 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01003746 TEST_ASSERT( signature_size != 0 );
Gilles Peskine69c12672018-06-28 00:07:19 +02003747 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003748 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003749
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003750 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003751 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3752 input_data->x, input_data->len,
3753 signature, signature_size,
3754 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003755 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003756 ASSERT_COMPARE( output_data->x, output_data->len,
3757 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003758
3759exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003760 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003761 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01003762 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003763 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003764}
3765/* END_CASE */
3766
3767/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003768void sign_fail( int key_type_arg, data_t *key_data,
3769 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003770 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01003771{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003772 psa_key_handle_t handle = 0;
Gilles Peskine20035e32018-02-03 22:44:14 +01003773 psa_key_type_t key_type = key_type_arg;
3774 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003775 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01003776 psa_status_t actual_status;
3777 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01003778 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01003779 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003780 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01003781
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003782 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003783
Gilles Peskine8817f612018-12-18 00:18:46 +01003784 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003785
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003786 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
3787 psa_set_key_algorithm( &attributes, alg );
3788 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07003789
Gilles Peskine049c7532019-05-15 20:22:09 +02003790 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3791 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01003792
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003793 actual_status = psa_asymmetric_sign( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003794 input_data->x, input_data->len,
Gilles Peskine20035e32018-02-03 22:44:14 +01003795 signature, signature_size,
3796 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003797 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02003798 /* The value of *signature_length is unspecified on error, but
3799 * whatever it is, it should be less than signature_size, so that
3800 * if the caller tries to read *signature_length bytes without
3801 * checking the error code then they don't overflow a buffer. */
3802 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01003803
3804exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003805 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003806 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01003807 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003808 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01003809}
3810/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03003811
3812/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02003813void sign_verify( int key_type_arg, data_t *key_data,
3814 int alg_arg, data_t *input_data )
3815{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003816 psa_key_handle_t handle = 0;
Gilles Peskine9911b022018-06-29 17:30:48 +02003817 psa_key_type_t key_type = key_type_arg;
3818 psa_algorithm_t alg = alg_arg;
3819 size_t key_bits;
3820 unsigned char *signature = NULL;
3821 size_t signature_size;
3822 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003823 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02003824
Gilles Peskine8817f612018-12-18 00:18:46 +01003825 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003826
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003827 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY );
3828 psa_set_key_algorithm( &attributes, alg );
3829 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02003830
Gilles Peskine049c7532019-05-15 20:22:09 +02003831 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3832 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003833 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3834 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02003835
3836 /* Allocate a buffer which has the size advertized by the
3837 * library. */
3838 signature_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type,
3839 key_bits, alg );
3840 TEST_ASSERT( signature_size != 0 );
3841 TEST_ASSERT( signature_size <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003842 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02003843
3844 /* Perform the signature. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003845 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
3846 input_data->x, input_data->len,
3847 signature, signature_size,
3848 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003849 /* Check that the signature length looks sensible. */
3850 TEST_ASSERT( signature_length <= signature_size );
3851 TEST_ASSERT( signature_length > 0 );
3852
3853 /* Use the library to verify that the signature is correct. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003854 PSA_ASSERT( psa_asymmetric_verify(
3855 handle, alg,
3856 input_data->x, input_data->len,
3857 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02003858
3859 if( input_data->len != 0 )
3860 {
3861 /* Flip a bit in the input and verify that the signature is now
3862 * detected as invalid. Flip a bit at the beginning, not at the end,
3863 * because ECDSA may ignore the last few bits of the input. */
3864 input_data->x[0] ^= 1;
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003865 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
3866 input_data->x, input_data->len,
3867 signature, signature_length ),
3868 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02003869 }
3870
3871exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003872 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003873 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02003874 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003875 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02003876}
3877/* END_CASE */
3878
3879/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003880void asymmetric_verify( int key_type_arg, data_t *key_data,
3881 int alg_arg, data_t *hash_data,
3882 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03003883{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003884 psa_key_handle_t handle = 0;
itayzafrir5c753392018-05-08 11:18:38 +03003885 psa_key_type_t key_type = key_type_arg;
3886 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003887 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03003888
Gilles Peskine69c12672018-06-28 00:07:19 +02003889 TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
3890
Gilles Peskine8817f612018-12-18 00:18:46 +01003891 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03003892
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003893 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3894 psa_set_key_algorithm( &attributes, alg );
3895 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03003896
Gilles Peskine049c7532019-05-15 20:22:09 +02003897 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3898 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03003899
Gilles Peskine8817f612018-12-18 00:18:46 +01003900 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
3901 hash_data->x, hash_data->len,
3902 signature_data->x,
3903 signature_data->len ) );
itayzafrir5c753392018-05-08 11:18:38 +03003904exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003905 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003906 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003907 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03003908}
3909/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003910
3911/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03003912void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
3913 int alg_arg, data_t *hash_data,
3914 data_t *signature_data,
3915 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003916{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003917 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003918 psa_key_type_t key_type = key_type_arg;
3919 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003920 psa_status_t actual_status;
3921 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003922 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003923
Gilles Peskine8817f612018-12-18 00:18:46 +01003924 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003925
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003926 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
3927 psa_set_key_algorithm( &attributes, alg );
3928 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03003929
Gilles Peskine049c7532019-05-15 20:22:09 +02003930 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3931 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003932
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003933 actual_status = psa_asymmetric_verify( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003934 hash_data->x, hash_data->len,
Gilles Peskine2d277862018-06-18 15:41:12 +02003935 signature_data->x,
Gilles Peskine4abf7412018-06-18 16:35:34 +02003936 signature_data->len );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003937
Gilles Peskinefe11b722018-12-18 00:24:04 +01003938 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003939
3940exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02003941 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003942 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003943 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003944}
3945/* END_CASE */
3946
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003947/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02003948void asymmetric_encrypt( int key_type_arg,
3949 data_t *key_data,
3950 int alg_arg,
3951 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02003952 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02003953 int expected_output_length_arg,
3954 int expected_status_arg )
3955{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003956 psa_key_handle_t handle = 0;
Gilles Peskine656896e2018-06-29 19:12:28 +02003957 psa_key_type_t key_type = key_type_arg;
3958 psa_algorithm_t alg = alg_arg;
3959 size_t expected_output_length = expected_output_length_arg;
3960 size_t key_bits;
3961 unsigned char *output = NULL;
3962 size_t output_size;
3963 size_t output_length = ~0;
3964 psa_status_t actual_status;
3965 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003966 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02003967
Gilles Peskine8817f612018-12-18 00:18:46 +01003968 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003969
Gilles Peskine656896e2018-06-29 19:12:28 +02003970 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003971 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3972 psa_set_key_algorithm( &attributes, alg );
3973 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02003974 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3975 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02003976
3977 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02003978 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
3979 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02003980 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003981 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02003982
3983 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003984 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02003985 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02003986 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02003987 output, output_size,
3988 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01003989 TEST_EQUAL( actual_status, expected_status );
3990 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02003991
Gilles Peskine68428122018-06-30 18:42:41 +02003992 /* If the label is empty, the test framework puts a non-null pointer
3993 * in label->x. Test that a null pointer works as well. */
3994 if( label->len == 0 )
3995 {
3996 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02003997 if( output_size != 0 )
3998 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003999 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004000 input_data->x, input_data->len,
4001 NULL, label->len,
4002 output, output_size,
4003 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004004 TEST_EQUAL( actual_status, expected_status );
4005 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004006 }
4007
Gilles Peskine656896e2018-06-29 19:12:28 +02004008exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004009 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004010 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02004011 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004012 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02004013}
4014/* END_CASE */
4015
4016/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004017void asymmetric_encrypt_decrypt( int key_type_arg,
4018 data_t *key_data,
4019 int alg_arg,
4020 data_t *input_data,
4021 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004022{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004023 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004024 psa_key_type_t key_type = key_type_arg;
4025 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004026 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004027 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004028 size_t output_size;
4029 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03004030 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004031 size_t output2_size;
4032 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004033 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004034
Gilles Peskine8817f612018-12-18 00:18:46 +01004035 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004036
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004037 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
4038 psa_set_key_algorithm( &attributes, alg );
4039 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004040
Gilles Peskine049c7532019-05-15 20:22:09 +02004041 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4042 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004043
4044 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004045 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4046 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004047 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004048 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004049 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004050 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004051
Gilles Peskineeebd7382018-06-08 18:11:54 +02004052 /* We test encryption by checking that encrypt-then-decrypt gives back
4053 * the original plaintext because of the non-optional random
4054 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004055 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
4056 input_data->x, input_data->len,
4057 label->x, label->len,
4058 output, output_size,
4059 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004060 /* We don't know what ciphertext length to expect, but check that
4061 * it looks sensible. */
4062 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03004063
Gilles Peskine8817f612018-12-18 00:18:46 +01004064 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4065 output, output_length,
4066 label->x, label->len,
4067 output2, output2_size,
4068 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004069 ASSERT_COMPARE( input_data->x, input_data->len,
4070 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004071
4072exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004073 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004074 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004075 mbedtls_free( output );
4076 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004077 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004078}
4079/* END_CASE */
4080
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004081/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004082void asymmetric_decrypt( int key_type_arg,
4083 data_t *key_data,
4084 int alg_arg,
4085 data_t *input_data,
4086 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02004087 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004088{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004089 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004090 psa_key_type_t key_type = key_type_arg;
4091 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004092 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03004093 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004094 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004095 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004096
Jaeden Amero412654a2019-02-06 12:57:46 +00004097 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004098 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004099
Gilles Peskine8817f612018-12-18 00:18:46 +01004100 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004101
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004102 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4103 psa_set_key_algorithm( &attributes, alg );
4104 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004105
Gilles Peskine049c7532019-05-15 20:22:09 +02004106 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4107 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004108
Gilles Peskine8817f612018-12-18 00:18:46 +01004109 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4110 input_data->x, input_data->len,
4111 label->x, label->len,
4112 output,
4113 output_size,
4114 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004115 ASSERT_COMPARE( expected_data->x, expected_data->len,
4116 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004117
Gilles Peskine68428122018-06-30 18:42:41 +02004118 /* If the label is empty, the test framework puts a non-null pointer
4119 * in label->x. Test that a null pointer works as well. */
4120 if( label->len == 0 )
4121 {
4122 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004123 if( output_size != 0 )
4124 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004125 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4126 input_data->x, input_data->len,
4127 NULL, label->len,
4128 output,
4129 output_size,
4130 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004131 ASSERT_COMPARE( expected_data->x, expected_data->len,
4132 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004133 }
4134
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004135exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004136 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004137 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004138 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004139 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004140}
4141/* END_CASE */
4142
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004143/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004144void asymmetric_decrypt_fail( int key_type_arg,
4145 data_t *key_data,
4146 int alg_arg,
4147 data_t *input_data,
4148 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00004149 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02004150 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004151{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004152 psa_key_handle_t handle = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004153 psa_key_type_t key_type = key_type_arg;
4154 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004155 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004156 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004157 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004158 psa_status_t actual_status;
4159 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004160 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004161
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004162 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004163
Gilles Peskine8817f612018-12-18 00:18:46 +01004164 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004165
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004166 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4167 psa_set_key_algorithm( &attributes, alg );
4168 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004169
Gilles Peskine049c7532019-05-15 20:22:09 +02004170 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4171 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004172
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004173 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004174 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004175 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004176 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004177 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004178 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004179 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004180
Gilles Peskine68428122018-06-30 18:42:41 +02004181 /* If the label is empty, the test framework puts a non-null pointer
4182 * in label->x. Test that a null pointer works as well. */
4183 if( label->len == 0 )
4184 {
4185 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004186 if( output_size != 0 )
4187 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004188 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004189 input_data->x, input_data->len,
4190 NULL, label->len,
4191 output, output_size,
4192 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004193 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004194 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004195 }
4196
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004197exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004198 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004199 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004200 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004201 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004202}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004203/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004204
4205/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004206void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004207{
4208 /* Test each valid way of initializing the object, except for `= {0}`, as
4209 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4210 * though it's OK by the C standard. We could test for this, but we'd need
4211 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004212 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004213 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4214 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4215 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004216
4217 memset( &zero, 0, sizeof( zero ) );
4218
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004219 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004220 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004221 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004222 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004223 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004224 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004225 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004226
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004227 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004228 PSA_ASSERT( psa_key_derivation_abort(&func) );
4229 PSA_ASSERT( psa_key_derivation_abort(&init) );
4230 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004231}
4232/* END_CASE */
4233
Janos Follath16de4a42019-06-13 16:32:24 +01004234/* BEGIN_CASE */
4235void derive_setup( int alg_arg, int expected_status_arg )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004236{
Gilles Peskineea0fb492018-07-12 17:17:20 +02004237 psa_algorithm_t alg = alg_arg;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004238 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004239 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004240
Gilles Peskine8817f612018-12-18 00:18:46 +01004241 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004242
Janos Follath16de4a42019-06-13 16:32:24 +01004243 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004244 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004245
4246exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004247 psa_key_derivation_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004248 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004249}
4250/* END_CASE */
4251
Janos Follathaf3c2a02019-06-12 12:34:34 +01004252/* BEGIN_CASE */
Janos Follatha27c9272019-06-14 09:59:36 +01004253void derive_set_capacity( int alg_arg, int capacity_arg,
4254 int expected_status_arg )
4255{
4256 psa_algorithm_t alg = alg_arg;
4257 size_t capacity = capacity_arg;
4258 psa_status_t expected_status = expected_status_arg;
4259 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4260
4261 PSA_ASSERT( psa_crypto_init( ) );
4262
4263 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4264
4265 TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
4266 expected_status );
4267
4268exit:
4269 psa_key_derivation_abort( &operation );
4270 PSA_DONE( );
4271}
4272/* END_CASE */
4273
4274/* BEGIN_CASE */
Janos Follathaf3c2a02019-06-12 12:34:34 +01004275void derive_input( int alg_arg,
Gilles Peskine6842ba42019-09-23 13:49:33 +02004276 int step_arg1, int key_type_arg1, data_t *input1,
4277 int step_arg2, int key_type_arg2, data_t *input2,
4278 int step_arg3, int key_type_arg3, data_t *input3,
Janos Follathaf3c2a02019-06-12 12:34:34 +01004279 int expected_status_arg1,
4280 int expected_status_arg2,
4281 int expected_status_arg3 )
4282{
4283 psa_algorithm_t alg = alg_arg;
Gilles Peskine6842ba42019-09-23 13:49:33 +02004284 psa_key_derivation_step_t steps[] = {step_arg1, step_arg2, step_arg3};
4285 psa_key_type_t key_types[] = {key_type_arg1, key_type_arg2, key_type_arg3};
Janos Follathaf3c2a02019-06-12 12:34:34 +01004286 psa_status_t expected_statuses[] = {expected_status_arg1,
4287 expected_status_arg2,
4288 expected_status_arg3};
4289 data_t *inputs[] = {input1, input2, input3};
4290 psa_key_handle_t handles[] = {0, 0, 0};
4291 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4292 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4293 size_t i;
4294
4295 PSA_ASSERT( psa_crypto_init( ) );
4296
4297 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4298 psa_set_key_algorithm( &attributes, alg );
Janos Follathaf3c2a02019-06-12 12:34:34 +01004299
4300 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4301
4302 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
4303 {
Gilles Peskine6842ba42019-09-23 13:49:33 +02004304 if( key_types[i] != 0 )
Janos Follathaf3c2a02019-06-12 12:34:34 +01004305 {
Gilles Peskine6842ba42019-09-23 13:49:33 +02004306 psa_set_key_type( &attributes, key_types[i] );
4307 PSA_ASSERT( psa_import_key( &attributes,
4308 inputs[i]->x, inputs[i]->len,
4309 &handles[i] ) );
4310 TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
4311 handles[i] ),
4312 expected_statuses[i] );
4313 }
4314 else
4315 {
4316 TEST_EQUAL( psa_key_derivation_input_bytes(
4317 &operation, steps[i],
4318 inputs[i]->x, inputs[i]->len ),
4319 expected_statuses[i] );
Janos Follathaf3c2a02019-06-12 12:34:34 +01004320 }
4321 }
4322
4323exit:
4324 psa_key_derivation_abort( &operation );
4325 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4326 psa_destroy_key( handles[i] );
4327 PSA_DONE( );
4328}
4329/* END_CASE */
4330
Janos Follathd958bb72019-07-03 15:02:16 +01004331/* BEGIN_CASE */
4332void test_derive_invalid_key_derivation_state( int alg_arg )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004333{
Janos Follathd958bb72019-07-03 15:02:16 +01004334 psa_algorithm_t alg = alg_arg;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004335 psa_key_handle_t handle = 0;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004336 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004337 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathd958bb72019-07-03 15:02:16 +01004338 unsigned char input1[] = "Input 1";
4339 size_t input1_length = sizeof( input1 );
4340 unsigned char input2[] = "Input 2";
4341 size_t input2_length = sizeof( input2 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004342 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004343 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004344 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4345 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4346 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004347 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004348
Gilles Peskine8817f612018-12-18 00:18:46 +01004349 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004350
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004351 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4352 psa_set_key_algorithm( &attributes, alg );
4353 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004354
Gilles Peskine73676cb2019-05-15 20:15:10 +02004355 PSA_ASSERT( psa_import_key( &attributes,
4356 key_data, sizeof( key_data ),
4357 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004358
4359 /* valid key derivation */
Janos Follathd958bb72019-07-03 15:02:16 +01004360 if( !setup_key_derivation_wrap( &operation, handle, alg,
4361 input1, input1_length,
4362 input2, input2_length,
4363 capacity ) )
4364 goto exit;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004365
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004366 /* state of operation shouldn't allow additional generation */
Janos Follathd958bb72019-07-03 15:02:16 +01004367 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004368 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004369
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004370 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004371
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004372 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004373 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004374
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004375exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004376 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004377 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004378 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004379}
4380/* END_CASE */
4381
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004382/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004383void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004384{
4385 uint8_t output_buffer[16];
4386 size_t buffer_size = 16;
4387 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004388 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004389
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004390 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4391 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004392 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004393
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004394 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004395 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004396
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004397 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004398
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004399 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4400 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004401 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004402
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004403 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004404 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004405
4406exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004407 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004408}
4409/* END_CASE */
4410
4411/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004412void derive_output( int alg_arg,
Gilles Peskine1468da72019-05-29 17:35:49 +02004413 int step1_arg, data_t *input1,
4414 int step2_arg, data_t *input2,
4415 int step3_arg, data_t *input3,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004416 int requested_capacity_arg,
4417 data_t *expected_output1,
4418 data_t *expected_output2 )
4419{
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004420 psa_algorithm_t alg = alg_arg;
Gilles Peskine1468da72019-05-29 17:35:49 +02004421 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4422 data_t *inputs[] = {input1, input2, input3};
4423 psa_key_handle_t handles[] = {0, 0, 0};
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004424 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004425 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004426 uint8_t *expected_outputs[2] =
4427 {expected_output1->x, expected_output2->x};
4428 size_t output_sizes[2] =
4429 {expected_output1->len, expected_output2->len};
4430 size_t output_buffer_size = 0;
4431 uint8_t *output_buffer = NULL;
4432 size_t expected_capacity;
4433 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004434 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004435 psa_status_t status;
Gilles Peskine1468da72019-05-29 17:35:49 +02004436 size_t i;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004437
4438 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4439 {
4440 if( output_sizes[i] > output_buffer_size )
4441 output_buffer_size = output_sizes[i];
4442 if( output_sizes[i] == 0 )
4443 expected_outputs[i] = NULL;
4444 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004445 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004446 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004447
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004448 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4449 psa_set_key_algorithm( &attributes, alg );
4450 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004451
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004452 /* Extraction phase. */
Gilles Peskine1468da72019-05-29 17:35:49 +02004453 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4454 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4455 requested_capacity ) );
4456 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004457 {
Gilles Peskine1468da72019-05-29 17:35:49 +02004458 switch( steps[i] )
4459 {
4460 case 0:
4461 break;
4462 case PSA_KEY_DERIVATION_INPUT_SECRET:
4463 PSA_ASSERT( psa_import_key( &attributes,
4464 inputs[i]->x, inputs[i]->len,
4465 &handles[i] ) );
4466 PSA_ASSERT( psa_key_derivation_input_key(
4467 &operation, steps[i],
4468 handles[i] ) );
4469 break;
4470 default:
4471 PSA_ASSERT( psa_key_derivation_input_bytes(
4472 &operation, steps[i],
4473 inputs[i]->x, inputs[i]->len ) );
4474 break;
4475 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004476 }
Gilles Peskine1468da72019-05-29 17:35:49 +02004477
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004478 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004479 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004480 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004481 expected_capacity = requested_capacity;
4482
4483 /* Expansion phase. */
4484 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4485 {
4486 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004487 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004488 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004489 if( expected_capacity == 0 && output_sizes[i] == 0 )
4490 {
4491 /* Reading 0 bytes when 0 bytes are available can go either way. */
4492 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004493 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004494 continue;
4495 }
4496 else if( expected_capacity == 0 ||
4497 output_sizes[i] > expected_capacity )
4498 {
4499 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004500 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004501 expected_capacity = 0;
4502 continue;
4503 }
4504 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004505 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004506 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004507 ASSERT_COMPARE( output_buffer, output_sizes[i],
4508 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004509 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004510 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004511 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004512 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004513 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004514 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004515 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004516
4517exit:
4518 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004519 psa_key_derivation_abort( &operation );
Gilles Peskine1468da72019-05-29 17:35:49 +02004520 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4521 psa_destroy_key( handles[i] );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004522 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004523}
4524/* END_CASE */
4525
4526/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004527void derive_full( int alg_arg,
4528 data_t *key_data,
Janos Follath47f27ed2019-06-25 13:24:52 +01004529 data_t *input1,
4530 data_t *input2,
Gilles Peskined54931c2018-07-17 21:06:59 +02004531 int requested_capacity_arg )
4532{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004533 psa_key_handle_t handle = 0;
Gilles Peskined54931c2018-07-17 21:06:59 +02004534 psa_algorithm_t alg = alg_arg;
4535 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004536 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004537 unsigned char output_buffer[16];
4538 size_t expected_capacity = requested_capacity;
4539 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004540 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004541
Gilles Peskine8817f612018-12-18 00:18:46 +01004542 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004543
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004544 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4545 psa_set_key_algorithm( &attributes, alg );
4546 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02004547
Gilles Peskine049c7532019-05-15 20:22:09 +02004548 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4549 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004550
Janos Follathf2815ea2019-07-03 12:41:36 +01004551 if( !setup_key_derivation_wrap( &operation, handle, alg,
4552 input1->x, input1->len,
4553 input2->x, input2->len,
4554 requested_capacity ) )
4555 goto exit;
Janos Follath47f27ed2019-06-25 13:24:52 +01004556
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004557 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004558 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004559 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004560
4561 /* Expansion phase. */
4562 while( current_capacity > 0 )
4563 {
4564 size_t read_size = sizeof( output_buffer );
4565 if( read_size > current_capacity )
4566 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004567 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004568 output_buffer,
4569 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004570 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004571 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004572 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004573 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02004574 }
4575
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004576 /* Check that the operation refuses to go over capacity. */
4577 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004578 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02004579
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004580 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02004581
4582exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004583 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004584 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004585 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02004586}
4587/* END_CASE */
4588
Janos Follathe60c9052019-07-03 13:51:30 +01004589/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004590void derive_key_exercise( int alg_arg,
4591 data_t *key_data,
Janos Follathe60c9052019-07-03 13:51:30 +01004592 data_t *input1,
4593 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004594 int derived_type_arg,
4595 int derived_bits_arg,
4596 int derived_usage_arg,
4597 int derived_alg_arg )
4598{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004599 psa_key_handle_t base_handle = 0;
4600 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004601 psa_algorithm_t alg = alg_arg;
4602 psa_key_type_t derived_type = derived_type_arg;
4603 size_t derived_bits = derived_bits_arg;
4604 psa_key_usage_t derived_usage = derived_usage_arg;
4605 psa_algorithm_t derived_alg = derived_alg_arg;
4606 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004607 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004608 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004609 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004610
Gilles Peskine8817f612018-12-18 00:18:46 +01004611 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004612
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004613 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4614 psa_set_key_algorithm( &attributes, alg );
4615 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004616 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4617 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004618
4619 /* Derive a key. */
Janos Follathe60c9052019-07-03 13:51:30 +01004620 if ( setup_key_derivation_wrap( &operation, base_handle, alg,
4621 input1->x, input1->len,
4622 input2->x, input2->len, capacity ) )
4623 goto exit;
4624
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004625 psa_set_key_usage_flags( &attributes, derived_usage );
4626 psa_set_key_algorithm( &attributes, derived_alg );
4627 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004628 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004629 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004630 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004631
4632 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004633 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
4634 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
4635 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004636
4637 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004638 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02004639 goto exit;
4640
4641exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004642 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004643 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004644 psa_destroy_key( base_handle );
4645 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004646 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004647}
4648/* END_CASE */
4649
Janos Follath42fd8882019-07-03 14:17:09 +01004650/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02004651void derive_key_export( int alg_arg,
4652 data_t *key_data,
Janos Follath42fd8882019-07-03 14:17:09 +01004653 data_t *input1,
4654 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02004655 int bytes1_arg,
4656 int bytes2_arg )
4657{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004658 psa_key_handle_t base_handle = 0;
4659 psa_key_handle_t derived_handle = 0;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004660 psa_algorithm_t alg = alg_arg;
4661 size_t bytes1 = bytes1_arg;
4662 size_t bytes2 = bytes2_arg;
4663 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004664 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004665 uint8_t *output_buffer = NULL;
4666 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004667 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4668 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02004669 size_t length;
4670
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004671 ASSERT_ALLOC( output_buffer, capacity );
4672 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01004673 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004674
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004675 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4676 psa_set_key_algorithm( &base_attributes, alg );
4677 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02004678 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4679 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004680
4681 /* Derive some material and output it. */
Janos Follath42fd8882019-07-03 14:17:09 +01004682 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4683 input1->x, input1->len,
4684 input2->x, input2->len, capacity ) )
4685 goto exit;
4686
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004687 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004688 output_buffer,
4689 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004690 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004691
4692 /* Derive the same output again, but this time store it in key objects. */
Janos Follath42fd8882019-07-03 14:17:09 +01004693 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4694 input1->x, input1->len,
4695 input2->x, input2->len, capacity ) )
4696 goto exit;
4697
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004698 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4699 psa_set_key_algorithm( &derived_attributes, 0 );
4700 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004701 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004702 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004703 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004704 PSA_ASSERT( psa_export_key( derived_handle,
4705 export_buffer, bytes1,
4706 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004707 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01004708 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02004709 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004710 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004711 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01004712 PSA_ASSERT( psa_export_key( derived_handle,
4713 export_buffer + bytes1, bytes2,
4714 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004715 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004716
4717 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004718 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
4719 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004720
4721exit:
4722 mbedtls_free( output_buffer );
4723 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004724 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004725 psa_destroy_key( base_handle );
4726 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004727 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02004728}
4729/* END_CASE */
4730
4731/* BEGIN_CASE */
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004732void derive_key( int alg_arg,
4733 data_t *key_data, data_t *input1, data_t *input2,
4734 int type_arg, int bits_arg,
4735 int expected_status_arg )
Gilles Peskinec744d992019-07-30 17:26:54 +02004736{
4737 psa_key_handle_t base_handle = 0;
4738 psa_key_handle_t derived_handle = 0;
4739 psa_algorithm_t alg = alg_arg;
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004740 psa_key_type_t type = type_arg;
Gilles Peskinec744d992019-07-30 17:26:54 +02004741 size_t bits = bits_arg;
4742 psa_status_t expected_status = expected_status_arg;
4743 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4744 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
4745 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
4746
4747 PSA_ASSERT( psa_crypto_init( ) );
4748
4749 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
4750 psa_set_key_algorithm( &base_attributes, alg );
4751 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
4752 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
4753 &base_handle ) );
4754
4755 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
4756 input1->x, input1->len,
4757 input2->x, input2->len, SIZE_MAX ) )
4758 goto exit;
4759
4760 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
4761 psa_set_key_algorithm( &derived_attributes, 0 );
Gilles Peskine7c227ae2019-07-31 15:14:44 +02004762 psa_set_key_type( &derived_attributes, type );
Gilles Peskinec744d992019-07-30 17:26:54 +02004763 psa_set_key_bits( &derived_attributes, bits );
4764 TEST_EQUAL( psa_key_derivation_output_key( &derived_attributes, &operation,
4765 &derived_handle ),
4766 expected_status );
4767
4768exit:
4769 psa_key_derivation_abort( &operation );
4770 psa_destroy_key( base_handle );
4771 psa_destroy_key( derived_handle );
4772 PSA_DONE( );
4773}
4774/* END_CASE */
4775
4776/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004777void key_agreement_setup( int alg_arg,
4778 int our_key_type_arg, data_t *our_key_data,
4779 data_t *peer_key_data,
4780 int expected_status_arg )
4781{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004782 psa_key_handle_t our_key = 0;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004783 psa_algorithm_t alg = alg_arg;
4784 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004785 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004786 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02004787 psa_status_t expected_status = expected_status_arg;
4788 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004789
Gilles Peskine8817f612018-12-18 00:18:46 +01004790 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004791
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004792 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4793 psa_set_key_algorithm( &attributes, alg );
4794 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004795 PSA_ASSERT( psa_import_key( &attributes,
4796 our_key_data->x, our_key_data->len,
4797 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004798
Gilles Peskine77f40d82019-04-11 21:27:06 +02004799 /* The tests currently include inputs that should fail at either step.
4800 * Test cases that fail at the setup step should be changed to call
4801 * key_derivation_setup instead, and this function should be renamed
4802 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004803 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02004804 if( status == PSA_SUCCESS )
4805 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004806 TEST_EQUAL( psa_key_derivation_key_agreement(
4807 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
4808 our_key,
4809 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02004810 expected_status );
4811 }
4812 else
4813 {
4814 TEST_ASSERT( status == expected_status );
4815 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02004816
4817exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004818 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004819 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004820 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004821}
4822/* END_CASE */
4823
4824/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02004825void raw_key_agreement( int alg_arg,
4826 int our_key_type_arg, data_t *our_key_data,
4827 data_t *peer_key_data,
4828 data_t *expected_output )
4829{
4830 psa_key_handle_t our_key = 0;
4831 psa_algorithm_t alg = alg_arg;
4832 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004833 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02004834 unsigned char *output = NULL;
4835 size_t output_length = ~0;
4836
4837 ASSERT_ALLOC( output, expected_output->len );
4838 PSA_ASSERT( psa_crypto_init( ) );
4839
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004840 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4841 psa_set_key_algorithm( &attributes, alg );
4842 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004843 PSA_ASSERT( psa_import_key( &attributes,
4844 our_key_data->x, our_key_data->len,
4845 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004846
Gilles Peskinebe697d82019-05-16 18:00:41 +02004847 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
4848 peer_key_data->x, peer_key_data->len,
4849 output, expected_output->len,
4850 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004851 ASSERT_COMPARE( output, output_length,
4852 expected_output->x, expected_output->len );
4853
4854exit:
4855 mbedtls_free( output );
4856 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004857 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02004858}
4859/* END_CASE */
4860
4861/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02004862void key_agreement_capacity( int alg_arg,
4863 int our_key_type_arg, data_t *our_key_data,
4864 data_t *peer_key_data,
4865 int expected_capacity_arg )
4866{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004867 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004868 psa_algorithm_t alg = alg_arg;
4869 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004870 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004871 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02004872 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02004873 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02004874
Gilles Peskine8817f612018-12-18 00:18:46 +01004875 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004876
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004877 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4878 psa_set_key_algorithm( &attributes, alg );
4879 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004880 PSA_ASSERT( psa_import_key( &attributes,
4881 our_key_data->x, our_key_data->len,
4882 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004883
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004884 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004885 PSA_ASSERT( psa_key_derivation_key_agreement(
4886 &operation,
4887 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4888 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004889 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4890 {
4891 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004892 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004893 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004894 NULL, 0 ) );
4895 }
Gilles Peskine59685592018-09-18 12:11:34 +02004896
Gilles Peskinebf491972018-10-25 22:36:12 +02004897 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004898 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004899 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004900 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02004901
Gilles Peskinebf491972018-10-25 22:36:12 +02004902 /* Test the actual capacity by reading the output. */
4903 while( actual_capacity > sizeof( output ) )
4904 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004905 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004906 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02004907 actual_capacity -= sizeof( output );
4908 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004909 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004910 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004911 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02004912 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02004913
Gilles Peskine59685592018-09-18 12:11:34 +02004914exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004915 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004916 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004917 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004918}
4919/* END_CASE */
4920
4921/* BEGIN_CASE */
4922void key_agreement_output( int alg_arg,
4923 int our_key_type_arg, data_t *our_key_data,
4924 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004925 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02004926{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004927 psa_key_handle_t our_key = 0;
Gilles Peskine59685592018-09-18 12:11:34 +02004928 psa_algorithm_t alg = alg_arg;
4929 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004930 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004931 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004932 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02004933
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004934 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
4935 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004936
Gilles Peskine8817f612018-12-18 00:18:46 +01004937 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004938
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004939 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4940 psa_set_key_algorithm( &attributes, alg );
4941 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004942 PSA_ASSERT( psa_import_key( &attributes,
4943 our_key_data->x, our_key_data->len,
4944 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02004945
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004946 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004947 PSA_ASSERT( psa_key_derivation_key_agreement(
4948 &operation,
4949 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
4950 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004951 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
4952 {
4953 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004954 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02004955 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02004956 NULL, 0 ) );
4957 }
Gilles Peskine59685592018-09-18 12:11:34 +02004958
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004959 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004960 actual_output,
4961 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004962 ASSERT_COMPARE( actual_output, expected_output1->len,
4963 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004964 if( expected_output2->len != 0 )
4965 {
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_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004969 ASSERT_COMPARE( actual_output, expected_output2->len,
4970 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02004971 }
Gilles Peskine59685592018-09-18 12:11:34 +02004972
4973exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004974 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02004975 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004976 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02004977 mbedtls_free( actual_output );
4978}
4979/* END_CASE */
4980
4981/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02004982void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02004983{
Gilles Peskinea50d7392018-06-21 10:22:13 +02004984 size_t bytes = bytes_arg;
4985 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004986 unsigned char *output = NULL;
4987 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02004988 size_t i;
4989 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02004990
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004991 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
4992 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02004993 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004994
Gilles Peskine8817f612018-12-18 00:18:46 +01004995 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02004996
Gilles Peskinea50d7392018-06-21 10:22:13 +02004997 /* Run several times, to ensure that every output byte will be
4998 * nonzero at least once with overwhelming probability
4999 * (2^(-8*number_of_runs)). */
5000 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02005001 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02005002 if( bytes != 0 )
5003 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01005004 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005005
5006 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01005007 ASSERT_COMPARE( output + bytes, sizeof( trail ),
5008 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005009
5010 for( i = 0; i < bytes; i++ )
5011 {
5012 if( output[i] != 0 )
5013 ++changed[i];
5014 }
Gilles Peskine05d69892018-06-19 22:00:52 +02005015 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02005016
5017 /* Check that every byte was changed to nonzero at least once. This
5018 * validates that psa_generate_random is overwriting every byte of
5019 * the output buffer. */
5020 for( i = 0; i < bytes; i++ )
5021 {
5022 TEST_ASSERT( changed[i] != 0 );
5023 }
Gilles Peskine05d69892018-06-19 22:00:52 +02005024
5025exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005026 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005027 mbedtls_free( output );
5028 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02005029}
5030/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02005031
5032/* BEGIN_CASE */
5033void generate_key( int type_arg,
5034 int bits_arg,
5035 int usage_arg,
5036 int alg_arg,
5037 int expected_status_arg )
5038{
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005039 psa_key_handle_t handle = 0;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005040 psa_key_type_t type = type_arg;
5041 psa_key_usage_t usage = usage_arg;
5042 size_t bits = bits_arg;
5043 psa_algorithm_t alg = alg_arg;
5044 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005045 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005046 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005047
Gilles Peskine8817f612018-12-18 00:18:46 +01005048 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005049
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005050 psa_set_key_usage_flags( &attributes, usage );
5051 psa_set_key_algorithm( &attributes, alg );
5052 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005053 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005054
5055 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005056 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005057 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005058 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005059
5060 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005061 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
5062 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
5063 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005064
Gilles Peskine818ca122018-06-20 18:16:48 +02005065 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005066 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02005067 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005068
5069exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005070 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005071 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005072 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005073}
5074/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03005075
Gilles Peskinee56e8782019-04-26 17:34:02 +02005076/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
5077void generate_key_rsa( int bits_arg,
5078 data_t *e_arg,
5079 int expected_status_arg )
5080{
5081 psa_key_handle_t handle = 0;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02005082 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02005083 size_t bits = bits_arg;
5084 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
5085 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
5086 psa_status_t expected_status = expected_status_arg;
5087 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5088 uint8_t *exported = NULL;
5089 size_t exported_size =
5090 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
5091 size_t exported_length = SIZE_MAX;
5092 uint8_t *e_read_buffer = NULL;
5093 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02005094 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005095 size_t e_read_length = SIZE_MAX;
5096
5097 if( e_arg->len == 0 ||
5098 ( e_arg->len == 3 &&
5099 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
5100 {
5101 is_default_public_exponent = 1;
5102 e_read_size = 0;
5103 }
5104 ASSERT_ALLOC( e_read_buffer, e_read_size );
5105 ASSERT_ALLOC( exported, exported_size );
5106
5107 PSA_ASSERT( psa_crypto_init( ) );
5108
5109 psa_set_key_usage_flags( &attributes, usage );
5110 psa_set_key_algorithm( &attributes, alg );
5111 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
5112 e_arg->x, e_arg->len ) );
5113 psa_set_key_bits( &attributes, bits );
5114
5115 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005116 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005117 if( expected_status != PSA_SUCCESS )
5118 goto exit;
5119
5120 /* Test the key information */
5121 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5122 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5123 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5124 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
5125 e_read_buffer, e_read_size,
5126 &e_read_length ) );
5127 if( is_default_public_exponent )
5128 TEST_EQUAL( e_read_length, 0 );
5129 else
5130 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
5131
5132 /* Do something with the key according to its type and permitted usage. */
5133 if( ! exercise_key( handle, usage, alg ) )
5134 goto exit;
5135
5136 /* Export the key and check the public exponent. */
5137 PSA_ASSERT( psa_export_public_key( handle,
5138 exported, exported_size,
5139 &exported_length ) );
5140 {
5141 uint8_t *p = exported;
5142 uint8_t *end = exported + exported_length;
5143 size_t len;
5144 /* RSAPublicKey ::= SEQUENCE {
5145 * modulus INTEGER, -- n
5146 * publicExponent INTEGER } -- e
5147 */
5148 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005149 MBEDTLS_ASN1_SEQUENCE |
5150 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005151 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
5152 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
5153 MBEDTLS_ASN1_INTEGER ) );
5154 if( len >= 1 && p[0] == 0 )
5155 {
5156 ++p;
5157 --len;
5158 }
5159 if( e_arg->len == 0 )
5160 {
5161 TEST_EQUAL( len, 3 );
5162 TEST_EQUAL( p[0], 1 );
5163 TEST_EQUAL( p[1], 0 );
5164 TEST_EQUAL( p[2], 1 );
5165 }
5166 else
5167 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
5168 }
5169
5170exit:
5171 psa_reset_key_attributes( &attributes );
5172 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005173 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005174 mbedtls_free( e_read_buffer );
5175 mbedtls_free( exported );
5176}
5177/* END_CASE */
5178
Darryl Greend49a4992018-06-18 17:27:26 +01005179/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005180void persistent_key_load_key_from_storage( data_t *data,
5181 int type_arg, int bits_arg,
5182 int usage_flags_arg, int alg_arg,
5183 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01005184{
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005185 psa_key_id_t key_id = 1;
5186 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005187 psa_key_handle_t handle = 0;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005188 psa_key_handle_t base_key = 0;
5189 psa_key_type_t type = type_arg;
5190 size_t bits = bits_arg;
5191 psa_key_usage_t usage_flags = usage_flags_arg;
5192 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005193 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01005194 unsigned char *first_export = NULL;
5195 unsigned char *second_export = NULL;
5196 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
5197 size_t first_exported_length;
5198 size_t second_exported_length;
5199
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005200 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5201 {
5202 ASSERT_ALLOC( first_export, export_size );
5203 ASSERT_ALLOC( second_export, export_size );
5204 }
Darryl Greend49a4992018-06-18 17:27:26 +01005205
Gilles Peskine8817f612018-12-18 00:18:46 +01005206 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005207
Gilles Peskinec87af662019-05-15 16:12:22 +02005208 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005209 psa_set_key_usage_flags( &attributes, usage_flags );
5210 psa_set_key_algorithm( &attributes, alg );
5211 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005212 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01005213
Darryl Green0c6575a2018-11-07 16:05:30 +00005214 switch( generation_method )
5215 {
5216 case IMPORT_KEY:
5217 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02005218 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
5219 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005220 break;
Darryl Greend49a4992018-06-18 17:27:26 +01005221
Darryl Green0c6575a2018-11-07 16:05:30 +00005222 case GENERATE_KEY:
5223 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005224 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005225 break;
5226
5227 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005228 {
5229 /* Create base key */
5230 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
5231 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5232 psa_set_key_usage_flags( &base_attributes,
5233 PSA_KEY_USAGE_DERIVE );
5234 psa_set_key_algorithm( &base_attributes, derive_alg );
5235 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005236 PSA_ASSERT( psa_import_key( &base_attributes,
5237 data->x, data->len,
5238 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005239 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005240 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005241 PSA_ASSERT( psa_key_derivation_input_key(
5242 &operation,
5243 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005244 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005245 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005246 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005247 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5248 &operation,
5249 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005250 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005251 PSA_ASSERT( psa_destroy_key( base_key ) );
5252 base_key = 0;
5253 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005254 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005255 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005256 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005257
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005258 /* Export the key if permitted by the key policy. */
5259 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5260 {
5261 PSA_ASSERT( psa_export_key( handle,
5262 first_export, export_size,
5263 &first_exported_length ) );
5264 if( generation_method == IMPORT_KEY )
5265 ASSERT_COMPARE( data->x, data->len,
5266 first_export, first_exported_length );
5267 }
Darryl Greend49a4992018-06-18 17:27:26 +01005268
5269 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005270 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005271 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005272 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005273
Darryl Greend49a4992018-06-18 17:27:26 +01005274 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005275 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005276 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5277 TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
5278 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5279 PSA_KEY_LIFETIME_PERSISTENT );
5280 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5281 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5282 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5283 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005284
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005285 /* Export the key again if permitted by the key policy. */
5286 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005287 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005288 PSA_ASSERT( psa_export_key( handle,
5289 second_export, export_size,
5290 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005291 ASSERT_COMPARE( first_export, first_exported_length,
5292 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005293 }
5294
5295 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005296 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005297 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005298
5299exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005300 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005301 mbedtls_free( first_export );
5302 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005303 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005304 psa_destroy_key( base_key );
5305 if( handle == 0 )
5306 {
5307 /* In case there was a test failure after creating the persistent key
5308 * but while it was not open, try to re-open the persistent key
5309 * to delete it. */
Gilles Peskine225010f2019-05-06 18:44:55 +02005310 psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005311 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005312 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005313 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005314}
5315/* END_CASE */