blob: 23d827ec4bd7f36ecd7e8d8ba14c231a4d121cbf [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
Ronald Cron02c78b72020-05-27 09:22:32 +020012#include "test/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"
Ronald Cron41841072020-09-17 15:28:26 +020022#include "psa_crypto_slot_management.h"
Gilles Peskinebdc96fd2019-08-07 12:08:04 +020023
Jaeden Amerof24c7f82018-06-27 17:20:43 +010024/** An invalid export length that will never be set by psa_export_key(). */
25static const size_t INVALID_EXPORT_LENGTH = ~0U;
26
Gilles Peskinef426e0f2019-02-25 17:42:03 +010027/* A hash algorithm that is known to be supported.
28 *
29 * This is used in some smoke tests.
30 */
31#if defined(MBEDTLS_MD2_C)
32#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2
33#elif defined(MBEDTLS_MD4_C)
34#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4
35#elif defined(MBEDTLS_MD5_C)
36#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5
37/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of
38 * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160
39 * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be
40 * implausible anyway. */
41#elif defined(MBEDTLS_SHA1_C)
42#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1
43#elif defined(MBEDTLS_SHA256_C)
44#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256
45#elif defined(MBEDTLS_SHA512_C)
46#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384
47#elif defined(MBEDTLS_SHA3_C)
48#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256
49#else
50#undef KNOWN_SUPPORTED_HASH_ALG
51#endif
52
53/* A block cipher that is known to be supported.
54 *
55 * For simplicity's sake, stick to block ciphers with 16-byte blocks.
56 */
57#if defined(MBEDTLS_AES_C)
58#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
59#elif defined(MBEDTLS_ARIA_C)
60#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
61#elif defined(MBEDTLS_CAMELLIA_C)
62#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
63#undef KNOWN_SUPPORTED_BLOCK_CIPHER
64#endif
65
66/* A MAC mode that is known to be supported.
67 *
68 * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or
69 * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER.
70 *
71 * This is used in some smoke tests.
72 */
73#if defined(KNOWN_SUPPORTED_HASH_ALG)
74#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) )
75#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC
76#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C)
77#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC
78#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
79#else
80#undef KNOWN_SUPPORTED_MAC_ALG
81#undef KNOWN_SUPPORTED_MAC_KEY_TYPE
82#endif
83
84/* A cipher algorithm and key type that are known to be supported.
85 *
86 * This is used in some smoke tests.
87 */
88#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
89#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
90#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
91#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
92#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
93#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
94#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
95#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
96#else
97#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
98#endif
99#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG)
100#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
101#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER
102#elif defined(MBEDTLS_RC4_C)
103#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4
104#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4
105#else
106#undef KNOWN_SUPPORTED_CIPHER_ALG
107#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
108#endif
109
Gilles Peskine667c1112019-12-03 19:03:20 +0100110#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
111int lifetime_is_secure_element( psa_key_lifetime_t lifetime )
112{
113 /* At the moment, anything that isn't a built-in lifetime is either
114 * a secure element or unassigned. */
115 return( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
116 lifetime != PSA_KEY_LIFETIME_PERSISTENT );
117}
118#else
119int lifetime_is_secure_element( psa_key_lifetime_t lifetime )
120{
121 (void) lifetime;
122 return( 0 );
123}
124#endif
125
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200126/** Test if a buffer contains a constant byte value.
127 *
128 * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200129 *
130 * \param buffer Pointer to the beginning of the buffer.
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200131 * \param c Expected value of every byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200132 * \param size Size of the buffer in bytes.
133 *
Gilles Peskine3f669c32018-06-21 09:21:51 +0200134 * \return 1 if the buffer is all-bits-zero.
135 * \return 0 if there is at least one nonzero byte.
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200136 */
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200137static int mem_is_char( void *buffer, unsigned char c, size_t size )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200138{
139 size_t i;
140 for( i = 0; i < size; i++ )
141 {
Gilles Peskinea7aa4422018-08-14 15:17:54 +0200142 if( ( (unsigned char *) buffer )[i] != c )
Gilles Peskine3f669c32018-06-21 09:21:51 +0200143 return( 0 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200144 }
Gilles Peskine3f669c32018-06-21 09:21:51 +0200145 return( 1 );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200146}
Gilles Peskine818ca122018-06-20 18:16:48 +0200147
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200148/* Write the ASN.1 INTEGER with the value 2^(bits-1)+x backwards from *p. */
149static int asn1_write_10x( unsigned char **p,
150 unsigned char *start,
151 size_t bits,
152 unsigned char x )
153{
154 int ret;
155 int len = bits / 8 + 1;
Gilles Peskine480416a2018-06-28 19:04:07 +0200156 if( bits == 0 )
157 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
158 if( bits <= 8 && x >= 1 << ( bits - 1 ) )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200159 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Moran Pekercb088e72018-07-17 17:36:59 +0300160 if( *p < start || *p - start < (ptrdiff_t) len )
Gilles Peskine0b352bc2018-06-28 00:16:11 +0200161 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
162 *p -= len;
163 ( *p )[len-1] = x;
164 if( bits % 8 == 0 )
165 ( *p )[1] |= 1;
166 else
167 ( *p )[0] |= 1 << ( bits % 8 );
168 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
169 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
170 MBEDTLS_ASN1_INTEGER ) );
171 return( len );
172}
173
174static int construct_fake_rsa_key( unsigned char *buffer,
175 size_t buffer_size,
176 unsigned char **p,
177 size_t bits,
178 int keypair )
179{
180 size_t half_bits = ( bits + 1 ) / 2;
181 int ret;
182 int len = 0;
183 /* Construct something that looks like a DER encoding of
184 * as defined by PKCS#1 v2.2 (RFC 8017) section A.1.2:
185 * RSAPrivateKey ::= SEQUENCE {
186 * version Version,
187 * modulus INTEGER, -- n
188 * publicExponent INTEGER, -- e
189 * privateExponent INTEGER, -- d
190 * prime1 INTEGER, -- p
191 * prime2 INTEGER, -- q
192 * exponent1 INTEGER, -- d mod (p-1)
193 * exponent2 INTEGER, -- d mod (q-1)
194 * coefficient INTEGER, -- (inverse of q) mod p
195 * otherPrimeInfos OtherPrimeInfos OPTIONAL
196 * }
197 * Or, for a public key, the same structure with only
198 * version, modulus and publicExponent.
199 */
200 *p = buffer + buffer_size;
201 if( keypair )
202 {
203 MBEDTLS_ASN1_CHK_ADD( len, /* pq */
204 asn1_write_10x( p, buffer, half_bits, 1 ) );
205 MBEDTLS_ASN1_CHK_ADD( len, /* dq */
206 asn1_write_10x( p, buffer, half_bits, 1 ) );
207 MBEDTLS_ASN1_CHK_ADD( len, /* dp */
208 asn1_write_10x( p, buffer, half_bits, 1 ) );
209 MBEDTLS_ASN1_CHK_ADD( len, /* q */
210 asn1_write_10x( p, buffer, half_bits, 1 ) );
211 MBEDTLS_ASN1_CHK_ADD( len, /* p != q to pass mbedtls sanity checks */
212 asn1_write_10x( p, buffer, half_bits, 3 ) );
213 MBEDTLS_ASN1_CHK_ADD( len, /* d */
214 asn1_write_10x( p, buffer, bits, 1 ) );
215 }
216 MBEDTLS_ASN1_CHK_ADD( len, /* e = 65537 */
217 asn1_write_10x( p, buffer, 17, 1 ) );
218 MBEDTLS_ASN1_CHK_ADD( len, /* n */
219 asn1_write_10x( p, buffer, bits, 1 ) );
220 if( keypair )
221 MBEDTLS_ASN1_CHK_ADD( len, /* version = 0 */
222 mbedtls_asn1_write_int( p, buffer, 0 ) );
223 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, buffer, len ) );
224 {
225 const unsigned char tag =
226 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
227 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, buffer, tag ) );
228 }
229 return( len );
230}
231
Gilles Peskine667c1112019-12-03 19:03:20 +0100232int check_key_attributes_sanity( psa_key_handle_t key )
233{
234 int ok = 0;
235 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
236 psa_key_lifetime_t lifetime;
Ronald Cron71016a92020-08-28 19:01:50 +0200237 mbedtls_svc_key_id_t id;
Gilles Peskine667c1112019-12-03 19:03:20 +0100238 psa_key_type_t type;
239 psa_key_type_t bits;
240
241 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
242 lifetime = psa_get_key_lifetime( &attributes );
243 id = psa_get_key_id( &attributes );
244 type = psa_get_key_type( &attributes );
245 bits = psa_get_key_bits( &attributes );
246
247 /* Persistence */
248 if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
Ronald Cron41841072020-09-17 15:28:26 +0200249 {
250 TEST_ASSERT(
251 ( PSA_KEY_ID_VOLATILE_MIN <=
252 MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ) &&
253 ( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) <=
254 PSA_KEY_ID_VOLATILE_MAX ) );
255 }
Gilles Peskine667c1112019-12-03 19:03:20 +0100256 else
257 {
258 TEST_ASSERT(
Ronald Cronecfb2372020-07-23 17:13:42 +0200259 ( PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ) &&
260 ( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) <= PSA_KEY_ID_USER_MAX ) );
Gilles Peskine667c1112019-12-03 19:03:20 +0100261 }
262#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
263 /* randomly-generated 64-bit constant, should never appear in test data */
264 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
265 psa_status_t status = psa_get_key_slot_number( &attributes, &slot_number );
266 if( lifetime_is_secure_element( lifetime ) )
267 {
268 /* Mbed Crypto currently always exposes the slot number to
269 * applications. This is not mandated by the PSA specification
270 * and may change in future versions. */
271 TEST_EQUAL( status, 0 );
272 TEST_ASSERT( slot_number != 0xec94d4a5058a1a21 );
273 }
274 else
275 {
276 TEST_EQUAL( status, PSA_ERROR_INVALID_ARGUMENT );
277 }
278#endif
279
280 /* Type and size */
281 TEST_ASSERT( type != 0 );
282 TEST_ASSERT( bits != 0 );
283 TEST_ASSERT( bits <= PSA_MAX_KEY_BITS );
284 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
285 TEST_ASSERT( bits % 8 == 0 );
286
287 /* MAX macros concerning specific key types */
288 if( PSA_KEY_TYPE_IS_ECC( type ) )
289 TEST_ASSERT( bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS );
290 else if( PSA_KEY_TYPE_IS_RSA( type ) )
291 TEST_ASSERT( bits <= PSA_VENDOR_RSA_MAX_KEY_BITS );
292 TEST_ASSERT( PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) <= PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE );
293
294 ok = 1;
295
296exit:
297 psa_reset_key_attributes( &attributes );
298 return( ok );
299}
300
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100301int exercise_mac_setup( psa_key_type_t key_type,
302 const unsigned char *key_bytes,
303 size_t key_length,
304 psa_algorithm_t alg,
305 psa_mac_operation_t *operation,
306 psa_status_t *status )
307{
Ronald Cron91e95152020-07-30 17:48:03 +0200308 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200309 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100310
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100311 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200312 psa_set_key_algorithm( &attributes, alg );
313 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200314 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
315 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100316
317 *status = psa_mac_sign_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100318 /* Whether setup succeeded or failed, abort must succeed. */
319 PSA_ASSERT( psa_mac_abort( operation ) );
320 /* If setup failed, reproduce the failure, so that the caller can
321 * test the resulting state of the operation object. */
322 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100323 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100324 TEST_EQUAL( psa_mac_sign_setup( operation, handle, alg ),
325 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100326 }
327
328 psa_destroy_key( handle );
329 return( 1 );
330
331exit:
332 psa_destroy_key( handle );
333 return( 0 );
334}
335
336int exercise_cipher_setup( psa_key_type_t key_type,
337 const unsigned char *key_bytes,
338 size_t key_length,
339 psa_algorithm_t alg,
340 psa_cipher_operation_t *operation,
341 psa_status_t *status )
342{
Ronald Cron91e95152020-07-30 17:48:03 +0200343 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200344 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100345
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +0200346 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
347 psa_set_key_algorithm( &attributes, alg );
348 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +0200349 PSA_ASSERT( psa_import_key( &attributes, key_bytes, key_length,
350 &handle ) );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100351
352 *status = psa_cipher_encrypt_setup( operation, handle, alg );
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100353 /* Whether setup succeeded or failed, abort must succeed. */
354 PSA_ASSERT( psa_cipher_abort( operation ) );
355 /* If setup failed, reproduce the failure, so that the caller can
356 * test the resulting state of the operation object. */
357 if( *status != PSA_SUCCESS )
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100358 {
Gilles Peskine9e0a4a52019-02-25 22:11:18 +0100359 TEST_EQUAL( psa_cipher_encrypt_setup( operation, handle, alg ),
360 *status );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100361 }
362
363 psa_destroy_key( handle );
364 return( 1 );
365
366exit:
367 psa_destroy_key( handle );
368 return( 0 );
369}
370
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100371static int exercise_mac_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200372 psa_key_usage_t usage,
373 psa_algorithm_t alg )
374{
Jaeden Amero769ce272019-01-04 11:48:03 +0000375 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200376 const unsigned char input[] = "foo";
Gilles Peskine69c12672018-06-28 00:07:19 +0200377 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200378 size_t mac_length = sizeof( mac );
379
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100380 if( usage & PSA_KEY_USAGE_SIGN_HASH )
Gilles Peskine818ca122018-06-20 18:16:48 +0200381 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100382 PSA_ASSERT( psa_mac_sign_setup( &operation,
383 handle, alg ) );
384 PSA_ASSERT( psa_mac_update( &operation,
385 input, sizeof( input ) ) );
386 PSA_ASSERT( psa_mac_sign_finish( &operation,
387 mac, sizeof( mac ),
388 &mac_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200389 }
390
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100391 if( usage & PSA_KEY_USAGE_VERIFY_HASH )
Gilles Peskine818ca122018-06-20 18:16:48 +0200392 {
393 psa_status_t verify_status =
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100394 ( usage & PSA_KEY_USAGE_SIGN_HASH ?
Gilles Peskine818ca122018-06-20 18:16:48 +0200395 PSA_SUCCESS :
396 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine8817f612018-12-18 00:18:46 +0100397 PSA_ASSERT( psa_mac_verify_setup( &operation,
398 handle, alg ) );
399 PSA_ASSERT( psa_mac_update( &operation,
400 input, sizeof( input ) ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100401 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
402 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200403 }
404
405 return( 1 );
406
407exit:
408 psa_mac_abort( &operation );
409 return( 0 );
410}
411
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100412static int exercise_cipher_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200413 psa_key_usage_t usage,
414 psa_algorithm_t alg )
415{
Jaeden Amero5bae2272019-01-04 11:48:27 +0000416 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine818ca122018-06-20 18:16:48 +0200417 unsigned char iv[16] = {0};
418 size_t iv_length = sizeof( iv );
419 const unsigned char plaintext[16] = "Hello, world...";
420 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
421 size_t ciphertext_length = sizeof( ciphertext );
422 unsigned char decrypted[sizeof( ciphertext )];
423 size_t part_length;
424
425 if( usage & PSA_KEY_USAGE_ENCRYPT )
426 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100427 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
428 handle, alg ) );
429 PSA_ASSERT( psa_cipher_generate_iv( &operation,
430 iv, sizeof( iv ),
431 &iv_length ) );
432 PSA_ASSERT( psa_cipher_update( &operation,
433 plaintext, sizeof( plaintext ),
434 ciphertext, sizeof( ciphertext ),
435 &ciphertext_length ) );
436 PSA_ASSERT( psa_cipher_finish( &operation,
437 ciphertext + ciphertext_length,
438 sizeof( ciphertext ) - ciphertext_length,
439 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200440 ciphertext_length += part_length;
441 }
442
443 if( usage & PSA_KEY_USAGE_DECRYPT )
444 {
445 psa_status_t status;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200446 int maybe_invalid_padding = 0;
Gilles Peskine818ca122018-06-20 18:16:48 +0200447 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
448 {
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200449 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
450 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
451 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
452 * have this macro yet. */
453 iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
454 psa_get_key_type( &attributes ) );
455 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
Gilles Peskine818ca122018-06-20 18:16:48 +0200456 }
Gilles Peskine8817f612018-12-18 00:18:46 +0100457 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
458 handle, alg ) );
459 PSA_ASSERT( psa_cipher_set_iv( &operation,
460 iv, iv_length ) );
461 PSA_ASSERT( psa_cipher_update( &operation,
462 ciphertext, ciphertext_length,
463 decrypted, sizeof( decrypted ),
464 &part_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200465 status = psa_cipher_finish( &operation,
466 decrypted + part_length,
467 sizeof( decrypted ) - part_length,
468 &part_length );
469 /* For a stream cipher, all inputs are valid. For a block cipher,
470 * if the input is some aribtrary data rather than an actual
471 ciphertext, a padding error is likely. */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200472 if( maybe_invalid_padding )
Gilles Peskine818ca122018-06-20 18:16:48 +0200473 TEST_ASSERT( status == PSA_SUCCESS ||
474 status == PSA_ERROR_INVALID_PADDING );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200475 else
476 PSA_ASSERT( status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200477 }
478
479 return( 1 );
480
481exit:
482 psa_cipher_abort( &operation );
483 return( 0 );
484}
485
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100486static int exercise_aead_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200487 psa_key_usage_t usage,
488 psa_algorithm_t alg )
489{
490 unsigned char nonce[16] = {0};
491 size_t nonce_length = sizeof( nonce );
492 unsigned char plaintext[16] = "Hello, world...";
493 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
494 size_t ciphertext_length = sizeof( ciphertext );
495 size_t plaintext_length = sizeof( ciphertext );
496
497 if( usage & PSA_KEY_USAGE_ENCRYPT )
498 {
Gilles Peskine8817f612018-12-18 00:18:46 +0100499 PSA_ASSERT( psa_aead_encrypt( handle, alg,
500 nonce, nonce_length,
501 NULL, 0,
502 plaintext, sizeof( plaintext ),
503 ciphertext, sizeof( ciphertext ),
504 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200505 }
506
507 if( usage & PSA_KEY_USAGE_DECRYPT )
508 {
509 psa_status_t verify_status =
510 ( usage & PSA_KEY_USAGE_ENCRYPT ?
511 PSA_SUCCESS :
512 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100513 TEST_EQUAL( psa_aead_decrypt( handle, alg,
514 nonce, nonce_length,
515 NULL, 0,
516 ciphertext, ciphertext_length,
517 plaintext, sizeof( plaintext ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100518 &plaintext_length ),
519 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200520 }
521
522 return( 1 );
523
524exit:
525 return( 0 );
526}
527
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100528static int exercise_signature_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200529 psa_key_usage_t usage,
530 psa_algorithm_t alg )
531{
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200532 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
533 size_t payload_length = 16;
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100534 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine818ca122018-06-20 18:16:48 +0200535 size_t signature_length = sizeof( signature );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100536 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
537
538 /* If the policy allows signing with any hash, just pick one. */
539 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH )
540 {
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100541#if defined(KNOWN_SUPPORTED_HASH_ALG)
542 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
543 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Gilles Peskine57ab7212019-01-28 13:03:09 +0100544#else
545 test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ );
Gilles Peskinef426e0f2019-02-25 17:42:03 +0100546 return( 1 );
Gilles Peskine57ab7212019-01-28 13:03:09 +0100547#endif
Gilles Peskine57ab7212019-01-28 13:03:09 +0100548 }
Gilles Peskine818ca122018-06-20 18:16:48 +0200549
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100550 if( usage & PSA_KEY_USAGE_SIGN_HASH )
Gilles Peskine818ca122018-06-20 18:16:48 +0200551 {
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200552 /* Some algorithms require the payload to have the size of
553 * the hash encoded in the algorithm. Use this input size
554 * even for algorithms that allow other input sizes. */
Gilles Peskinef969b3a2018-06-30 00:20:25 +0200555 if( hash_alg != 0 )
556 payload_length = PSA_HASH_SIZE( hash_alg );
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100557 PSA_ASSERT( psa_sign_hash( handle, alg,
558 payload, payload_length,
559 signature, sizeof( signature ),
560 &signature_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200561 }
562
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100563 if( usage & PSA_KEY_USAGE_VERIFY_HASH )
Gilles Peskine818ca122018-06-20 18:16:48 +0200564 {
565 psa_status_t verify_status =
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100566 ( usage & PSA_KEY_USAGE_SIGN_HASH ?
Gilles Peskine818ca122018-06-20 18:16:48 +0200567 PSA_SUCCESS :
568 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine89d8c5c2019-11-26 17:01:59 +0100569 TEST_EQUAL( psa_verify_hash( handle, alg,
570 payload, payload_length,
571 signature, signature_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +0100572 verify_status );
Gilles Peskine818ca122018-06-20 18:16:48 +0200573 }
574
575 return( 1 );
576
577exit:
578 return( 0 );
579}
580
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100581static int exercise_asymmetric_encryption_key( psa_key_handle_t handle,
Gilles Peskine818ca122018-06-20 18:16:48 +0200582 psa_key_usage_t usage,
583 psa_algorithm_t alg )
584{
585 unsigned char plaintext[256] = "Hello, world...";
586 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
587 size_t ciphertext_length = sizeof( ciphertext );
588 size_t plaintext_length = 16;
589
590 if( usage & PSA_KEY_USAGE_ENCRYPT )
591 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100592 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
593 plaintext, plaintext_length,
594 NULL, 0,
595 ciphertext, sizeof( ciphertext ),
596 &ciphertext_length ) );
Gilles Peskine818ca122018-06-20 18:16:48 +0200597 }
598
599 if( usage & PSA_KEY_USAGE_DECRYPT )
600 {
601 psa_status_t status =
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100602 psa_asymmetric_decrypt( handle, alg,
Gilles Peskine818ca122018-06-20 18:16:48 +0200603 ciphertext, ciphertext_length,
604 NULL, 0,
605 plaintext, sizeof( plaintext ),
606 &plaintext_length );
607 TEST_ASSERT( status == PSA_SUCCESS ||
608 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
609 ( status == PSA_ERROR_INVALID_ARGUMENT ||
610 status == PSA_ERROR_INVALID_PADDING ) ) );
611 }
612
613 return( 1 );
614
615exit:
616 return( 0 );
617}
Gilles Peskine02b75072018-07-01 22:31:34 +0200618
Janos Follathf2815ea2019-07-03 12:41:36 +0100619static int setup_key_derivation_wrap( psa_key_derivation_operation_t* operation,
620 psa_key_handle_t handle,
621 psa_algorithm_t alg,
622 unsigned char* input1, size_t input1_length,
623 unsigned char* input2, size_t input2_length,
624 size_t capacity )
625{
626 PSA_ASSERT( psa_key_derivation_setup( operation, alg ) );
627 if( PSA_ALG_IS_HKDF( alg ) )
628 {
629 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
630 PSA_KEY_DERIVATION_INPUT_SALT,
631 input1, input1_length ) );
632 PSA_ASSERT( psa_key_derivation_input_key( operation,
633 PSA_KEY_DERIVATION_INPUT_SECRET,
634 handle ) );
635 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
636 PSA_KEY_DERIVATION_INPUT_INFO,
637 input2,
638 input2_length ) );
639 }
640 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
641 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
642 {
643 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
644 PSA_KEY_DERIVATION_INPUT_SEED,
645 input1, input1_length ) );
646 PSA_ASSERT( psa_key_derivation_input_key( operation,
647 PSA_KEY_DERIVATION_INPUT_SECRET,
648 handle ) );
649 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
650 PSA_KEY_DERIVATION_INPUT_LABEL,
651 input2, input2_length ) );
652 }
653 else
654 {
655 TEST_ASSERT( ! "Key derivation algorithm not supported" );
656 }
657
Gilles Peskinec744d992019-07-30 17:26:54 +0200658 if( capacity != SIZE_MAX )
659 PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
Janos Follathf2815ea2019-07-03 12:41:36 +0100660
661 return( 1 );
662
663exit:
664 return( 0 );
665}
666
667
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100668static int exercise_key_derivation_key( psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +0200669 psa_key_usage_t usage,
670 psa_algorithm_t alg )
671{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200672 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathf2815ea2019-07-03 12:41:36 +0100673 unsigned char input1[] = "Input 1";
674 size_t input1_length = sizeof( input1 );
675 unsigned char input2[] = "Input 2";
676 size_t input2_length = sizeof( input2 );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200677 unsigned char output[1];
Janos Follathf2815ea2019-07-03 12:41:36 +0100678 size_t capacity = sizeof( output );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200679
680 if( usage & PSA_KEY_USAGE_DERIVE )
681 {
Janos Follathf2815ea2019-07-03 12:41:36 +0100682 if( !setup_key_derivation_wrap( &operation, handle, alg,
683 input1, input1_length,
684 input2, input2_length, capacity ) )
685 goto exit;
Gilles Peskine7607cd62019-05-29 17:35:00 +0200686
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200687 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200688 output,
Janos Follathf2815ea2019-07-03 12:41:36 +0100689 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200690 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +0200691 }
692
693 return( 1 );
694
695exit:
696 return( 0 );
697}
698
Gilles Peskinec7998b72018-11-07 18:45:02 +0100699/* We need two keys to exercise key agreement. Exercise the
700 * private key against its own public key. */
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200701static psa_status_t key_agreement_with_self(
702 psa_key_derivation_operation_t *operation,
703 psa_key_handle_t handle )
Gilles Peskinec7998b72018-11-07 18:45:02 +0100704{
705 psa_key_type_t private_key_type;
706 psa_key_type_t public_key_type;
707 size_t key_bits;
708 uint8_t *public_key = NULL;
709 size_t public_key_length;
David Saadab4ecc272019-02-14 13:48:10 +0200710 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200711 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
712 * but it's good enough: callers will report it as a failed test anyway. */
David Saadab4ecc272019-02-14 13:48:10 +0200713 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200714 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinec7998b72018-11-07 18:45:02 +0100715
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200716 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
717 private_key_type = psa_get_key_type( &attributes );
718 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200719 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100720 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
721 ASSERT_ALLOC( public_key, public_key_length );
Gilles Peskine8817f612018-12-18 00:18:46 +0100722 PSA_ASSERT( psa_export_public_key( handle,
723 public_key, public_key_length,
724 &public_key_length ) );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100725
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200726 status = psa_key_derivation_key_agreement(
727 operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle,
728 public_key, public_key_length );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100729exit:
730 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200731 psa_reset_key_attributes( &attributes );
Gilles Peskinec7998b72018-11-07 18:45:02 +0100732 return( status );
733}
734
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200735/* We need two keys to exercise key agreement. Exercise the
736 * private key against its own public key. */
737static psa_status_t raw_key_agreement_with_self( psa_algorithm_t alg,
738 psa_key_handle_t handle )
739{
740 psa_key_type_t private_key_type;
741 psa_key_type_t public_key_type;
742 size_t key_bits;
743 uint8_t *public_key = NULL;
744 size_t public_key_length;
745 uint8_t output[1024];
746 size_t output_length;
747 /* Return GENERIC_ERROR if something other than the final call to
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200748 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
749 * but it's good enough: callers will report it as a failed test anyway. */
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200750 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200751 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200752
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200753 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
754 private_key_type = psa_get_key_type( &attributes );
755 key_bits = psa_get_key_bits( &attributes );
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200756 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200757 public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
758 ASSERT_ALLOC( public_key, public_key_length );
759 PSA_ASSERT( psa_export_public_key( handle,
760 public_key, public_key_length,
761 &public_key_length ) );
762
Gilles Peskinebe697d82019-05-16 18:00:41 +0200763 status = psa_raw_key_agreement( alg, handle,
764 public_key, public_key_length,
765 output, sizeof( output ), &output_length );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200766exit:
767 mbedtls_free( public_key );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +0200768 psa_reset_key_attributes( &attributes );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +0200769 return( status );
770}
771
772static int exercise_raw_key_agreement_key( psa_key_handle_t handle,
773 psa_key_usage_t usage,
774 psa_algorithm_t alg )
775{
776 int ok = 0;
777
778 if( usage & PSA_KEY_USAGE_DERIVE )
779 {
780 /* We need two keys to exercise key agreement. Exercise the
781 * private key against its own public key. */
782 PSA_ASSERT( raw_key_agreement_with_self( alg, handle ) );
783 }
784 ok = 1;
785
786exit:
787 return( ok );
788}
789
Gilles Peskinebdf309c2018-12-03 15:36:32 +0100790static int exercise_key_agreement_key( psa_key_handle_t handle,
Gilles Peskine01d718c2018-09-18 12:01:02 +0200791 psa_key_usage_t usage,
792 psa_algorithm_t alg )
793{
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200794 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +0200795 unsigned char output[1];
796 int ok = 0;
797
798 if( usage & PSA_KEY_USAGE_DERIVE )
799 {
800 /* We need two keys to exercise key agreement. Exercise the
801 * private key against its own public key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200802 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
803 PSA_ASSERT( key_agreement_with_self( &operation, handle ) );
804 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +0200805 output,
806 sizeof( output ) ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +0200807 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +0200808 }
809 ok = 1;
810
811exit:
Gilles Peskine01d718c2018-09-18 12:01:02 +0200812 return( ok );
813}
814
Jaeden Amerof7dca862019-06-27 17:31:33 +0100815int asn1_skip_integer( unsigned char **p, const unsigned char *end,
816 size_t min_bits, size_t max_bits,
817 int must_be_odd )
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200818{
819 size_t len;
820 size_t actual_bits;
821 unsigned char msb;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100822 TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100823 MBEDTLS_ASN1_INTEGER ),
824 0 );
k-stachowiak9b88efc2019-09-13 15:26:53 +0200825
826 /* Check if the retrieved length doesn't extend the actual buffer's size.
827 * It is assumed here, that end >= p, which validates casting to size_t. */
828 TEST_ASSERT( len <= (size_t)( end - *p) );
829
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200830 /* Tolerate a slight departure from DER encoding:
831 * - 0 may be represented by an empty string or a 1-byte string.
832 * - The sign bit may be used as a value bit. */
833 if( ( len == 1 && ( *p )[0] == 0 ) ||
834 ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) )
835 {
836 ++( *p );
837 --len;
838 }
839 if( min_bits == 0 && len == 0 )
840 return( 1 );
841 msb = ( *p )[0];
842 TEST_ASSERT( msb != 0 );
843 actual_bits = 8 * ( len - 1 );
844 while( msb != 0 )
845 {
846 msb >>= 1;
847 ++actual_bits;
848 }
849 TEST_ASSERT( actual_bits >= min_bits );
850 TEST_ASSERT( actual_bits <= max_bits );
851 if( must_be_odd )
852 TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 );
853 *p += len;
854 return( 1 );
855exit:
856 return( 0 );
857}
858
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200859static int exported_key_sanity_check( psa_key_type_t type, size_t bits,
860 uint8_t *exported, size_t exported_length )
861{
862 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
Gilles Peskinefe11b722018-12-18 00:24:04 +0100863 TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200864 else
865 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
Gilles Peskined14664a2018-08-10 19:07:32 +0200866
867#if defined(MBEDTLS_DES_C)
868 if( type == PSA_KEY_TYPE_DES )
869 {
870 /* Check the parity bits. */
871 unsigned i;
872 for( i = 0; i < bits / 8; i++ )
873 {
874 unsigned bit_count = 0;
875 unsigned m;
876 for( m = 1; m <= 0x100; m <<= 1 )
877 {
878 if( exported[i] & m )
879 ++bit_count;
880 }
881 TEST_ASSERT( bit_count % 2 != 0 );
882 }
883 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200884 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200885#endif
886
887#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200888 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskined14664a2018-08-10 19:07:32 +0200889 {
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200890 uint8_t *p = exported;
891 uint8_t *end = exported + exported_length;
892 size_t len;
893 /* RSAPrivateKey ::= SEQUENCE {
Gilles Peskinedea46cf2018-08-21 16:12:54 +0200894 * version INTEGER, -- must be 0
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200895 * modulus INTEGER, -- n
896 * publicExponent INTEGER, -- e
897 * privateExponent INTEGER, -- d
898 * prime1 INTEGER, -- p
899 * prime2 INTEGER, -- q
900 * exponent1 INTEGER, -- d mod (p-1)
901 * exponent2 INTEGER, -- d mod (q-1)
902 * coefficient INTEGER, -- (inverse of q) mod p
903 * }
904 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100905 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
906 MBEDTLS_ASN1_SEQUENCE |
907 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
908 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200909 if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
910 goto exit;
911 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
912 goto exit;
913 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
914 goto exit;
915 /* Require d to be at least half the size of n. */
916 if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
917 goto exit;
918 /* Require p and q to be at most half the size of n, rounded up. */
919 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
920 goto exit;
921 if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
922 goto exit;
923 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
924 goto exit;
925 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
926 goto exit;
927 if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
928 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100929 TEST_EQUAL( p, end );
Gilles Peskine0f915f12018-12-17 23:35:42 +0100930 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200931 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200932#endif /* MBEDTLS_RSA_C */
933
934#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200935 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
Gilles Peskined14664a2018-08-10 19:07:32 +0200936 {
Gilles Peskine5b802a32018-10-29 19:21:41 +0100937 /* Just the secret value */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100938 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskine5b802a32018-10-29 19:21:41 +0100939 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200940 else
Gilles Peskined14664a2018-08-10 19:07:32 +0200941#endif /* MBEDTLS_ECP_C */
942
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200943 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
944 {
945 uint8_t *p = exported;
946 uint8_t *end = exported + exported_length;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200947#if defined(MBEDTLS_RSA_C)
948 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
949 {
Jaeden Amerof7dca862019-06-27 17:31:33 +0100950 size_t len;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200951 /* RSAPublicKey ::= SEQUENCE {
952 * modulus INTEGER, -- n
953 * publicExponent INTEGER } -- e
954 */
Gilles Peskinefe11b722018-12-18 00:24:04 +0100955 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
956 MBEDTLS_ASN1_SEQUENCE |
Gilles Peskinef812dcf2018-12-18 00:33:25 +0100957 MBEDTLS_ASN1_CONSTRUCTED ),
958 0 );
Gilles Peskinefe11b722018-12-18 00:24:04 +0100959 TEST_EQUAL( p + len, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200960 if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
961 goto exit;
962 if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
963 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +0100964 TEST_EQUAL( p, end );
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200965 }
966 else
967#endif /* MBEDTLS_RSA_C */
968#if defined(MBEDTLS_ECP_C)
969 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
970 {
Steven Cooreman3fa684e2020-07-30 15:04:07 +0200971 if( PSA_KEY_TYPE_ECC_GET_FAMILY( type ) == PSA_ECC_FAMILY_MONTGOMERY )
972 {
973 /* The representation of an ECC Montgomery public key is
974 * the raw compressed point */
975 TEST_EQUAL( p + PSA_BITS_TO_BYTES( bits ), end );
976 }
977 else
978 {
979 /* The representation of an ECC Weierstrass public key is:
980 * - The byte 0x04;
981 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
982 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
983 * - where m is the bit size associated with the curve.
984 */
985 TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
986 TEST_EQUAL( p[0], 4 );
987 }
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200988 }
989 else
990#endif /* MBEDTLS_ECP_C */
991 {
Jaeden Amero594a3302018-10-26 17:07:22 +0100992 char message[47];
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200993 mbedtls_snprintf( message, sizeof( message ),
994 "No sanity check for public key type=0x%08lx",
995 (unsigned long) type );
996 test_fail( message, __LINE__, __FILE__ );
Gilles Peskineb16841e2019-10-10 20:36:12 +0200997 (void) p;
998 (void) end;
Gilles Peskinedd2f95b2018-08-11 01:22:42 +0200999 return( 0 );
1000 }
1001 }
1002 else
1003
1004 {
1005 /* No sanity checks for other types */
1006 }
1007
1008 return( 1 );
Gilles Peskined14664a2018-08-10 19:07:32 +02001009
1010exit:
Gilles Peskinedd2f95b2018-08-11 01:22:42 +02001011 return( 0 );
Gilles Peskined14664a2018-08-10 19:07:32 +02001012}
1013
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001014static int exercise_export_key( psa_key_handle_t handle,
Gilles Peskined14664a2018-08-10 19:07:32 +02001015 psa_key_usage_t usage )
1016{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001017 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +02001018 uint8_t *exported = NULL;
1019 size_t exported_size = 0;
1020 size_t exported_length = 0;
1021 int ok = 0;
1022
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001023 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskineacec7b6f2018-09-13 20:34:11 +02001024
1025 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001026 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +02001027 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001028 TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
1029 PSA_ERROR_NOT_PERMITTED );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001030 ok = 1;
1031 goto exit;
Gilles Peskined14664a2018-08-10 19:07:32 +02001032 }
1033
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001034 exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
1035 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001036 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +02001037
Gilles Peskine8817f612018-12-18 00:18:46 +01001038 PSA_ASSERT( psa_export_key( handle,
1039 exported, exported_size,
1040 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001041 ok = exported_key_sanity_check( psa_get_key_type( &attributes ),
1042 psa_get_key_bits( &attributes ),
1043 exported, exported_length );
Gilles Peskined14664a2018-08-10 19:07:32 +02001044
1045exit:
1046 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001047 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +02001048 return( ok );
1049}
1050
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001051static int exercise_export_public_key( psa_key_handle_t handle )
Gilles Peskined14664a2018-08-10 19:07:32 +02001052{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001053 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined14664a2018-08-10 19:07:32 +02001054 psa_key_type_t public_type;
Gilles Peskined14664a2018-08-10 19:07:32 +02001055 uint8_t *exported = NULL;
1056 size_t exported_size = 0;
1057 size_t exported_length = 0;
1058 int ok = 0;
1059
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001060 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1061 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
Gilles Peskined14664a2018-08-10 19:07:32 +02001062 {
Gilles Peskinef812dcf2018-12-18 00:33:25 +01001063 TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01001064 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined14664a2018-08-10 19:07:32 +02001065 return( 1 );
1066 }
1067
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001068 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001069 psa_get_key_type( &attributes ) );
1070 exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
1071 psa_get_key_bits( &attributes ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001072 ASSERT_ALLOC( exported, exported_size );
Gilles Peskined14664a2018-08-10 19:07:32 +02001073
Gilles Peskine8817f612018-12-18 00:18:46 +01001074 PSA_ASSERT( psa_export_public_key( handle,
1075 exported, exported_size,
1076 &exported_length ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001077 ok = exported_key_sanity_check( public_type,
1078 psa_get_key_bits( &attributes ),
Gilles Peskined14664a2018-08-10 19:07:32 +02001079 exported, exported_length );
1080
1081exit:
1082 mbedtls_free( exported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001083 psa_reset_key_attributes( &attributes );
Gilles Peskined14664a2018-08-10 19:07:32 +02001084 return( ok );
1085}
1086
Gilles Peskinec9516fb2019-02-05 20:32:06 +01001087/** Do smoke tests on a key.
1088 *
1089 * Perform one of each operation indicated by \p alg (decrypt/encrypt,
1090 * sign/verify, or derivation) that is permitted according to \p usage.
1091 * \p usage and \p alg should correspond to the expected policy on the
1092 * key.
1093 *
1094 * Export the key if permitted by \p usage, and check that the output
1095 * looks sensible. If \p usage forbids export, check that
1096 * \p psa_export_key correctly rejects the attempt. If the key is
1097 * asymmetric, also check \p psa_export_public_key.
1098 *
1099 * If the key fails the tests, this function calls the test framework's
1100 * `test_fail` function and returns false. Otherwise this function returns
1101 * true. Therefore it should be used as follows:
1102 * ```
1103 * if( ! exercise_key( ... ) ) goto exit;
1104 * ```
1105 *
1106 * \param handle The key to exercise. It should be capable of performing
1107 * \p alg.
1108 * \param usage The usage flags to assume.
1109 * \param alg The algorithm to exercise.
1110 *
1111 * \retval 0 The key failed the smoke tests.
1112 * \retval 1 The key passed the smoke tests.
1113 */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001114static int exercise_key( psa_key_handle_t handle,
Gilles Peskine02b75072018-07-01 22:31:34 +02001115 psa_key_usage_t usage,
1116 psa_algorithm_t alg )
1117{
1118 int ok;
Gilles Peskine667c1112019-12-03 19:03:20 +01001119
1120 if( ! check_key_attributes_sanity( handle ) )
1121 return( 0 );
1122
Gilles Peskine02b75072018-07-01 22:31:34 +02001123 if( alg == 0 )
1124 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
1125 else if( PSA_ALG_IS_MAC( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001126 ok = exercise_mac_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001127 else if( PSA_ALG_IS_CIPHER( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001128 ok = exercise_cipher_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001129 else if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001130 ok = exercise_aead_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001131 else if( PSA_ALG_IS_SIGN( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001132 ok = exercise_signature_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001133 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001134 ok = exercise_asymmetric_encryption_key( handle, usage, alg );
Gilles Peskineea0fb492018-07-12 17:17:20 +02001135 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001136 ok = exercise_key_derivation_key( handle, usage, alg );
Gilles Peskine2e46e9c2019-04-11 21:24:55 +02001137 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
1138 ok = exercise_raw_key_agreement_key( handle, usage, alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02001139 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001140 ok = exercise_key_agreement_key( handle, usage, alg );
Gilles Peskine02b75072018-07-01 22:31:34 +02001141 else
1142 {
1143 char message[40];
1144 mbedtls_snprintf( message, sizeof( message ),
1145 "No code to exercise alg=0x%08lx",
1146 (unsigned long) alg );
1147 test_fail( message, __LINE__, __FILE__ );
1148 ok = 0;
1149 }
Gilles Peskined14664a2018-08-10 19:07:32 +02001150
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001151 ok = ok && exercise_export_key( handle, usage );
1152 ok = ok && exercise_export_public_key( handle );
Gilles Peskined14664a2018-08-10 19:07:32 +02001153
Gilles Peskine02b75072018-07-01 22:31:34 +02001154 return( ok );
1155}
1156
Gilles Peskine10df3412018-10-25 22:35:43 +02001157static psa_key_usage_t usage_to_exercise( psa_key_type_t type,
1158 psa_algorithm_t alg )
1159{
1160 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
1161 {
1162 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001163 PSA_KEY_USAGE_VERIFY_HASH :
1164 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH );
Gilles Peskine10df3412018-10-25 22:35:43 +02001165 }
1166 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1167 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1168 {
1169 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1170 PSA_KEY_USAGE_ENCRYPT :
1171 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1172 }
1173 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1174 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1175 {
1176 return( PSA_KEY_USAGE_DERIVE );
1177 }
1178 else
1179 {
1180 return( 0 );
1181 }
1182
1183}
Darryl Green0c6575a2018-11-07 16:05:30 +00001184
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001185static int test_operations_on_invalid_handle( psa_key_handle_t handle )
1186{
1187 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronecfb2372020-07-23 17:13:42 +02001188 mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make( 1, 0x6964 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001189 uint8_t buffer[1];
1190 size_t length;
1191 int ok = 0;
1192
Ronald Cronecfb2372020-07-23 17:13:42 +02001193 psa_set_key_id( &attributes, key_id );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001194 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
1195 psa_set_key_algorithm( &attributes, PSA_ALG_CTR );
1196 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
1197 TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
Ronald Cron432e19c2020-09-17 14:12:30 +02001198 PSA_ERROR_DOES_NOT_EXIST );
Ronald Cronecfb2372020-07-23 17:13:42 +02001199 TEST_EQUAL(
1200 MBEDTLS_SVC_KEY_ID_GET_KEY_ID( psa_get_key_id( &attributes ) ), 0 );
1201 TEST_EQUAL(
1202 MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( psa_get_key_id( &attributes ) ), 0 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02001203 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001204 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 );
1207 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
1208
1209 TEST_EQUAL( psa_export_key( handle,
1210 buffer, sizeof( buffer ), &length ),
Ronald Cron432e19c2020-09-17 14:12:30 +02001211 PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001212 TEST_EQUAL( psa_export_public_key( handle,
1213 buffer, sizeof( buffer ), &length ),
Ronald Cron432e19c2020-09-17 14:12:30 +02001214 PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001215
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001216 ok = 1;
1217
1218exit:
1219 psa_reset_key_attributes( &attributes );
1220 return( ok );
1221}
1222
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001223/* Assert that a key isn't reported as having a slot number. */
1224#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1225#define ASSERT_NO_SLOT_NUMBER( attributes ) \
1226 do \
1227 { \
1228 psa_key_slot_number_t ASSERT_NO_SLOT_NUMBER_slot_number; \
1229 TEST_EQUAL( psa_get_key_slot_number( \
1230 attributes, \
1231 &ASSERT_NO_SLOT_NUMBER_slot_number ), \
1232 PSA_ERROR_INVALID_ARGUMENT ); \
1233 } \
1234 while( 0 )
1235#else /* MBEDTLS_PSA_CRYPTO_SE_C */
1236#define ASSERT_NO_SLOT_NUMBER( attributes ) \
1237 ( (void) 0 )
1238#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1239
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001240/* An overapproximation of the amount of storage needed for a key of the
1241 * given type and with the given content. The API doesn't make it easy
1242 * to find a good value for the size. The current implementation doesn't
1243 * care about the value anyway. */
1244#define KEY_BITS_FROM_DATA( type, data ) \
1245 ( data )->len
1246
Darryl Green0c6575a2018-11-07 16:05:30 +00001247typedef enum {
1248 IMPORT_KEY = 0,
1249 GENERATE_KEY = 1,
1250 DERIVE_KEY = 2
1251} generate_method;
1252
Gilles Peskinee59236f2018-01-27 23:32:46 +01001253/* END_HEADER */
1254
1255/* BEGIN_DEPENDENCIES
1256 * depends_on:MBEDTLS_PSA_CRYPTO_C
1257 * END_DEPENDENCIES
1258 */
1259
1260/* BEGIN_CASE */
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001261void static_checks( )
1262{
1263 size_t max_truncated_mac_size =
1264 PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
1265
1266 /* Check that the length for a truncated MAC always fits in the algorithm
1267 * encoding. The shifted mask is the maximum truncated value. The
1268 * untruncated algorithm may be one byte larger. */
1269 TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
Gilles Peskine841b14b2019-11-26 17:37:37 +01001270
1271#if defined(MBEDTLS_TEST_DEPRECATED)
1272 /* Check deprecated constants. */
1273 TEST_EQUAL( PSA_ERROR_UNKNOWN_ERROR, PSA_ERROR_GENERIC_ERROR );
1274 TEST_EQUAL( PSA_ERROR_OCCUPIED_SLOT, PSA_ERROR_ALREADY_EXISTS );
1275 TEST_EQUAL( PSA_ERROR_EMPTY_SLOT, PSA_ERROR_DOES_NOT_EXIST );
1276 TEST_EQUAL( PSA_ERROR_INSUFFICIENT_CAPACITY, PSA_ERROR_INSUFFICIENT_DATA );
1277 TEST_EQUAL( PSA_ERROR_TAMPERING_DETECTED, PSA_ERROR_CORRUPTION_DETECTED );
1278 TEST_EQUAL( PSA_KEY_USAGE_SIGN, PSA_KEY_USAGE_SIGN_HASH );
1279 TEST_EQUAL( PSA_KEY_USAGE_VERIFY, PSA_KEY_USAGE_VERIFY_HASH );
1280 TEST_EQUAL( PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE, PSA_SIGNATURE_MAX_SIZE );
Gilles Peskineb87b7192019-12-04 16:24:10 +01001281
Paul Elliott8ff510a2020-06-02 17:19:28 +01001282 TEST_EQUAL( PSA_ECC_CURVE_SECP160K1, PSA_ECC_FAMILY_SECP_K1 );
1283 TEST_EQUAL( PSA_ECC_CURVE_SECP192K1, PSA_ECC_FAMILY_SECP_K1 );
1284 TEST_EQUAL( PSA_ECC_CURVE_SECP224K1, PSA_ECC_FAMILY_SECP_K1 );
1285 TEST_EQUAL( PSA_ECC_CURVE_SECP256K1, PSA_ECC_FAMILY_SECP_K1 );
1286 TEST_EQUAL( PSA_ECC_CURVE_SECP160R1, PSA_ECC_FAMILY_SECP_R1 );
1287 TEST_EQUAL( PSA_ECC_CURVE_SECP192R1, PSA_ECC_FAMILY_SECP_R1 );
1288 TEST_EQUAL( PSA_ECC_CURVE_SECP224R1, PSA_ECC_FAMILY_SECP_R1 );
1289 TEST_EQUAL( PSA_ECC_CURVE_SECP256R1, PSA_ECC_FAMILY_SECP_R1 );
1290 TEST_EQUAL( PSA_ECC_CURVE_SECP384R1, PSA_ECC_FAMILY_SECP_R1 );
1291 TEST_EQUAL( PSA_ECC_CURVE_SECP521R1, PSA_ECC_FAMILY_SECP_R1 );
1292 TEST_EQUAL( PSA_ECC_CURVE_SECP160R2, PSA_ECC_FAMILY_SECP_R2 );
1293 TEST_EQUAL( PSA_ECC_CURVE_SECT163K1, PSA_ECC_FAMILY_SECT_K1 );
1294 TEST_EQUAL( PSA_ECC_CURVE_SECT233K1, PSA_ECC_FAMILY_SECT_K1 );
1295 TEST_EQUAL( PSA_ECC_CURVE_SECT239K1, PSA_ECC_FAMILY_SECT_K1 );
1296 TEST_EQUAL( PSA_ECC_CURVE_SECT283K1, PSA_ECC_FAMILY_SECT_K1 );
1297 TEST_EQUAL( PSA_ECC_CURVE_SECT409K1, PSA_ECC_FAMILY_SECT_K1 );
1298 TEST_EQUAL( PSA_ECC_CURVE_SECT571K1, PSA_ECC_FAMILY_SECT_K1 );
1299 TEST_EQUAL( PSA_ECC_CURVE_SECT163R1, PSA_ECC_FAMILY_SECT_R1 );
1300 TEST_EQUAL( PSA_ECC_CURVE_SECT193R1, PSA_ECC_FAMILY_SECT_R1 );
1301 TEST_EQUAL( PSA_ECC_CURVE_SECT233R1, PSA_ECC_FAMILY_SECT_R1 );
1302 TEST_EQUAL( PSA_ECC_CURVE_SECT283R1, PSA_ECC_FAMILY_SECT_R1 );
1303 TEST_EQUAL( PSA_ECC_CURVE_SECT409R1, PSA_ECC_FAMILY_SECT_R1 );
1304 TEST_EQUAL( PSA_ECC_CURVE_SECT571R1, PSA_ECC_FAMILY_SECT_R1 );
1305 TEST_EQUAL( PSA_ECC_CURVE_SECT163R2, PSA_ECC_FAMILY_SECT_R2 );
1306 TEST_EQUAL( PSA_ECC_CURVE_SECT193R2, PSA_ECC_FAMILY_SECT_R2 );
1307 TEST_EQUAL( PSA_ECC_CURVE_BRAINPOOL_P256R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1 );
1308 TEST_EQUAL( PSA_ECC_CURVE_BRAINPOOL_P384R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1 );
1309 TEST_EQUAL( PSA_ECC_CURVE_BRAINPOOL_P512R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1 );
1310 TEST_EQUAL( PSA_ECC_CURVE_CURVE25519, PSA_ECC_FAMILY_MONTGOMERY );
1311 TEST_EQUAL( PSA_ECC_CURVE_CURVE448, PSA_ECC_FAMILY_MONTGOMERY );
1312
1313 TEST_EQUAL( PSA_ECC_CURVE_SECP_K1, PSA_ECC_FAMILY_SECP_K1 );
1314 TEST_EQUAL( PSA_ECC_CURVE_SECP_R1, PSA_ECC_FAMILY_SECP_R1 );
1315 TEST_EQUAL( PSA_ECC_CURVE_SECP_R2, PSA_ECC_FAMILY_SECP_R2 );
1316 TEST_EQUAL( PSA_ECC_CURVE_SECT_K1, PSA_ECC_FAMILY_SECT_K1 );
1317 TEST_EQUAL( PSA_ECC_CURVE_SECT_R1, PSA_ECC_FAMILY_SECT_R1 );
1318 TEST_EQUAL( PSA_ECC_CURVE_SECT_R2, PSA_ECC_FAMILY_SECT_R2 );
1319 TEST_EQUAL( PSA_ECC_CURVE_BRAINPOOL_P_R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1 );
1320 TEST_EQUAL( PSA_ECC_CURVE_MONTGOMERY, PSA_ECC_FAMILY_MONTGOMERY );
Gilles Peskineb87b7192019-12-04 16:24:10 +01001321
Paul Elliott75e27032020-06-03 15:17:39 +01001322 TEST_EQUAL( PSA_DH_GROUP_FFDHE2048, PSA_DH_FAMILY_RFC7919 );
1323 TEST_EQUAL( PSA_DH_GROUP_FFDHE3072, PSA_DH_FAMILY_RFC7919 );
1324 TEST_EQUAL( PSA_DH_GROUP_FFDHE4096, PSA_DH_FAMILY_RFC7919 );
1325 TEST_EQUAL( PSA_DH_GROUP_FFDHE6144, PSA_DH_FAMILY_RFC7919 );
1326 TEST_EQUAL( PSA_DH_GROUP_FFDHE8192, PSA_DH_FAMILY_RFC7919 );
1327
1328 TEST_EQUAL( PSA_DH_GROUP_RFC7919, PSA_DH_FAMILY_RFC7919 );
1329 TEST_EQUAL( PSA_DH_GROUP_CUSTOM, PSA_DH_FAMILY_CUSTOM );
Gilles Peskineb87b7192019-12-04 16:24:10 +01001330#endif
Gilles Peskinee1f2d7d2018-08-21 14:54:54 +02001331}
1332/* END_CASE */
1333
1334/* BEGIN_CASE */
Ronald Cron81e00502020-07-28 15:06:14 +02001335void attributes_set_get( int owner_id_arg, int id_arg, int lifetime_arg,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001336 int usage_flags_arg, int alg_arg,
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001337 int type_arg, int bits_arg )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001338{
Gilles Peskine4747d192019-04-17 15:05:45 +02001339 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cron81e00502020-07-28 15:06:14 +02001340 mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make( owner_id_arg, id_arg );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001341 psa_key_lifetime_t lifetime = lifetime_arg;
1342 psa_key_usage_t usage_flags = usage_flags_arg;
1343 psa_algorithm_t alg = alg_arg;
1344 psa_key_type_t type = type_arg;
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001345 size_t bits = bits_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001346
Ronald Cronecfb2372020-07-23 17:13:42 +02001347 TEST_EQUAL(
1348 MBEDTLS_SVC_KEY_ID_GET_KEY_ID( psa_get_key_id( &attributes ) ), 0 );
1349 TEST_EQUAL(
1350 MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( psa_get_key_id( &attributes ) ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001351 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1352 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1353 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1354 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001355 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001356
Gilles Peskinec87af662019-05-15 16:12:22 +02001357 psa_set_key_id( &attributes, id );
1358 psa_set_key_lifetime( &attributes, lifetime );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001359 psa_set_key_usage_flags( &attributes, usage_flags );
1360 psa_set_key_algorithm( &attributes, alg );
1361 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001362 psa_set_key_bits( &attributes, bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001363
Ronald Cronecfb2372020-07-23 17:13:42 +02001364 TEST_ASSERT( mbedtls_svc_key_id_equal(
1365 psa_get_key_id( &attributes ), id ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001366 TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
1367 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
1368 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
1369 TEST_EQUAL( psa_get_key_type( &attributes ), type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001370 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001371
1372 psa_reset_key_attributes( &attributes );
1373
Ronald Cronecfb2372020-07-23 17:13:42 +02001374 TEST_EQUAL(
1375 MBEDTLS_SVC_KEY_ID_GET_KEY_ID( psa_get_key_id( &attributes ) ), 0 );
1376 TEST_EQUAL(
1377 MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( psa_get_key_id( &attributes ) ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001378 TEST_EQUAL( psa_get_key_lifetime( &attributes ), 0 );
1379 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
1380 TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
1381 TEST_EQUAL( psa_get_key_type( &attributes ), 0 );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02001382 TEST_EQUAL( psa_get_key_bits( &attributes ), 0 );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001383}
1384/* END_CASE */
1385
1386/* BEGIN_CASE */
Ronald Cronecfb2372020-07-23 17:13:42 +02001387void persistence_attributes( int id1_arg, int owner_id1_arg, int lifetime_arg,
1388 int id2_arg, int owner_id2_arg,
1389 int expected_id_arg, int expected_owner_id_arg,
1390 int expected_lifetime_arg )
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001391{
1392 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronecfb2372020-07-23 17:13:42 +02001393 mbedtls_svc_key_id_t id1 =
1394 mbedtls_svc_key_id_make( owner_id1_arg, id1_arg );
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001395 psa_key_lifetime_t lifetime = lifetime_arg;
Ronald Cronecfb2372020-07-23 17:13:42 +02001396 mbedtls_svc_key_id_t id2 =
1397 mbedtls_svc_key_id_make( owner_id2_arg, id2_arg );
Ronald Cron71016a92020-08-28 19:01:50 +02001398 mbedtls_svc_key_id_t expected_id =
Ronald Cronecfb2372020-07-23 17:13:42 +02001399 mbedtls_svc_key_id_make( expected_owner_id_arg, expected_id_arg );
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001400 psa_key_lifetime_t expected_lifetime = expected_lifetime_arg;
1401
1402 if( id1_arg != -1 )
1403 psa_set_key_id( &attributes, id1 );
1404 if( lifetime_arg != -1 )
1405 psa_set_key_lifetime( &attributes, lifetime );
1406 if( id2_arg != -1 )
1407 psa_set_key_id( &attributes, id2 );
1408
Ronald Cronecfb2372020-07-23 17:13:42 +02001409 TEST_ASSERT( mbedtls_svc_key_id_equal(
1410 psa_get_key_id( &attributes ), expected_id ) );
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001411 TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime );
1412}
1413/* END_CASE */
1414
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001415/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_SE_C */
1416void slot_number_attribute( )
1417{
1418 psa_key_slot_number_t slot_number = 0xdeadbeef;
1419 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1420
1421 /* Initially, there is no slot number. */
1422 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1423 PSA_ERROR_INVALID_ARGUMENT );
1424
1425 /* Test setting a slot number. */
1426 psa_set_key_slot_number( &attributes, 0 );
1427 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1428 TEST_EQUAL( slot_number, 0 );
1429
1430 /* Test changing the slot number. */
1431 psa_set_key_slot_number( &attributes, 42 );
1432 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1433 TEST_EQUAL( slot_number, 42 );
1434
1435 /* Test clearing the slot number. */
1436 psa_clear_key_slot_number( &attributes );
1437 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1438 PSA_ERROR_INVALID_ARGUMENT );
1439
1440 /* Clearing again should have no effect. */
1441 psa_clear_key_slot_number( &attributes );
1442 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1443 PSA_ERROR_INVALID_ARGUMENT );
1444
1445 /* Test that reset clears the slot number. */
1446 psa_set_key_slot_number( &attributes, 42 );
1447 PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) );
1448 TEST_EQUAL( slot_number, 42 );
1449 psa_reset_key_attributes( &attributes );
1450 TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ),
1451 PSA_ERROR_INVALID_ARGUMENT );
1452}
1453/* END_CASE */
1454
Gilles Peskinedd835cb2019-05-15 16:14:57 +02001455/* BEGIN_CASE */
Gilles Peskine6edfa292019-07-31 15:53:45 +02001456void import_with_policy( int type_arg,
1457 int usage_arg, int alg_arg,
1458 int expected_status_arg )
1459{
1460 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1461 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cron91e95152020-07-30 17:48:03 +02001462 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine6edfa292019-07-31 15:53:45 +02001463 psa_key_type_t type = type_arg;
1464 psa_key_usage_t usage = usage_arg;
1465 psa_algorithm_t alg = alg_arg;
1466 psa_status_t expected_status = expected_status_arg;
1467 const uint8_t key_material[16] = {0};
1468 psa_status_t status;
1469
1470 PSA_ASSERT( psa_crypto_init( ) );
1471
1472 psa_set_key_type( &attributes, type );
1473 psa_set_key_usage_flags( &attributes, usage );
1474 psa_set_key_algorithm( &attributes, alg );
1475
1476 status = psa_import_key( &attributes,
1477 key_material, sizeof( key_material ),
1478 &handle );
1479 TEST_EQUAL( status, expected_status );
1480 if( status != PSA_SUCCESS )
1481 goto exit;
1482
1483 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1484 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1485 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
1486 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001487 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001488
1489 PSA_ASSERT( psa_destroy_key( handle ) );
1490 test_operations_on_invalid_handle( handle );
1491
1492exit:
1493 psa_destroy_key( handle );
1494 psa_reset_key_attributes( &got_attributes );
1495 PSA_DONE( );
1496}
1497/* END_CASE */
1498
1499/* BEGIN_CASE */
1500void import_with_data( data_t *data, int type_arg,
1501 int attr_bits_arg,
1502 int expected_status_arg )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001503{
1504 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1505 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cron91e95152020-07-30 17:48:03 +02001506 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001507 psa_key_type_t type = type_arg;
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001508 size_t attr_bits = attr_bits_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001509 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001510 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001511
Gilles Peskine8817f612018-12-18 00:18:46 +01001512 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001513
Gilles Peskine4747d192019-04-17 15:05:45 +02001514 psa_set_key_type( &attributes, type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001515 psa_set_key_bits( &attributes, attr_bits );
Gilles Peskine6edfa292019-07-31 15:53:45 +02001516
Gilles Peskine73676cb2019-05-15 20:15:10 +02001517 status = psa_import_key( &attributes, data->x, data->len, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001518 TEST_EQUAL( status, expected_status );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001519 if( status != PSA_SUCCESS )
1520 goto exit;
1521
1522 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1523 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
Gilles Peskine8fb3a9e2019-05-03 16:59:21 +02001524 if( attr_bits != 0 )
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001525 TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001526 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001527
1528 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001529 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001530
1531exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001532 psa_destroy_key( handle );
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 */
1537
1538/* BEGIN_CASE */
Gilles Peskinec744d992019-07-30 17:26:54 +02001539void import_large_key( int type_arg, int byte_size_arg,
1540 int expected_status_arg )
1541{
1542 psa_key_type_t type = type_arg;
1543 size_t byte_size = byte_size_arg;
1544 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1545 psa_status_t expected_status = expected_status_arg;
Ronald Cron91e95152020-07-30 17:48:03 +02001546 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinec744d992019-07-30 17:26:54 +02001547 psa_status_t status;
1548 uint8_t *buffer = NULL;
1549 size_t buffer_size = byte_size + 1;
1550 size_t n;
1551
1552 /* It would be better to skip the test than fail it if the allocation
1553 * fails, but the test framework doesn't support this yet. */
1554 ASSERT_ALLOC( buffer, buffer_size );
1555 memset( buffer, 'K', byte_size );
1556
1557 PSA_ASSERT( psa_crypto_init( ) );
1558
1559 /* Try importing the key */
1560 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1561 psa_set_key_type( &attributes, type );
1562 status = psa_import_key( &attributes, buffer, byte_size, &handle );
1563 TEST_EQUAL( status, expected_status );
1564
1565 if( status == PSA_SUCCESS )
1566 {
1567 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1568 TEST_EQUAL( psa_get_key_type( &attributes ), type );
1569 TEST_EQUAL( psa_get_key_bits( &attributes ),
1570 PSA_BYTES_TO_BITS( byte_size ) );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001571 ASSERT_NO_SLOT_NUMBER( &attributes );
Gilles Peskinec744d992019-07-30 17:26:54 +02001572 memset( buffer, 0, byte_size + 1 );
1573 PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) );
1574 for( n = 0; n < byte_size; n++ )
1575 TEST_EQUAL( buffer[n], 'K' );
1576 for( n = byte_size; n < buffer_size; n++ )
1577 TEST_EQUAL( buffer[n], 0 );
1578 }
1579
1580exit:
1581 psa_destroy_key( handle );
1582 PSA_DONE( );
1583 mbedtls_free( buffer );
1584}
1585/* END_CASE */
1586
1587/* BEGIN_CASE */
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001588void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
1589{
Ronald Cron91e95152020-07-30 17:48:03 +02001590 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001591 size_t bits = bits_arg;
1592 psa_status_t expected_status = expected_status_arg;
1593 psa_status_t status;
1594 psa_key_type_t type =
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001595 keypair ? PSA_KEY_TYPE_RSA_KEY_PAIR : PSA_KEY_TYPE_RSA_PUBLIC_KEY;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001596 size_t buffer_size = /* Slight overapproximations */
1597 keypair ? bits * 9 / 16 + 80 : bits / 8 + 20;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001598 unsigned char *buffer = NULL;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001599 unsigned char *p;
1600 int ret;
1601 size_t length;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001602 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001603
Gilles Peskine8817f612018-12-18 00:18:46 +01001604 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001605 ASSERT_ALLOC( buffer, buffer_size );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001606
1607 TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
1608 bits, keypair ) ) >= 0 );
1609 length = ret;
1610
1611 /* Try importing the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001612 psa_set_key_type( &attributes, type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02001613 status = psa_import_key( &attributes, p, length, &handle );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001614 TEST_EQUAL( status, expected_status );
Gilles Peskine76b29a72019-05-28 14:08:50 +02001615
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001616 if( status == PSA_SUCCESS )
Gilles Peskine8817f612018-12-18 00:18:46 +01001617 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001618
1619exit:
1620 mbedtls_free( buffer );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001621 PSA_DONE( );
Gilles Peskine0b352bc2018-06-28 00:16:11 +02001622}
1623/* END_CASE */
1624
1625/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001626void import_export( data_t *data,
Moran Pekera964a8f2018-06-04 18:42:36 +03001627 int type_arg,
Gilles Peskine1ecf92c22019-05-24 15:00:06 +02001628 int usage_arg, int alg_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001629 int expected_bits,
1630 int export_size_delta,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001631 int expected_export_status_arg,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001632 int canonical_input )
1633{
Ronald Cron91e95152020-07-30 17:48:03 +02001634 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001635 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001636 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001637 psa_status_t expected_export_status = expected_export_status_arg;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001638 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001639 unsigned char *exported = NULL;
1640 unsigned char *reexported = NULL;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001641 size_t export_size;
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001642 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001643 size_t reexported_length;
Gilles Peskine4747d192019-04-17 15:05:45 +02001644 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001645 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001646
Moran Pekercb088e72018-07-17 17:36:59 +03001647 export_size = (ptrdiff_t) data->len + export_size_delta;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001648 ASSERT_ALLOC( exported, export_size );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001649 if( ! canonical_input )
Gilles Peskine8cebbba2018-09-27 13:54:18 +02001650 ASSERT_ALLOC( reexported, export_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01001651 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001652
Gilles Peskine4747d192019-04-17 15:05:45 +02001653 psa_set_key_usage_flags( &attributes, usage_arg );
1654 psa_set_key_algorithm( &attributes, alg );
1655 psa_set_key_type( &attributes, type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07001656
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001657 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001658 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001659
1660 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001661 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1662 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1663 TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits );
Gilles Peskine5fe5e272019-08-02 20:30:01 +02001664 ASSERT_NO_SLOT_NUMBER( &got_attributes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001665
1666 /* Export the key */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001667 status = psa_export_key( handle,
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001668 exported, export_size,
1669 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001670 TEST_EQUAL( status, expected_export_status );
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001671
1672 /* The exported length must be set by psa_export_key() to a value between 0
1673 * and export_size. On errors, the exported length must be 0. */
1674 TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
1675 TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
1676 TEST_ASSERT( exported_length <= export_size );
1677
Gilles Peskinea7aa4422018-08-14 15:17:54 +02001678 TEST_ASSERT( mem_is_char( exported + exported_length, 0,
Gilles Peskine3f669c32018-06-21 09:21:51 +02001679 export_size - exported_length ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001680 if( status != PSA_SUCCESS )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001681 {
Gilles Peskinefe11b722018-12-18 00:24:04 +01001682 TEST_EQUAL( exported_length, 0 );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001683 goto destroy;
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001684 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001685
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001686 if( ! exercise_export_key( handle, usage_arg ) )
Gilles Peskine8f609232018-08-11 01:24:55 +02001687 goto exit;
1688
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001689 if( canonical_input )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001690 ASSERT_COMPARE( data->x, data->len, exported, exported_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001691 else
1692 {
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001693 psa_key_handle_t handle2;
Gilles Peskine049c7532019-05-15 20:22:09 +02001694 PSA_ASSERT( psa_import_key( &attributes, exported, exported_length,
1695 &handle2 ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01001696 PSA_ASSERT( psa_export_key( handle2,
1697 reexported,
1698 export_size,
1699 &reexported_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02001700 ASSERT_COMPARE( exported, exported_length,
1701 reexported, reexported_length );
Gilles Peskine8817f612018-12-18 00:18:46 +01001702 PSA_ASSERT( psa_close_key( handle2 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001703 }
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001704 TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001705
1706destroy:
1707 /* Destroy the key */
Gilles Peskine8817f612018-12-18 00:18:46 +01001708 PSA_ASSERT( psa_destroy_key( handle ) );
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001709 test_operations_on_invalid_handle( handle );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001710
1711exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001712 mbedtls_free( exported );
1713 mbedtls_free( reexported );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001714 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001715 PSA_DONE( );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001716}
1717/* END_CASE */
Gilles Peskine20035e32018-02-03 22:44:14 +01001718
Moran Pekerf709f4a2018-06-06 17:26:04 +03001719/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03001720void import_export_public_key( data_t *data,
Gilles Peskine2d277862018-06-18 15:41:12 +02001721 int type_arg,
1722 int alg_arg,
Gilles Peskine49c25912018-10-29 15:15:31 +01001723 int export_size_delta,
1724 int expected_export_status_arg,
1725 data_t *expected_public_key )
Moran Pekerf709f4a2018-06-06 17:26:04 +03001726{
Ronald Cron91e95152020-07-30 17:48:03 +02001727 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001728 psa_key_type_t type = type_arg;
Gilles Peskine4abf7412018-06-18 16:35:34 +02001729 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02001730 psa_status_t expected_export_status = expected_export_status_arg;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001731 psa_status_t status;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001732 unsigned char *exported = NULL;
Gilles Peskine49c25912018-10-29 15:15:31 +01001733 size_t export_size = expected_public_key->len + export_size_delta;
Jaeden Amero2a671e92018-06-27 17:47:40 +01001734 size_t exported_length = INVALID_EXPORT_LENGTH;
Gilles Peskine4747d192019-04-17 15:05:45 +02001735 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerf709f4a2018-06-06 17:26:04 +03001736
Gilles Peskine8817f612018-12-18 00:18:46 +01001737 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001738
Gilles Peskine4747d192019-04-17 15:05:45 +02001739 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1740 psa_set_key_algorithm( &attributes, alg );
1741 psa_set_key_type( &attributes, type );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001742
1743 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001744 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001745
Gilles Peskine49c25912018-10-29 15:15:31 +01001746 /* Export the public key */
1747 ASSERT_ALLOC( exported, export_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001748 status = psa_export_public_key( handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001749 exported, export_size,
1750 &exported_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01001751 TEST_EQUAL( status, expected_export_status );
Gilles Peskine49c25912018-10-29 15:15:31 +01001752 if( status == PSA_SUCCESS )
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001753 {
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001754 psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001755 size_t bits;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001756 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
1757 bits = psa_get_key_bits( &attributes );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001758 TEST_ASSERT( expected_public_key->len <=
1759 PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
Gilles Peskine49c25912018-10-29 15:15:31 +01001760 ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
1761 exported, exported_length );
Gilles Peskined8b7d4f2018-10-29 15:18:41 +01001762 }
Moran Pekerf709f4a2018-06-06 17:26:04 +03001763
1764exit:
itayzafrir3e02b3b2018-06-12 17:06:52 +03001765 mbedtls_free( exported );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001766 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001767 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001768 PSA_DONE( );
Moran Pekerf709f4a2018-06-06 17:26:04 +03001769}
1770/* END_CASE */
1771
Gilles Peskine20035e32018-02-03 22:44:14 +01001772/* BEGIN_CASE */
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001773void import_and_exercise_key( data_t *data,
1774 int type_arg,
1775 int bits_arg,
1776 int alg_arg )
1777{
Ronald Cron91e95152020-07-30 17:48:03 +02001778 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001779 psa_key_type_t type = type_arg;
1780 size_t bits = bits_arg;
1781 psa_algorithm_t alg = alg_arg;
Gilles Peskine10df3412018-10-25 22:35:43 +02001782 psa_key_usage_t usage = usage_to_exercise( type, alg );
Gilles Peskine4747d192019-04-17 15:05:45 +02001783 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001784 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001785
Gilles Peskine8817f612018-12-18 00:18:46 +01001786 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001787
Gilles Peskine4747d192019-04-17 15:05:45 +02001788 psa_set_key_usage_flags( &attributes, usage );
1789 psa_set_key_algorithm( &attributes, alg );
1790 psa_set_key_type( &attributes, type );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001791
1792 /* Import the key */
Gilles Peskine73676cb2019-05-15 20:15:10 +02001793 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001794
1795 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001796 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
1797 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
1798 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001799
1800 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001801 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02001802 goto exit;
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001803
Gilles Peskine4cf3a432019-04-18 22:28:52 +02001804 PSA_ASSERT( psa_destroy_key( handle ) );
1805 test_operations_on_invalid_handle( handle );
1806
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001807exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001808 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001809 psa_reset_key_attributes( &got_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001810 PSA_DONE( );
Gilles Peskinea680c7a2018-06-26 16:12:43 +02001811}
1812/* END_CASE */
1813
1814/* BEGIN_CASE */
Gilles Peskine06c28892019-11-26 18:07:46 +01001815void effective_key_attributes( int type_arg, int expected_type_arg,
1816 int bits_arg, int expected_bits_arg,
1817 int usage_arg, int expected_usage_arg,
1818 int alg_arg, int expected_alg_arg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001819{
Ronald Cron91e95152020-07-30 17:48:03 +02001820 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine1a960492019-11-26 17:12:21 +01001821 psa_key_type_t key_type = type_arg;
Gilles Peskine06c28892019-11-26 18:07:46 +01001822 psa_key_type_t expected_key_type = expected_type_arg;
Gilles Peskine1a960492019-11-26 17:12:21 +01001823 size_t bits = bits_arg;
Gilles Peskine06c28892019-11-26 18:07:46 +01001824 size_t expected_bits = expected_bits_arg;
Gilles Peskined5b33222018-06-18 22:20:03 +02001825 psa_algorithm_t alg = alg_arg;
Gilles Peskine06c28892019-11-26 18:07:46 +01001826 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskined5b33222018-06-18 22:20:03 +02001827 psa_key_usage_t usage = usage_arg;
Gilles Peskine06c28892019-11-26 18:07:46 +01001828 psa_key_usage_t expected_usage = expected_usage_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001829 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined5b33222018-06-18 22:20:03 +02001830
Gilles Peskine8817f612018-12-18 00:18:46 +01001831 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001832
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001833 psa_set_key_usage_flags( &attributes, usage );
1834 psa_set_key_algorithm( &attributes, alg );
1835 psa_set_key_type( &attributes, key_type );
Gilles Peskine1a960492019-11-26 17:12:21 +01001836 psa_set_key_bits( &attributes, bits );
Gilles Peskined5b33222018-06-18 22:20:03 +02001837
Gilles Peskine1a960492019-11-26 17:12:21 +01001838 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
1839 psa_reset_key_attributes( &attributes );
Gilles Peskined5b33222018-06-18 22:20:03 +02001840
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001841 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Gilles Peskine06c28892019-11-26 18:07:46 +01001842 TEST_EQUAL( psa_get_key_type( &attributes ), expected_key_type );
1843 TEST_EQUAL( psa_get_key_bits( &attributes ), expected_bits );
1844 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), expected_usage );
1845 TEST_EQUAL( psa_get_key_algorithm( &attributes ), expected_alg );
Gilles Peskined5b33222018-06-18 22:20:03 +02001846
1847exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001848 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02001849 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001850 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02001851}
1852/* END_CASE */
1853
1854/* BEGIN_CASE */
Gilles Peskine06c28892019-11-26 18:07:46 +01001855void check_key_policy( int type_arg, int bits_arg,
1856 int usage_arg, int alg_arg )
1857{
1858 test_effective_key_attributes( type_arg, type_arg, bits_arg, bits_arg,
1859 usage_arg, usage_arg, alg_arg, alg_arg );
1860 goto exit;
1861}
1862/* END_CASE */
1863
1864/* BEGIN_CASE */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001865void key_attributes_init( )
Jaeden Amero70261c52019-01-04 11:47:20 +00001866{
1867 /* Test each valid way of initializing the object, except for `= {0}`, as
1868 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
1869 * though it's OK by the C standard. We could test for this, but we'd need
1870 * to supress the Clang warning for the test. */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001871 psa_key_attributes_t func = psa_key_attributes_init( );
1872 psa_key_attributes_t init = PSA_KEY_ATTRIBUTES_INIT;
1873 psa_key_attributes_t zero;
Jaeden Amero70261c52019-01-04 11:47:20 +00001874
1875 memset( &zero, 0, sizeof( zero ) );
1876
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001877 TEST_EQUAL( psa_get_key_lifetime( &func ), PSA_KEY_LIFETIME_VOLATILE );
1878 TEST_EQUAL( psa_get_key_lifetime( &init ), PSA_KEY_LIFETIME_VOLATILE );
1879 TEST_EQUAL( psa_get_key_lifetime( &zero ), PSA_KEY_LIFETIME_VOLATILE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00001880
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001881 TEST_EQUAL( psa_get_key_type( &func ), 0 );
1882 TEST_EQUAL( psa_get_key_type( &init ), 0 );
1883 TEST_EQUAL( psa_get_key_type( &zero ), 0 );
1884
1885 TEST_EQUAL( psa_get_key_bits( &func ), 0 );
1886 TEST_EQUAL( psa_get_key_bits( &init ), 0 );
1887 TEST_EQUAL( psa_get_key_bits( &zero ), 0 );
1888
1889 TEST_EQUAL( psa_get_key_usage_flags( &func ), 0 );
1890 TEST_EQUAL( psa_get_key_usage_flags( &init ), 0 );
1891 TEST_EQUAL( psa_get_key_usage_flags( &zero ), 0 );
1892
1893 TEST_EQUAL( psa_get_key_algorithm( &func ), 0 );
1894 TEST_EQUAL( psa_get_key_algorithm( &init ), 0 );
1895 TEST_EQUAL( psa_get_key_algorithm( &zero ), 0 );
Jaeden Amero70261c52019-01-04 11:47:20 +00001896}
1897/* END_CASE */
1898
1899/* BEGIN_CASE */
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001900void mac_key_policy( int policy_usage,
1901 int policy_alg,
1902 int key_type,
1903 data_t *key_data,
1904 int exercise_alg )
Gilles Peskined5b33222018-06-18 22:20:03 +02001905{
Ronald Cron91e95152020-07-30 17:48:03 +02001906 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001907 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero769ce272019-01-04 11:48:03 +00001908 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001909 psa_status_t status;
1910 unsigned char mac[PSA_MAC_MAX_SIZE];
Gilles Peskined5b33222018-06-18 22:20:03 +02001911
Gilles Peskine8817f612018-12-18 00:18:46 +01001912 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001913
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001914 psa_set_key_usage_flags( &attributes, policy_usage );
1915 psa_set_key_algorithm( &attributes, policy_alg );
1916 psa_set_key_type( &attributes, key_type );
Gilles Peskined5b33222018-06-18 22:20:03 +02001917
Gilles Peskine049c7532019-05-15 20:22:09 +02001918 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1919 &handle ) );
Gilles Peskined5b33222018-06-18 22:20:03 +02001920
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001921 status = psa_mac_sign_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001922 if( policy_alg == exercise_alg &&
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001923 ( policy_usage & PSA_KEY_USAGE_SIGN_HASH ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001924 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001925 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001926 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001927 psa_mac_abort( &operation );
Gilles Peskined5b33222018-06-18 22:20:03 +02001928
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001929 memset( mac, 0, sizeof( mac ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001930 status = psa_mac_verify_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001931 if( policy_alg == exercise_alg &&
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001932 ( policy_usage & PSA_KEY_USAGE_VERIFY_HASH ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001933 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001934 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001935 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001936
1937exit:
1938 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001939 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001940 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001941}
1942/* END_CASE */
1943
1944/* BEGIN_CASE */
1945void cipher_key_policy( int policy_usage,
1946 int policy_alg,
1947 int key_type,
1948 data_t *key_data,
1949 int exercise_alg )
1950{
Ronald Cron91e95152020-07-30 17:48:03 +02001951 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001952 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero5bae2272019-01-04 11:48:27 +00001953 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001954 psa_status_t status;
1955
Gilles Peskine8817f612018-12-18 00:18:46 +01001956 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001957
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001958 psa_set_key_usage_flags( &attributes, policy_usage );
1959 psa_set_key_algorithm( &attributes, policy_alg );
1960 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001961
Gilles Peskine049c7532019-05-15 20:22:09 +02001962 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
1963 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001964
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001965 status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001966 if( policy_alg == exercise_alg &&
1967 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001968 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001969 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001970 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001971 psa_cipher_abort( &operation );
1972
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001973 status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001974 if( policy_alg == exercise_alg &&
1975 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01001976 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001977 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01001978 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001979
1980exit:
1981 psa_cipher_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01001982 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02001983 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001984}
1985/* END_CASE */
1986
1987/* BEGIN_CASE */
1988void aead_key_policy( int policy_usage,
1989 int policy_alg,
1990 int key_type,
1991 data_t *key_data,
1992 int nonce_length_arg,
1993 int tag_length_arg,
1994 int exercise_alg )
1995{
Ronald Cron91e95152020-07-30 17:48:03 +02001996 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02001997 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02001998 psa_status_t status;
1999 unsigned char nonce[16] = {0};
2000 size_t nonce_length = nonce_length_arg;
2001 unsigned char tag[16];
2002 size_t tag_length = tag_length_arg;
2003 size_t output_length;
2004
2005 TEST_ASSERT( nonce_length <= sizeof( nonce ) );
2006 TEST_ASSERT( tag_length <= sizeof( tag ) );
2007
Gilles Peskine8817f612018-12-18 00:18:46 +01002008 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002009
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002010 psa_set_key_usage_flags( &attributes, policy_usage );
2011 psa_set_key_algorithm( &attributes, policy_alg );
2012 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002013
Gilles Peskine049c7532019-05-15 20:22:09 +02002014 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2015 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002016
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002017 status = psa_aead_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002018 nonce, nonce_length,
2019 NULL, 0,
2020 NULL, 0,
2021 tag, tag_length,
2022 &output_length );
2023 if( policy_alg == exercise_alg &&
2024 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002025 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002026 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002027 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002028
2029 memset( tag, 0, sizeof( tag ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002030 status = psa_aead_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002031 nonce, nonce_length,
2032 NULL, 0,
2033 tag, tag_length,
2034 NULL, 0,
2035 &output_length );
2036 if( policy_alg == exercise_alg &&
2037 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01002038 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002039 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002040 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002041
2042exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002043 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002044 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002045}
2046/* END_CASE */
2047
2048/* BEGIN_CASE */
2049void asymmetric_encryption_key_policy( int policy_usage,
2050 int policy_alg,
2051 int key_type,
2052 data_t *key_data,
2053 int exercise_alg )
2054{
Ronald Cron91e95152020-07-30 17:48:03 +02002055 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002056 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002057 psa_status_t status;
2058 size_t key_bits;
2059 size_t buffer_length;
2060 unsigned char *buffer = NULL;
2061 size_t output_length;
2062
Gilles Peskine8817f612018-12-18 00:18:46 +01002063 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002064
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002065 psa_set_key_usage_flags( &attributes, policy_usage );
2066 psa_set_key_algorithm( &attributes, policy_alg );
2067 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002068
Gilles Peskine049c7532019-05-15 20:22:09 +02002069 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2070 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002071
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002072 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
2073 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002074 buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
2075 exercise_alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02002076 ASSERT_ALLOC( buffer, buffer_length );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002077
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002078 status = psa_asymmetric_encrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002079 NULL, 0,
2080 NULL, 0,
2081 buffer, buffer_length,
2082 &output_length );
2083 if( policy_alg == exercise_alg &&
2084 ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002085 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002086 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002087 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002088
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02002089 if( buffer_length != 0 )
2090 memset( buffer, 0, buffer_length );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002091 status = psa_asymmetric_decrypt( handle, exercise_alg,
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002092 buffer, buffer_length,
2093 NULL, 0,
2094 buffer, buffer_length,
2095 &output_length );
2096 if( policy_alg == exercise_alg &&
2097 ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01002098 TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002099 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002100 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002101
2102exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002103 psa_destroy_key( handle );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002104 psa_reset_key_attributes( &attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002105 PSA_DONE( );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002106 mbedtls_free( buffer );
2107}
2108/* END_CASE */
2109
2110/* BEGIN_CASE */
2111void asymmetric_signature_key_policy( int policy_usage,
2112 int policy_alg,
2113 int key_type,
2114 data_t *key_data,
Gilles Peskine30f77cd2019-01-14 16:06:39 +01002115 int exercise_alg,
2116 int payload_length_arg )
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002117{
Ronald Cron91e95152020-07-30 17:48:03 +02002118 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002119 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002120 psa_status_t status;
Gilles Peskine30f77cd2019-01-14 16:06:39 +01002121 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
2122 /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
2123 * compatible with the policy and `payload_length_arg` is supposed to be
2124 * a valid input length to sign. If `payload_length_arg <= 0`,
2125 * `exercise_alg` is supposed to be forbidden by the policy. */
2126 int compatible_alg = payload_length_arg > 0;
2127 size_t payload_length = compatible_alg ? payload_length_arg : 0;
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01002128 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = {0};
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002129 size_t signature_length;
2130
Gilles Peskine8817f612018-12-18 00:18:46 +01002131 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002132
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002133 psa_set_key_usage_flags( &attributes, policy_usage );
2134 psa_set_key_algorithm( &attributes, policy_alg );
2135 psa_set_key_type( &attributes, key_type );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002136
Gilles Peskine049c7532019-05-15 20:22:09 +02002137 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2138 &handle ) );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002139
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01002140 status = psa_sign_hash( handle, exercise_alg,
2141 payload, payload_length,
2142 signature, sizeof( signature ),
2143 &signature_length );
2144 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN_HASH ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002145 PSA_ASSERT( status );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002146 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002147 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002148
2149 memset( signature, 0, sizeof( signature ) );
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01002150 status = psa_verify_hash( handle, exercise_alg,
2151 payload, payload_length,
2152 signature, sizeof( signature ) );
2153 if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY_HASH ) != 0 )
Gilles Peskinefe11b722018-12-18 00:24:04 +01002154 TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine76f5c7b2018-07-06 16:53:09 +02002155 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002156 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskined5b33222018-06-18 22:20:03 +02002157
2158exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002159 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002160 PSA_DONE( );
Gilles Peskined5b33222018-06-18 22:20:03 +02002161}
2162/* END_CASE */
2163
Janos Follathba3fab92019-06-11 14:50:16 +01002164/* BEGIN_CASE */
Gilles Peskineea0fb492018-07-12 17:17:20 +02002165void derive_key_policy( int policy_usage,
2166 int policy_alg,
2167 int key_type,
2168 data_t *key_data,
2169 int exercise_alg )
2170{
Ronald Cron91e95152020-07-30 17:48:03 +02002171 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002172 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002173 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02002174 psa_status_t status;
2175
Gilles Peskine8817f612018-12-18 00:18:46 +01002176 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002177
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002178 psa_set_key_usage_flags( &attributes, policy_usage );
2179 psa_set_key_algorithm( &attributes, policy_alg );
2180 psa_set_key_type( &attributes, key_type );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002181
Gilles Peskine049c7532019-05-15 20:22:09 +02002182 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2183 &handle ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002184
Janos Follathba3fab92019-06-11 14:50:16 +01002185 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
2186
2187 if( PSA_ALG_IS_TLS12_PRF( exercise_alg ) ||
2188 PSA_ALG_IS_TLS12_PSK_TO_MS( exercise_alg ) )
Janos Follath0c1ed842019-06-28 13:35:36 +01002189 {
Janos Follathba3fab92019-06-11 14:50:16 +01002190 PSA_ASSERT( psa_key_derivation_input_bytes(
2191 &operation,
2192 PSA_KEY_DERIVATION_INPUT_SEED,
2193 (const uint8_t*) "", 0) );
Janos Follath0c1ed842019-06-28 13:35:36 +01002194 }
Janos Follathba3fab92019-06-11 14:50:16 +01002195
2196 status = psa_key_derivation_input_key( &operation,
2197 PSA_KEY_DERIVATION_INPUT_SECRET,
2198 handle );
2199
Gilles Peskineea0fb492018-07-12 17:17:20 +02002200 if( policy_alg == exercise_alg &&
2201 ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
Gilles Peskine8817f612018-12-18 00:18:46 +01002202 PSA_ASSERT( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002203 else
Gilles Peskinefe11b722018-12-18 00:24:04 +01002204 TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002205
2206exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002207 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002208 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002209 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02002210}
2211/* END_CASE */
2212
2213/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02002214void agreement_key_policy( int policy_usage,
2215 int policy_alg,
2216 int key_type_arg,
2217 data_t *key_data,
Steven Cooremance48e852020-10-05 16:02:45 +02002218 int exercise_alg,
2219 int expected_status_arg )
Gilles Peskine01d718c2018-09-18 12:01:02 +02002220{
Ronald Cron91e95152020-07-30 17:48:03 +02002221 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002222 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02002223 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002224 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02002225 psa_status_t status;
Steven Cooremance48e852020-10-05 16:02:45 +02002226 psa_status_t expected_status = expected_status_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02002227
Gilles Peskine8817f612018-12-18 00:18:46 +01002228 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002229
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002230 psa_set_key_usage_flags( &attributes, policy_usage );
2231 psa_set_key_algorithm( &attributes, policy_alg );
2232 psa_set_key_type( &attributes, key_type );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002233
Gilles Peskine049c7532019-05-15 20:22:09 +02002234 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2235 &handle ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002236
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002237 PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
2238 status = key_agreement_with_self( &operation, handle );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002239
Steven Cooremance48e852020-10-05 16:02:45 +02002240 TEST_EQUAL( status, expected_status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002241
2242exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002243 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01002244 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002245 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02002246}
2247/* END_CASE */
2248
2249/* BEGIN_CASE */
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002250void key_policy_alg2( int key_type_arg, data_t *key_data,
2251 int usage_arg, int alg_arg, int alg2_arg )
2252{
Ronald Cron91e95152020-07-30 17:48:03 +02002253 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002254 psa_key_type_t key_type = key_type_arg;
2255 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
2256 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
2257 psa_key_usage_t usage = usage_arg;
2258 psa_algorithm_t alg = alg_arg;
2259 psa_algorithm_t alg2 = alg2_arg;
2260
2261 PSA_ASSERT( psa_crypto_init( ) );
2262
2263 psa_set_key_usage_flags( &attributes, usage );
2264 psa_set_key_algorithm( &attributes, alg );
2265 psa_set_key_enrollment_algorithm( &attributes, alg2 );
2266 psa_set_key_type( &attributes, key_type );
2267 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2268 &handle ) );
2269
2270 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
2271 TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
2272 TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
2273 TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
2274
2275 if( ! exercise_key( handle, usage, alg ) )
2276 goto exit;
2277 if( ! exercise_key( handle, usage, alg2 ) )
2278 goto exit;
2279
2280exit:
2281 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002282 PSA_DONE( );
Gilles Peskine96f0b3b2019-05-10 19:33:38 +02002283}
2284/* END_CASE */
2285
2286/* BEGIN_CASE */
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002287void raw_agreement_key_policy( int policy_usage,
2288 int policy_alg,
2289 int key_type_arg,
2290 data_t *key_data,
Steven Cooremance48e852020-10-05 16:02:45 +02002291 int exercise_alg,
2292 int expected_status_arg )
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002293{
Ronald Cron91e95152020-07-30 17:48:03 +02002294 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002295 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002296 psa_key_type_t key_type = key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002297 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002298 psa_status_t status;
Steven Cooremance48e852020-10-05 16:02:45 +02002299 psa_status_t expected_status = expected_status_arg;
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002300
2301 PSA_ASSERT( psa_crypto_init( ) );
2302
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002303 psa_set_key_usage_flags( &attributes, policy_usage );
2304 psa_set_key_algorithm( &attributes, policy_alg );
2305 psa_set_key_type( &attributes, key_type );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002306
Gilles Peskine049c7532019-05-15 20:22:09 +02002307 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
2308 &handle ) );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002309
2310 status = raw_key_agreement_with_self( exercise_alg, handle );
2311
Steven Cooremance48e852020-10-05 16:02:45 +02002312 TEST_EQUAL( status, expected_status );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002313
2314exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02002315 psa_key_derivation_abort( &operation );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002316 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002317 PSA_DONE( );
Gilles Peskine04ee2d22019-04-11 21:25:46 +02002318}
2319/* END_CASE */
2320
2321/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002322void copy_success( int source_usage_arg,
2323 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002324 int type_arg, data_t *material,
2325 int copy_attributes,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002326 int target_usage_arg,
2327 int target_alg_arg, int target_alg2_arg,
2328 int expected_usage_arg,
2329 int expected_alg_arg, int expected_alg2_arg )
Gilles Peskine57ab7212019-01-28 13:03:09 +01002330{
Gilles Peskineca25db92019-04-19 11:43:08 +02002331 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2332 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002333 psa_key_usage_t expected_usage = expected_usage_arg;
2334 psa_algorithm_t expected_alg = expected_alg_arg;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002335 psa_algorithm_t expected_alg2 = expected_alg2_arg;
Ronald Cron91e95152020-07-30 17:48:03 +02002336 psa_key_handle_t source_handle = PSA_KEY_HANDLE_INIT;
2337 psa_key_handle_t target_handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002338 uint8_t *export_buffer = NULL;
2339
Gilles Peskine57ab7212019-01-28 13:03:09 +01002340 PSA_ASSERT( psa_crypto_init( ) );
2341
Gilles Peskineca25db92019-04-19 11:43:08 +02002342 /* Prepare the source key. */
2343 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2344 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002345 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskineca25db92019-04-19 11:43:08 +02002346 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002347 PSA_ASSERT( psa_import_key( &source_attributes,
2348 material->x, material->len,
2349 &source_handle ) );
Gilles Peskineca25db92019-04-19 11:43:08 +02002350 PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002351
Gilles Peskineca25db92019-04-19 11:43:08 +02002352 /* Prepare the target attributes. */
2353 if( copy_attributes )
2354 target_attributes = source_attributes;
2355 if( target_usage_arg != -1 )
2356 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2357 if( target_alg_arg != -1 )
2358 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002359 if( target_alg2_arg != -1 )
2360 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002361
2362 /* Copy the key. */
Gilles Peskine4a644642019-05-03 17:14:08 +02002363 PSA_ASSERT( psa_copy_key( source_handle,
2364 &target_attributes, &target_handle ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002365
2366 /* Destroy the source to ensure that this doesn't affect the target. */
2367 PSA_ASSERT( psa_destroy_key( source_handle ) );
2368
2369 /* Test that the target slot has the expected content and policy. */
Gilles Peskineca25db92019-04-19 11:43:08 +02002370 PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
2371 TEST_EQUAL( psa_get_key_type( &source_attributes ),
2372 psa_get_key_type( &target_attributes ) );
2373 TEST_EQUAL( psa_get_key_bits( &source_attributes ),
2374 psa_get_key_bits( &target_attributes ) );
2375 TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
2376 TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002377 TEST_EQUAL( expected_alg2,
2378 psa_get_key_enrollment_algorithm( &target_attributes ) );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002379 if( expected_usage & PSA_KEY_USAGE_EXPORT )
2380 {
2381 size_t length;
2382 ASSERT_ALLOC( export_buffer, material->len );
2383 PSA_ASSERT( psa_export_key( target_handle, export_buffer,
2384 material->len, &length ) );
2385 ASSERT_COMPARE( material->x, material->len,
2386 export_buffer, length );
2387 }
2388 if( ! exercise_key( target_handle, expected_usage, expected_alg ) )
2389 goto exit;
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002390 if( ! exercise_key( target_handle, expected_usage, expected_alg2 ) )
2391 goto exit;
Gilles Peskine57ab7212019-01-28 13:03:09 +01002392
2393 PSA_ASSERT( psa_close_key( target_handle ) );
2394
2395exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02002396 psa_reset_key_attributes( &source_attributes );
2397 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002398 PSA_DONE( );
Gilles Peskine57ab7212019-01-28 13:03:09 +01002399 mbedtls_free( export_buffer );
2400}
2401/* END_CASE */
2402
2403/* BEGIN_CASE */
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002404void copy_fail( int source_usage_arg,
2405 int source_alg_arg, int source_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002406 int type_arg, data_t *material,
2407 int target_type_arg, int target_bits_arg,
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002408 int target_usage_arg,
2409 int target_alg_arg, int target_alg2_arg,
Gilles Peskine4a644642019-05-03 17:14:08 +02002410 int expected_status_arg )
2411{
2412 psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
2413 psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cron91e95152020-07-30 17:48:03 +02002414 psa_key_handle_t source_handle = PSA_KEY_HANDLE_INIT;
2415 psa_key_handle_t target_handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine4a644642019-05-03 17:14:08 +02002416
2417 PSA_ASSERT( psa_crypto_init( ) );
2418
2419 /* Prepare the source key. */
2420 psa_set_key_usage_flags( &source_attributes, source_usage_arg );
2421 psa_set_key_algorithm( &source_attributes, source_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002422 psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002423 psa_set_key_type( &source_attributes, type_arg );
Gilles Peskine049c7532019-05-15 20:22:09 +02002424 PSA_ASSERT( psa_import_key( &source_attributes,
2425 material->x, material->len,
2426 &source_handle ) );
Gilles Peskine4a644642019-05-03 17:14:08 +02002427
2428 /* Prepare the target attributes. */
2429 psa_set_key_type( &target_attributes, target_type_arg );
2430 psa_set_key_bits( &target_attributes, target_bits_arg );
2431 psa_set_key_usage_flags( &target_attributes, target_usage_arg );
2432 psa_set_key_algorithm( &target_attributes, target_alg_arg );
Gilles Peskinebcdd44b2019-05-20 17:28:11 +02002433 psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
Gilles Peskine4a644642019-05-03 17:14:08 +02002434
2435 /* Try to copy the key. */
2436 TEST_EQUAL( psa_copy_key( source_handle,
2437 &target_attributes, &target_handle ),
2438 expected_status_arg );
Gilles Peskine76b29a72019-05-28 14:08:50 +02002439
2440 PSA_ASSERT( psa_destroy_key( source_handle ) );
2441
Gilles Peskine4a644642019-05-03 17:14:08 +02002442exit:
2443 psa_reset_key_attributes( &source_attributes );
2444 psa_reset_key_attributes( &target_attributes );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002445 PSA_DONE( );
Gilles Peskine4a644642019-05-03 17:14:08 +02002446}
2447/* END_CASE */
2448
2449/* BEGIN_CASE */
Jaeden Amero6a25b412019-01-04 11:47:44 +00002450void hash_operation_init( )
2451{
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002452 const uint8_t input[1] = { 0 };
Jaeden Amero6a25b412019-01-04 11:47:44 +00002453 /* Test each valid way of initializing the object, except for `= {0}`, as
2454 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2455 * though it's OK by the C standard. We could test for this, but we'd need
2456 * to supress the Clang warning for the test. */
2457 psa_hash_operation_t func = psa_hash_operation_init( );
2458 psa_hash_operation_t init = PSA_HASH_OPERATION_INIT;
2459 psa_hash_operation_t zero;
2460
2461 memset( &zero, 0, sizeof( zero ) );
2462
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002463 /* A freshly-initialized hash operation should not be usable. */
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002464 TEST_EQUAL( psa_hash_update( &func, input, sizeof( input ) ),
2465 PSA_ERROR_BAD_STATE );
2466 TEST_EQUAL( psa_hash_update( &init, input, sizeof( input ) ),
2467 PSA_ERROR_BAD_STATE );
2468 TEST_EQUAL( psa_hash_update( &zero, input, sizeof( input ) ),
2469 PSA_ERROR_BAD_STATE );
2470
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002471 /* A default hash operation should be abortable without error. */
2472 PSA_ASSERT( psa_hash_abort( &func ) );
2473 PSA_ASSERT( psa_hash_abort( &init ) );
2474 PSA_ASSERT( psa_hash_abort( &zero ) );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002475}
2476/* END_CASE */
2477
2478/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002479void hash_setup( int alg_arg,
2480 int expected_status_arg )
2481{
2482 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002483 psa_status_t expected_status = expected_status_arg;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002484 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002485 psa_status_t status;
2486
Gilles Peskine8817f612018-12-18 00:18:46 +01002487 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002488
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02002489 status = psa_hash_setup( &operation, alg );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002490 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002491
Gilles Peskine9e0a4a52019-02-25 22:11:18 +01002492 /* Whether setup succeeded or failed, abort must succeed. */
2493 PSA_ASSERT( psa_hash_abort( &operation ) );
2494
2495 /* If setup failed, reproduce the failure, so as to
2496 * test the resulting state of the operation object. */
2497 if( status != PSA_SUCCESS )
2498 TEST_EQUAL( psa_hash_setup( &operation, alg ), status );
2499
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002500 /* Now the operation object should be reusable. */
2501#if defined(KNOWN_SUPPORTED_HASH_ALG)
2502 PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) );
2503 PSA_ASSERT( psa_hash_abort( &operation ) );
2504#endif
2505
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002506exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002507 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002508}
2509/* END_CASE */
2510
2511/* BEGIN_CASE */
Gilles Peskine0a749c82019-11-28 19:33:58 +01002512void hash_compute_fail( int alg_arg, data_t *input,
2513 int output_size_arg, int expected_status_arg )
2514{
2515 psa_algorithm_t alg = alg_arg;
2516 uint8_t *output = NULL;
2517 size_t output_size = output_size_arg;
2518 size_t output_length = INVALID_EXPORT_LENGTH;
2519 psa_status_t expected_status = expected_status_arg;
2520 psa_status_t status;
2521
2522 ASSERT_ALLOC( output, output_size );
2523
2524 PSA_ASSERT( psa_crypto_init( ) );
2525
2526 status = psa_hash_compute( alg, input->x, input->len,
2527 output, output_size, &output_length );
2528 TEST_EQUAL( status, expected_status );
2529 TEST_ASSERT( output_length <= output_size );
2530
2531exit:
2532 mbedtls_free( output );
2533 PSA_DONE( );
2534}
2535/* END_CASE */
2536
2537/* BEGIN_CASE */
Gilles Peskine88e08462020-01-28 20:43:00 +01002538void hash_compare_fail( int alg_arg, data_t *input,
2539 data_t *reference_hash,
2540 int expected_status_arg )
2541{
2542 psa_algorithm_t alg = alg_arg;
2543 psa_status_t expected_status = expected_status_arg;
2544 psa_status_t status;
2545
2546 PSA_ASSERT( psa_crypto_init( ) );
2547
2548 status = psa_hash_compare( alg, input->x, input->len,
2549 reference_hash->x, reference_hash->len );
2550 TEST_EQUAL( status, expected_status );
2551
2552exit:
2553 PSA_DONE( );
2554}
2555/* END_CASE */
2556
2557/* BEGIN_CASE */
Gilles Peskine0a749c82019-11-28 19:33:58 +01002558void hash_compute_compare( int alg_arg, data_t *input,
2559 data_t *expected_output )
2560{
2561 psa_algorithm_t alg = alg_arg;
2562 uint8_t output[PSA_HASH_MAX_SIZE + 1];
2563 size_t output_length = INVALID_EXPORT_LENGTH;
2564 size_t i;
2565
2566 PSA_ASSERT( psa_crypto_init( ) );
2567
2568 /* Compute with tight buffer */
2569 PSA_ASSERT( psa_hash_compute( alg, input->x, input->len,
2570 output, PSA_HASH_SIZE( alg ),
2571 &output_length ) );
2572 TEST_EQUAL( output_length, PSA_HASH_SIZE( alg ) );
2573 ASSERT_COMPARE( output, output_length,
2574 expected_output->x, expected_output->len );
2575
2576 /* Compute with larger buffer */
2577 PSA_ASSERT( psa_hash_compute( alg, input->x, input->len,
2578 output, sizeof( output ),
2579 &output_length ) );
2580 TEST_EQUAL( output_length, PSA_HASH_SIZE( alg ) );
2581 ASSERT_COMPARE( output, output_length,
2582 expected_output->x, expected_output->len );
2583
2584 /* Compare with correct hash */
2585 PSA_ASSERT( psa_hash_compare( alg, input->x, input->len,
2586 output, output_length ) );
2587
2588 /* Compare with trailing garbage */
2589 TEST_EQUAL( psa_hash_compare( alg, input->x, input->len,
2590 output, output_length + 1 ),
2591 PSA_ERROR_INVALID_SIGNATURE );
2592
2593 /* Compare with truncated hash */
2594 TEST_EQUAL( psa_hash_compare( alg, input->x, input->len,
2595 output, output_length - 1 ),
2596 PSA_ERROR_INVALID_SIGNATURE );
2597
2598 /* Compare with corrupted value */
2599 for( i = 0; i < output_length; i++ )
2600 {
2601 test_set_step( i );
2602 output[i] ^= 1;
2603 TEST_EQUAL( psa_hash_compare( alg, input->x, input->len,
2604 output, output_length ),
2605 PSA_ERROR_INVALID_SIGNATURE );
2606 output[i] ^= 1;
2607 }
2608
2609exit:
2610 PSA_DONE( );
2611}
2612/* END_CASE */
2613
2614/* BEGIN_CASE */
itayzafrirf86548d2018-11-01 10:44:32 +02002615void hash_bad_order( )
2616{
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002617 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirf86548d2018-11-01 10:44:32 +02002618 unsigned char input[] = "";
2619 /* SHA-256 hash of an empty string */
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002620 const unsigned char valid_hash[] = {
itayzafrirf86548d2018-11-01 10:44:32 +02002621 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2622 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2623 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002624 unsigned char hash[sizeof(valid_hash)] = { 0 };
itayzafrirf86548d2018-11-01 10:44:32 +02002625 size_t hash_len;
Jaeden Amero6a25b412019-01-04 11:47:44 +00002626 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirf86548d2018-11-01 10:44:32 +02002627
Gilles Peskine8817f612018-12-18 00:18:46 +01002628 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002629
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002630 /* Call setup twice in a row. */
2631 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2632 TEST_EQUAL( psa_hash_setup( &operation, alg ),
2633 PSA_ERROR_BAD_STATE );
2634 PSA_ASSERT( psa_hash_abort( &operation ) );
2635
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002636 /* Call update without calling setup beforehand. */
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002637 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002638 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002639 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002640
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002641 /* Call update after finish. */
2642 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2643 PSA_ASSERT( psa_hash_finish( &operation,
2644 hash, sizeof( hash ), &hash_len ) );
2645 TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002646 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002647 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002648
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002649 /* Call verify without calling setup beforehand. */
2650 TEST_EQUAL( psa_hash_verify( &operation,
2651 valid_hash, sizeof( valid_hash ) ),
2652 PSA_ERROR_BAD_STATE );
2653 PSA_ASSERT( psa_hash_abort( &operation ) );
2654
2655 /* Call verify after finish. */
2656 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2657 PSA_ASSERT( psa_hash_finish( &operation,
2658 hash, sizeof( hash ), &hash_len ) );
2659 TEST_EQUAL( psa_hash_verify( &operation,
2660 valid_hash, sizeof( valid_hash ) ),
2661 PSA_ERROR_BAD_STATE );
2662 PSA_ASSERT( psa_hash_abort( &operation ) );
2663
2664 /* Call verify twice in a row. */
2665 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2666 PSA_ASSERT( psa_hash_verify( &operation,
2667 valid_hash, sizeof( valid_hash ) ) );
2668 TEST_EQUAL( psa_hash_verify( &operation,
2669 valid_hash, sizeof( valid_hash ) ),
2670 PSA_ERROR_BAD_STATE );
2671 PSA_ASSERT( psa_hash_abort( &operation ) );
2672
2673 /* Call finish without calling setup beforehand. */
Gilles Peskinefe11b722018-12-18 00:24:04 +01002674 TEST_EQUAL( psa_hash_finish( &operation,
2675 hash, sizeof( hash ), &hash_len ),
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002676 PSA_ERROR_BAD_STATE );
Jaeden Amero11aa7ee2019-02-19 11:44:55 +00002677 PSA_ASSERT( psa_hash_abort( &operation ) );
2678
2679 /* Call finish twice in a row. */
2680 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2681 PSA_ASSERT( psa_hash_finish( &operation,
2682 hash, sizeof( hash ), &hash_len ) );
2683 TEST_EQUAL( psa_hash_finish( &operation,
2684 hash, sizeof( hash ), &hash_len ),
2685 PSA_ERROR_BAD_STATE );
2686 PSA_ASSERT( psa_hash_abort( &operation ) );
2687
2688 /* Call finish after calling verify. */
2689 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
2690 PSA_ASSERT( psa_hash_verify( &operation,
2691 valid_hash, sizeof( valid_hash ) ) );
2692 TEST_EQUAL( psa_hash_finish( &operation,
2693 hash, sizeof( hash ), &hash_len ),
2694 PSA_ERROR_BAD_STATE );
2695 PSA_ASSERT( psa_hash_abort( &operation ) );
itayzafrirf86548d2018-11-01 10:44:32 +02002696
2697exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002698 PSA_DONE( );
itayzafrirf86548d2018-11-01 10:44:32 +02002699}
2700/* END_CASE */
2701
itayzafrir27e69452018-11-01 14:26:34 +02002702/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2703void hash_verify_bad_args( )
itayzafrirec93d302018-10-18 18:01:10 +03002704{
2705 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrir27e69452018-11-01 14:26:34 +02002706 /* SHA-256 hash of an empty string with 2 extra bytes (0xaa and 0xbb)
2707 * appended to it */
2708 unsigned char hash[] = {
2709 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
2710 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
2711 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
itayzafrirec93d302018-10-18 18:01:10 +03002712 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002713 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrirec93d302018-10-18 18:01:10 +03002714
Gilles Peskine8817f612018-12-18 00:18:46 +01002715 PSA_ASSERT( psa_crypto_init( ) );
itayzafrirec93d302018-10-18 18:01:10 +03002716
itayzafrir27e69452018-11-01 14:26:34 +02002717 /* psa_hash_verify with a smaller hash than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002718 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002719 TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002720 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002721
itayzafrir27e69452018-11-01 14:26:34 +02002722 /* psa_hash_verify with a non-matching hash */
Gilles Peskine8817f612018-12-18 00:18:46 +01002723 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002724 TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002725 PSA_ERROR_INVALID_SIGNATURE );
itayzafrirec93d302018-10-18 18:01:10 +03002726
itayzafrir27e69452018-11-01 14:26:34 +02002727 /* psa_hash_verify with a hash longer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002728 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002729 TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
Gilles Peskinefe11b722018-12-18 00:24:04 +01002730 PSA_ERROR_INVALID_SIGNATURE );
itayzafrir4271df92018-10-24 18:16:19 +03002731
itayzafrirec93d302018-10-18 18:01:10 +03002732exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002733 PSA_DONE( );
itayzafrirec93d302018-10-18 18:01:10 +03002734}
2735/* END_CASE */
2736
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002737/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2738void hash_finish_bad_args( )
itayzafrir58028322018-10-25 10:22:01 +03002739{
2740 psa_algorithm_t alg = PSA_ALG_SHA_256;
itayzafrirb2dd5ed2018-11-01 11:58:59 +02002741 unsigned char hash[PSA_HASH_MAX_SIZE];
itayzafrir58028322018-10-25 10:22:01 +03002742 size_t expected_size = PSA_HASH_SIZE( alg );
Jaeden Amero6a25b412019-01-04 11:47:44 +00002743 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
itayzafrir58028322018-10-25 10:22:01 +03002744 size_t hash_len;
2745
Gilles Peskine8817f612018-12-18 00:18:46 +01002746 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir58028322018-10-25 10:22:01 +03002747
itayzafrir58028322018-10-25 10:22:01 +03002748 /* psa_hash_finish with a smaller hash buffer than expected */
Gilles Peskine8817f612018-12-18 00:18:46 +01002749 PSA_ASSERT( psa_hash_setup( &operation, alg ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01002750 TEST_EQUAL( psa_hash_finish( &operation,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01002751 hash, expected_size - 1, &hash_len ),
2752 PSA_ERROR_BUFFER_TOO_SMALL );
itayzafrir58028322018-10-25 10:22:01 +03002753
2754exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002755 PSA_DONE( );
itayzafrir58028322018-10-25 10:22:01 +03002756}
2757/* END_CASE */
2758
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002759/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2760void hash_clone_source_state( )
2761{
2762 psa_algorithm_t alg = PSA_ALG_SHA_256;
2763 unsigned char hash[PSA_HASH_MAX_SIZE];
2764 psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT;
2765 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2766 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2767 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2768 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2769 size_t hash_len;
2770
2771 PSA_ASSERT( psa_crypto_init( ) );
2772 PSA_ASSERT( psa_hash_setup( &op_source, alg ) );
2773
2774 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2775 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2776 PSA_ASSERT( psa_hash_finish( &op_finished,
2777 hash, sizeof( hash ), &hash_len ) );
2778 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2779 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2780
2781 TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ),
2782 PSA_ERROR_BAD_STATE );
2783
2784 PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) );
2785 PSA_ASSERT( psa_hash_finish( &op_init,
2786 hash, sizeof( hash ), &hash_len ) );
2787 PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) );
2788 PSA_ASSERT( psa_hash_finish( &op_finished,
2789 hash, sizeof( hash ), &hash_len ) );
2790 PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) );
2791 PSA_ASSERT( psa_hash_finish( &op_aborted,
2792 hash, sizeof( hash ), &hash_len ) );
2793
2794exit:
2795 psa_hash_abort( &op_source );
2796 psa_hash_abort( &op_init );
2797 psa_hash_abort( &op_setup );
2798 psa_hash_abort( &op_finished );
2799 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002800 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002801}
2802/* END_CASE */
2803
2804/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
2805void hash_clone_target_state( )
2806{
2807 psa_algorithm_t alg = PSA_ALG_SHA_256;
2808 unsigned char hash[PSA_HASH_MAX_SIZE];
2809 psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT;
2810 psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT;
2811 psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT;
2812 psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT;
2813 psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT;
2814 size_t hash_len;
2815
2816 PSA_ASSERT( psa_crypto_init( ) );
2817
2818 PSA_ASSERT( psa_hash_setup( &op_setup, alg ) );
2819 PSA_ASSERT( psa_hash_setup( &op_finished, alg ) );
2820 PSA_ASSERT( psa_hash_finish( &op_finished,
2821 hash, sizeof( hash ), &hash_len ) );
2822 PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) );
2823 PSA_ASSERT( psa_hash_abort( &op_aborted ) );
2824
2825 PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) );
2826 PSA_ASSERT( psa_hash_finish( &op_target,
2827 hash, sizeof( hash ), &hash_len ) );
2828
2829 TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE );
2830 TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ),
2831 PSA_ERROR_BAD_STATE );
2832 TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ),
2833 PSA_ERROR_BAD_STATE );
2834
2835exit:
2836 psa_hash_abort( &op_target );
2837 psa_hash_abort( &op_init );
2838 psa_hash_abort( &op_setup );
2839 psa_hash_abort( &op_finished );
2840 psa_hash_abort( &op_aborted );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002841 PSA_DONE( );
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002842}
2843/* END_CASE */
2844
itayzafrir58028322018-10-25 10:22:01 +03002845/* BEGIN_CASE */
Jaeden Amero769ce272019-01-04 11:48:03 +00002846void mac_operation_init( )
2847{
Jaeden Amero252ef282019-02-15 14:05:35 +00002848 const uint8_t input[1] = { 0 };
2849
Jaeden Amero769ce272019-01-04 11:48:03 +00002850 /* Test each valid way of initializing the object, except for `= {0}`, as
2851 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
2852 * though it's OK by the C standard. We could test for this, but we'd need
2853 * to supress the Clang warning for the test. */
2854 psa_mac_operation_t func = psa_mac_operation_init( );
2855 psa_mac_operation_t init = PSA_MAC_OPERATION_INIT;
2856 psa_mac_operation_t zero;
2857
2858 memset( &zero, 0, sizeof( zero ) );
2859
Jaeden Amero252ef282019-02-15 14:05:35 +00002860 /* A freshly-initialized MAC operation should not be usable. */
2861 TEST_EQUAL( psa_mac_update( &func,
2862 input, sizeof( input ) ),
2863 PSA_ERROR_BAD_STATE );
2864 TEST_EQUAL( psa_mac_update( &init,
2865 input, sizeof( input ) ),
2866 PSA_ERROR_BAD_STATE );
2867 TEST_EQUAL( psa_mac_update( &zero,
2868 input, sizeof( input ) ),
2869 PSA_ERROR_BAD_STATE );
2870
Jaeden Amero5229bbb2019-02-07 16:33:37 +00002871 /* A default MAC operation should be abortable without error. */
2872 PSA_ASSERT( psa_mac_abort( &func ) );
2873 PSA_ASSERT( psa_mac_abort( &init ) );
2874 PSA_ASSERT( psa_mac_abort( &zero ) );
Jaeden Amero769ce272019-01-04 11:48:03 +00002875}
2876/* END_CASE */
2877
2878/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002879void mac_setup( int key_type_arg,
2880 data_t *key,
2881 int alg_arg,
2882 int expected_status_arg )
2883{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002884 psa_key_type_t key_type = key_type_arg;
2885 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02002886 psa_status_t expected_status = expected_status_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00002887 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002888 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2889#if defined(KNOWN_SUPPORTED_MAC_ALG)
2890 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
2891#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002892
Gilles Peskine8817f612018-12-18 00:18:46 +01002893 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002894
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002895 if( ! exercise_mac_setup( key_type, key->x, key->len, alg,
2896 &operation, &status ) )
2897 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01002898 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002899
Gilles Peskinef426e0f2019-02-25 17:42:03 +01002900 /* The operation object should be reusable. */
2901#if defined(KNOWN_SUPPORTED_MAC_ALG)
2902 if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE,
2903 smoke_test_key_data,
2904 sizeof( smoke_test_key_data ),
2905 KNOWN_SUPPORTED_MAC_ALG,
2906 &operation, &status ) )
2907 goto exit;
2908 TEST_EQUAL( status, PSA_SUCCESS );
2909#endif
2910
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002911exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02002912 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002913}
2914/* END_CASE */
2915
2916/* BEGIN_CASE */
Jaeden Amero252ef282019-02-15 14:05:35 +00002917void mac_bad_order( )
2918{
Ronald Cron91e95152020-07-30 17:48:03 +02002919 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002920 psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
2921 psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
2922 const uint8_t key[] = {
2923 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2924 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2925 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002926 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Amero252ef282019-02-15 14:05:35 +00002927 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
2928 uint8_t sign_mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
2929 size_t sign_mac_length = 0;
2930 const uint8_t input[] = { 0xbb, 0xbb, 0xbb, 0xbb };
2931 const uint8_t verify_mac[] = {
2932 0x74, 0x65, 0x93, 0x8c, 0xeb, 0x1d, 0xb3, 0x76, 0x5a, 0x38, 0xe7, 0xdd,
2933 0x85, 0xc5, 0xad, 0x4f, 0x07, 0xe7, 0xd5, 0xb2, 0x64, 0xf0, 0x1a, 0x1a,
2934 0x2c, 0xf9, 0x18, 0xca, 0x59, 0x7e, 0x5d, 0xf6 };
2935
2936 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01002937 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02002938 psa_set_key_algorithm( &attributes, alg );
2939 psa_set_key_type( &attributes, key_type );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002940
Gilles Peskine73676cb2019-05-15 20:15:10 +02002941 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02002942
Jaeden Amero252ef282019-02-15 14:05:35 +00002943 /* Call update without calling setup beforehand. */
2944 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2945 PSA_ERROR_BAD_STATE );
2946 PSA_ASSERT( psa_mac_abort( &operation ) );
2947
2948 /* Call sign finish without calling setup beforehand. */
2949 TEST_EQUAL( psa_mac_sign_finish( &operation, sign_mac, sizeof( sign_mac ),
2950 &sign_mac_length),
2951 PSA_ERROR_BAD_STATE );
2952 PSA_ASSERT( psa_mac_abort( &operation ) );
2953
2954 /* Call verify finish without calling setup beforehand. */
2955 TEST_EQUAL( psa_mac_verify_finish( &operation,
2956 verify_mac, sizeof( verify_mac ) ),
2957 PSA_ERROR_BAD_STATE );
2958 PSA_ASSERT( psa_mac_abort( &operation ) );
2959
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002960 /* Call setup twice in a row. */
2961 PSA_ASSERT( psa_mac_sign_setup( &operation,
2962 handle, alg ) );
2963 TEST_EQUAL( psa_mac_sign_setup( &operation,
2964 handle, alg ),
2965 PSA_ERROR_BAD_STATE );
2966 PSA_ASSERT( psa_mac_abort( &operation ) );
2967
Jaeden Amero252ef282019-02-15 14:05:35 +00002968 /* Call update after sign finish. */
2969 PSA_ASSERT( psa_mac_sign_setup( &operation,
2970 handle, alg ) );
2971 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2972 PSA_ASSERT( psa_mac_sign_finish( &operation,
2973 sign_mac, sizeof( sign_mac ),
2974 &sign_mac_length ) );
2975 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2976 PSA_ERROR_BAD_STATE );
2977 PSA_ASSERT( psa_mac_abort( &operation ) );
2978
2979 /* Call update after verify finish. */
2980 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02002981 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00002982 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2983 PSA_ASSERT( psa_mac_verify_finish( &operation,
2984 verify_mac, sizeof( verify_mac ) ) );
2985 TEST_EQUAL( psa_mac_update( &operation, input, sizeof( input ) ),
2986 PSA_ERROR_BAD_STATE );
2987 PSA_ASSERT( psa_mac_abort( &operation ) );
2988
2989 /* Call sign finish twice in a row. */
2990 PSA_ASSERT( psa_mac_sign_setup( &operation,
2991 handle, alg ) );
2992 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
2993 PSA_ASSERT( psa_mac_sign_finish( &operation,
2994 sign_mac, sizeof( sign_mac ),
2995 &sign_mac_length ) );
2996 TEST_EQUAL( psa_mac_sign_finish( &operation,
2997 sign_mac, sizeof( sign_mac ),
2998 &sign_mac_length ),
2999 PSA_ERROR_BAD_STATE );
3000 PSA_ASSERT( psa_mac_abort( &operation ) );
3001
3002 /* Call verify finish twice in a row. */
3003 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02003004 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00003005 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
3006 PSA_ASSERT( psa_mac_verify_finish( &operation,
3007 verify_mac, sizeof( verify_mac ) ) );
3008 TEST_EQUAL( psa_mac_verify_finish( &operation,
3009 verify_mac, sizeof( verify_mac ) ),
3010 PSA_ERROR_BAD_STATE );
3011 PSA_ASSERT( psa_mac_abort( &operation ) );
3012
3013 /* Setup sign but try verify. */
3014 PSA_ASSERT( psa_mac_sign_setup( &operation,
3015 handle, alg ) );
3016 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
3017 TEST_EQUAL( psa_mac_verify_finish( &operation,
3018 verify_mac, sizeof( verify_mac ) ),
3019 PSA_ERROR_BAD_STATE );
3020 PSA_ASSERT( psa_mac_abort( &operation ) );
3021
3022 /* Setup verify but try sign. */
3023 PSA_ASSERT( psa_mac_verify_setup( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02003024 handle, alg ) );
Jaeden Amero252ef282019-02-15 14:05:35 +00003025 PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
3026 TEST_EQUAL( psa_mac_sign_finish( &operation,
3027 sign_mac, sizeof( sign_mac ),
3028 &sign_mac_length ),
3029 PSA_ERROR_BAD_STATE );
3030 PSA_ASSERT( psa_mac_abort( &operation ) );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003031
Gilles Peskine76b29a72019-05-28 14:08:50 +02003032 PSA_ASSERT( psa_destroy_key( handle ) );
3033
Gilles Peskine9ef733f2018-02-07 21:05:37 +01003034exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003035 PSA_DONE( );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01003036}
3037/* END_CASE */
3038
3039/* BEGIN_CASE */
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003040void mac_sign( int key_type_arg,
3041 data_t *key,
3042 int alg_arg,
3043 data_t *input,
3044 data_t *expected_mac )
3045{
Ronald Cron91e95152020-07-30 17:48:03 +02003046 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003047 psa_key_type_t key_type = key_type_arg;
3048 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00003049 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003050 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine5e65cec2020-08-25 23:38:39 +02003051 uint8_t *actual_mac = NULL;
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003052 size_t mac_buffer_size =
3053 PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
3054 size_t mac_length = 0;
Gilles Peskine8b356b52020-08-25 23:44:59 +02003055 const size_t output_sizes_to_test[] = {
3056 0,
3057 1,
3058 expected_mac->len - 1,
3059 expected_mac->len,
3060 expected_mac->len + 1,
3061 };
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003062
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003063 TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
Gilles Peskine3d404d62020-08-25 23:47:36 +02003064 /* We expect PSA_MAC_FINAL_SIZE to be exact. */
3065 TEST_ASSERT( expected_mac->len == mac_buffer_size );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003066
Gilles Peskine8817f612018-12-18 00:18:46 +01003067 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003068
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003069 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003070 psa_set_key_algorithm( &attributes, alg );
3071 psa_set_key_type( &attributes, key_type );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003072
Gilles Peskine73676cb2019-05-15 20:15:10 +02003073 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003074
Gilles Peskine8b356b52020-08-25 23:44:59 +02003075 for( size_t i = 0; i < ARRAY_LENGTH( output_sizes_to_test ); i++ )
3076 {
3077 const size_t output_size = output_sizes_to_test[i];
3078 psa_status_t expected_status =
3079 ( output_size >= expected_mac->len ? PSA_SUCCESS :
3080 PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine5e65cec2020-08-25 23:38:39 +02003081
Gilles Peskine8b356b52020-08-25 23:44:59 +02003082 test_set_step( output_size );
3083 ASSERT_ALLOC( actual_mac, output_size );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003084
Gilles Peskine8b356b52020-08-25 23:44:59 +02003085 /* Calculate the MAC. */
3086 PSA_ASSERT( psa_mac_sign_setup( &operation,
3087 handle, alg ) );
3088 PSA_ASSERT( psa_mac_update( &operation,
3089 input->x, input->len ) );
3090 TEST_EQUAL( psa_mac_sign_finish( &operation,
3091 actual_mac, output_size,
3092 &mac_length ),
3093 expected_status );
3094 PSA_ASSERT( psa_mac_abort( &operation ) );
3095
3096 if( expected_status == PSA_SUCCESS )
3097 {
3098 ASSERT_COMPARE( expected_mac->x, expected_mac->len,
3099 actual_mac, mac_length );
3100 }
3101 mbedtls_free( actual_mac );
3102 actual_mac = NULL;
3103 }
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003104
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003105exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003106 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003107 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003108 PSA_DONE( );
Gilles Peskine5e65cec2020-08-25 23:38:39 +02003109 mbedtls_free( actual_mac );
Gilles Peskinea7aa4422018-08-14 15:17:54 +02003110}
3111/* END_CASE */
3112
3113/* BEGIN_CASE */
Gilles Peskinec0ec9722018-06-18 17:03:37 +02003114void mac_verify( int key_type_arg,
3115 data_t *key,
3116 int alg_arg,
3117 data_t *input,
3118 data_t *expected_mac )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003119{
Ronald Cron91e95152020-07-30 17:48:03 +02003120 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003121 psa_key_type_t key_type = key_type_arg;
3122 psa_algorithm_t alg = alg_arg;
Jaeden Amero769ce272019-01-04 11:48:03 +00003123 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003124 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine29c4a6c2020-08-26 00:01:39 +02003125 uint8_t *perturbed_mac = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01003126
Gilles Peskine69c12672018-06-28 00:07:19 +02003127 TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
3128
Gilles Peskine8817f612018-12-18 00:18:46 +01003129 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003130
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003131 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003132 psa_set_key_algorithm( &attributes, alg );
3133 psa_set_key_type( &attributes, key_type );
mohammad16036df908f2018-04-02 08:34:15 -07003134
Gilles Peskine73676cb2019-05-15 20:15:10 +02003135 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskinec0ec9722018-06-18 17:03:37 +02003136
Gilles Peskine29c4a6c2020-08-26 00:01:39 +02003137 /* Test the correct MAC. */
Gilles Peskine8817f612018-12-18 00:18:46 +01003138 PSA_ASSERT( psa_mac_verify_setup( &operation,
3139 handle, alg ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01003140 PSA_ASSERT( psa_mac_update( &operation,
3141 input->x, input->len ) );
3142 PSA_ASSERT( psa_mac_verify_finish( &operation,
3143 expected_mac->x,
3144 expected_mac->len ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003145
Gilles Peskine29c4a6c2020-08-26 00:01:39 +02003146 /* Test a MAC that's too short. */
3147 PSA_ASSERT( psa_mac_verify_setup( &operation,
3148 handle, alg ) );
3149 PSA_ASSERT( psa_mac_update( &operation,
3150 input->x, input->len ) );
3151 TEST_EQUAL( psa_mac_verify_finish( &operation,
3152 expected_mac->x,
3153 expected_mac->len - 1 ),
3154 PSA_ERROR_INVALID_SIGNATURE );
3155
3156 /* Test a MAC that's too long. */
3157 ASSERT_ALLOC( perturbed_mac, expected_mac->len + 1 );
3158 memcpy( perturbed_mac, expected_mac->x, expected_mac->len );
3159 PSA_ASSERT( psa_mac_verify_setup( &operation,
3160 handle, alg ) );
3161 PSA_ASSERT( psa_mac_update( &operation,
3162 input->x, input->len ) );
3163 TEST_EQUAL( psa_mac_verify_finish( &operation,
3164 perturbed_mac,
3165 expected_mac->len + 1 ),
3166 PSA_ERROR_INVALID_SIGNATURE );
3167
3168 /* Test changing one byte. */
3169 for( size_t i = 0; i < expected_mac->len; i++ )
3170 {
3171 test_set_step( i );
3172 perturbed_mac[i] ^= 1;
3173 PSA_ASSERT( psa_mac_verify_setup( &operation,
3174 handle, alg ) );
3175 PSA_ASSERT( psa_mac_update( &operation,
3176 input->x, input->len ) );
3177 TEST_EQUAL( psa_mac_verify_finish( &operation,
3178 perturbed_mac,
3179 expected_mac->len ),
3180 PSA_ERROR_INVALID_SIGNATURE );
3181 perturbed_mac[i] ^= 1;
3182 }
3183
Gilles Peskine8c9def32018-02-08 10:02:12 +01003184exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003185 psa_mac_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003186 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003187 PSA_DONE( );
Gilles Peskine29c4a6c2020-08-26 00:01:39 +02003188 mbedtls_free( perturbed_mac );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003189}
3190/* END_CASE */
3191
3192/* BEGIN_CASE */
Jaeden Amero5bae2272019-01-04 11:48:27 +00003193void cipher_operation_init( )
3194{
Jaeden Ameroab439972019-02-15 14:12:05 +00003195 const uint8_t input[1] = { 0 };
3196 unsigned char output[1] = { 0 };
3197 size_t output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003198 /* Test each valid way of initializing the object, except for `= {0}`, as
3199 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
3200 * though it's OK by the C standard. We could test for this, but we'd need
3201 * to supress the Clang warning for the test. */
3202 psa_cipher_operation_t func = psa_cipher_operation_init( );
3203 psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT;
3204 psa_cipher_operation_t zero;
3205
3206 memset( &zero, 0, sizeof( zero ) );
3207
Jaeden Ameroab439972019-02-15 14:12:05 +00003208 /* A freshly-initialized cipher operation should not be usable. */
3209 TEST_EQUAL( psa_cipher_update( &func,
3210 input, sizeof( input ),
3211 output, sizeof( output ),
3212 &output_length ),
3213 PSA_ERROR_BAD_STATE );
3214 TEST_EQUAL( psa_cipher_update( &init,
3215 input, sizeof( input ),
3216 output, sizeof( output ),
3217 &output_length ),
3218 PSA_ERROR_BAD_STATE );
3219 TEST_EQUAL( psa_cipher_update( &zero,
3220 input, sizeof( input ),
3221 output, sizeof( output ),
3222 &output_length ),
3223 PSA_ERROR_BAD_STATE );
3224
Jaeden Amero5229bbb2019-02-07 16:33:37 +00003225 /* A default cipher operation should be abortable without error. */
3226 PSA_ASSERT( psa_cipher_abort( &func ) );
3227 PSA_ASSERT( psa_cipher_abort( &init ) );
3228 PSA_ASSERT( psa_cipher_abort( &zero ) );
Jaeden Amero5bae2272019-01-04 11:48:27 +00003229}
3230/* END_CASE */
3231
3232/* BEGIN_CASE */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003233void cipher_setup( int key_type_arg,
3234 data_t *key,
3235 int alg_arg,
3236 int expected_status_arg )
3237{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003238 psa_key_type_t key_type = key_type_arg;
3239 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003240 psa_status_t expected_status = expected_status_arg;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003241 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003242 psa_status_t status;
Gilles Peskinef426e0f2019-02-25 17:42:03 +01003243#if defined(KNOWN_SUPPORTED_MAC_ALG)
3244 const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk";
3245#endif
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003246
Gilles Peskine8817f612018-12-18 00:18:46 +01003247 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003248
Gilles Peskinef426e0f2019-02-25 17:42:03 +01003249 if( ! exercise_cipher_setup( key_type, key->x, key->len, alg,
3250 &operation, &status ) )
3251 goto exit;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003252 TEST_EQUAL( status, expected_status );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003253
Gilles Peskinef426e0f2019-02-25 17:42:03 +01003254 /* The operation object should be reusable. */
3255#if defined(KNOWN_SUPPORTED_CIPHER_ALG)
3256 if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE,
3257 smoke_test_key_data,
3258 sizeof( smoke_test_key_data ),
3259 KNOWN_SUPPORTED_CIPHER_ALG,
3260 &operation, &status ) )
3261 goto exit;
3262 TEST_EQUAL( status, PSA_SUCCESS );
3263#endif
3264
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003265exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003266 psa_cipher_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003267 PSA_DONE( );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003268}
3269/* END_CASE */
3270
3271/* BEGIN_CASE */
Jaeden Ameroab439972019-02-15 14:12:05 +00003272void cipher_bad_order( )
3273{
Ronald Cron91e95152020-07-30 17:48:03 +02003274 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00003275 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
3276 psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003277 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Jaeden Ameroab439972019-02-15 14:12:05 +00003278 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
3279 unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
3280 const uint8_t key[] = {
3281 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
3282 0xaa, 0xaa, 0xaa, 0xaa };
3283 const uint8_t text[] = {
3284 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
3285 0xbb, 0xbb, 0xbb, 0xbb };
3286 uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
3287 size_t length = 0;
3288
3289 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003290 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3291 psa_set_key_algorithm( &attributes, alg );
3292 psa_set_key_type( &attributes, key_type );
Gilles Peskine73676cb2019-05-15 20:15:10 +02003293 PSA_ASSERT( psa_import_key( &attributes, key, sizeof( key ), &handle ) );
Jaeden Ameroab439972019-02-15 14:12:05 +00003294
3295
Jaeden Amero36ee5d02019-02-19 09:25:10 +00003296 /* Call encrypt setup twice in a row. */
3297 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3298 TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
3299 PSA_ERROR_BAD_STATE );
3300 PSA_ASSERT( psa_cipher_abort( &operation ) );
3301
3302 /* Call decrypt setup twice in a row. */
3303 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
3304 TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
3305 PSA_ERROR_BAD_STATE );
3306 PSA_ASSERT( psa_cipher_abort( &operation ) );
3307
Jaeden Ameroab439972019-02-15 14:12:05 +00003308 /* Generate an IV without calling setup beforehand. */
3309 TEST_EQUAL( psa_cipher_generate_iv( &operation,
3310 buffer, sizeof( buffer ),
3311 &length ),
3312 PSA_ERROR_BAD_STATE );
3313 PSA_ASSERT( psa_cipher_abort( &operation ) );
3314
3315 /* Generate an IV twice in a row. */
3316 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3317 PSA_ASSERT( psa_cipher_generate_iv( &operation,
3318 buffer, sizeof( buffer ),
3319 &length ) );
3320 TEST_EQUAL( psa_cipher_generate_iv( &operation,
3321 buffer, sizeof( buffer ),
3322 &length ),
3323 PSA_ERROR_BAD_STATE );
3324 PSA_ASSERT( psa_cipher_abort( &operation ) );
3325
3326 /* Generate an IV after it's already set. */
3327 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3328 PSA_ASSERT( psa_cipher_set_iv( &operation,
3329 iv, sizeof( iv ) ) );
3330 TEST_EQUAL( psa_cipher_generate_iv( &operation,
3331 buffer, sizeof( buffer ),
3332 &length ),
3333 PSA_ERROR_BAD_STATE );
3334 PSA_ASSERT( psa_cipher_abort( &operation ) );
3335
3336 /* Set an IV without calling setup beforehand. */
3337 TEST_EQUAL( psa_cipher_set_iv( &operation,
3338 iv, sizeof( iv ) ),
3339 PSA_ERROR_BAD_STATE );
3340 PSA_ASSERT( psa_cipher_abort( &operation ) );
3341
3342 /* Set an IV after it's already set. */
3343 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3344 PSA_ASSERT( psa_cipher_set_iv( &operation,
3345 iv, sizeof( iv ) ) );
3346 TEST_EQUAL( psa_cipher_set_iv( &operation,
3347 iv, sizeof( iv ) ),
3348 PSA_ERROR_BAD_STATE );
3349 PSA_ASSERT( psa_cipher_abort( &operation ) );
3350
3351 /* Set an IV after it's already generated. */
3352 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3353 PSA_ASSERT( psa_cipher_generate_iv( &operation,
3354 buffer, sizeof( buffer ),
3355 &length ) );
3356 TEST_EQUAL( psa_cipher_set_iv( &operation,
3357 iv, sizeof( iv ) ),
3358 PSA_ERROR_BAD_STATE );
3359 PSA_ASSERT( psa_cipher_abort( &operation ) );
3360
3361 /* Call update without calling setup beforehand. */
3362 TEST_EQUAL( psa_cipher_update( &operation,
3363 text, sizeof( text ),
3364 buffer, sizeof( buffer ),
3365 &length ),
3366 PSA_ERROR_BAD_STATE );
3367 PSA_ASSERT( psa_cipher_abort( &operation ) );
3368
3369 /* Call update without an IV where an IV is required. */
3370 TEST_EQUAL( psa_cipher_update( &operation,
3371 text, sizeof( text ),
3372 buffer, sizeof( buffer ),
3373 &length ),
3374 PSA_ERROR_BAD_STATE );
3375 PSA_ASSERT( psa_cipher_abort( &operation ) );
3376
3377 /* Call update after finish. */
3378 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3379 PSA_ASSERT( psa_cipher_set_iv( &operation,
3380 iv, sizeof( iv ) ) );
3381 PSA_ASSERT( psa_cipher_finish( &operation,
3382 buffer, sizeof( buffer ), &length ) );
3383 TEST_EQUAL( psa_cipher_update( &operation,
3384 text, sizeof( text ),
3385 buffer, sizeof( buffer ),
3386 &length ),
3387 PSA_ERROR_BAD_STATE );
3388 PSA_ASSERT( psa_cipher_abort( &operation ) );
3389
3390 /* Call finish without calling setup beforehand. */
3391 TEST_EQUAL( psa_cipher_finish( &operation,
3392 buffer, sizeof( buffer ), &length ),
3393 PSA_ERROR_BAD_STATE );
3394 PSA_ASSERT( psa_cipher_abort( &operation ) );
3395
3396 /* Call finish without an IV where an IV is required. */
3397 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3398 /* Not calling update means we are encrypting an empty buffer, which is OK
3399 * for cipher modes with padding. */
3400 TEST_EQUAL( psa_cipher_finish( &operation,
3401 buffer, sizeof( buffer ), &length ),
3402 PSA_ERROR_BAD_STATE );
3403 PSA_ASSERT( psa_cipher_abort( &operation ) );
3404
3405 /* Call finish twice in a row. */
3406 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
3407 PSA_ASSERT( psa_cipher_set_iv( &operation,
3408 iv, sizeof( iv ) ) );
3409 PSA_ASSERT( psa_cipher_finish( &operation,
3410 buffer, sizeof( buffer ), &length ) );
3411 TEST_EQUAL( psa_cipher_finish( &operation,
3412 buffer, sizeof( buffer ), &length ),
3413 PSA_ERROR_BAD_STATE );
3414 PSA_ASSERT( psa_cipher_abort( &operation ) );
3415
Gilles Peskine76b29a72019-05-28 14:08:50 +02003416 PSA_ASSERT( psa_destroy_key( handle ) );
3417
Jaeden Ameroab439972019-02-15 14:12:05 +00003418exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003419 psa_cipher_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003420 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003421}
3422/* END_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003423
Gilles Peskine50e586b2018-06-08 14:28:46 +02003424/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003425void cipher_encrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003426 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003427 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003428 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003429{
Ronald Cron91e95152020-07-30 17:48:03 +02003430 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003431 psa_status_t status;
3432 psa_key_type_t key_type = key_type_arg;
3433 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003434 psa_status_t expected_status = expected_status_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003435 unsigned char *output = NULL;
3436 size_t output_buffer_size = 0;
3437 size_t function_output_length = 0;
3438 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003439 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003440 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003441
Gilles Peskine8817f612018-12-18 00:18:46 +01003442 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003443
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003444 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
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 ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003449
Gilles Peskine8817f612018-12-18 00:18:46 +01003450 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3451 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003452
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003453 if( iv->len > 0 )
3454 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003455 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003456 }
3457
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003458 output_buffer_size = ( (size_t) input->len +
3459 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003460 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003461
Gilles Peskine8817f612018-12-18 00:18:46 +01003462 PSA_ASSERT( psa_cipher_update( &operation,
3463 input->x, input->len,
3464 output, output_buffer_size,
3465 &function_output_length ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003466 total_output_length += function_output_length;
3467 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003468 output + total_output_length,
3469 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003470 &function_output_length );
3471 total_output_length += function_output_length;
3472
Gilles Peskinefe11b722018-12-18 00:24:04 +01003473 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003474 if( expected_status == PSA_SUCCESS )
3475 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003476 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003477 ASSERT_COMPARE( expected_output->x, expected_output->len,
3478 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003479 }
3480
3481exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003482 psa_cipher_abort( &operation );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003483 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003484 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003485 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003486}
3487/* END_CASE */
3488
3489/* BEGIN_CASE */
3490void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003491 data_t *key, data_t *iv,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003492 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003493 int first_part_size_arg,
3494 int output1_length_arg, int output2_length_arg,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003495 data_t *expected_output )
3496{
Ronald Cron91e95152020-07-30 17:48:03 +02003497 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003498 psa_key_type_t key_type = key_type_arg;
3499 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003500 size_t first_part_size = first_part_size_arg;
3501 size_t output1_length = output1_length_arg;
3502 size_t output2_length = output2_length_arg;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003503 unsigned char *output = NULL;
3504 size_t output_buffer_size = 0;
3505 size_t function_output_length = 0;
3506 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003507 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003508 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003509
Gilles Peskine8817f612018-12-18 00:18:46 +01003510 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003511
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003512 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
3513 psa_set_key_algorithm( &attributes, alg );
3514 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003515
Gilles Peskine73676cb2019-05-15 20:15:10 +02003516 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003517
Gilles Peskine8817f612018-12-18 00:18:46 +01003518 PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
3519 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003520
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003521 if( iv->len > 0 )
3522 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003523 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003524 }
3525
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003526 output_buffer_size = ( (size_t) input->len +
3527 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003528 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003529
Gilles Peskinee0866522019-02-19 19:44:00 +01003530 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003531 PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
3532 output, output_buffer_size,
3533 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003534 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003535 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003536 PSA_ASSERT( psa_cipher_update( &operation,
3537 input->x + first_part_size,
3538 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003539 output + total_output_length,
3540 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003541 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003542 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003543 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003544 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003545 output + total_output_length,
3546 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003547 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003548 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003549 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003550
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003551 ASSERT_COMPARE( expected_output->x, expected_output->len,
3552 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003553
3554exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003555 psa_cipher_abort( &operation );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003556 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003557 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003558 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003559}
3560/* END_CASE */
3561
3562/* BEGIN_CASE */
3563void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003564 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003565 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003566 int first_part_size_arg,
3567 int output1_length_arg, int output2_length_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003568 data_t *expected_output )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003569{
Ronald Cron91e95152020-07-30 17:48:03 +02003570 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003571 psa_key_type_t key_type = key_type_arg;
3572 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003573 size_t first_part_size = first_part_size_arg;
3574 size_t output1_length = output1_length_arg;
3575 size_t output2_length = output2_length_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003576 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003577 size_t output_buffer_size = 0;
3578 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003579 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003580 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003581 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003582
Gilles Peskine8817f612018-12-18 00:18:46 +01003583 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003584
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003585 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3586 psa_set_key_algorithm( &attributes, alg );
3587 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003588
Gilles Peskine73676cb2019-05-15 20:15:10 +02003589 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003590
Gilles Peskine8817f612018-12-18 00:18:46 +01003591 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3592 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003593
Steven Cooreman177deba2020-09-07 17:14:14 +02003594 if( iv->len > 0 )
3595 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003596 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003597 }
Gilles Peskine50e586b2018-06-08 14:28:46 +02003598
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003599 output_buffer_size = ( (size_t) input->len +
3600 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003601 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003602
Gilles Peskinee0866522019-02-19 19:44:00 +01003603 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine8817f612018-12-18 00:18:46 +01003604 PSA_ASSERT( psa_cipher_update( &operation,
3605 input->x, first_part_size,
3606 output, output_buffer_size,
3607 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003608 TEST_ASSERT( function_output_length == output1_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003609 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003610 PSA_ASSERT( psa_cipher_update( &operation,
3611 input->x + first_part_size,
3612 input->len - first_part_size,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003613 output + total_output_length,
3614 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003615 &function_output_length ) );
Gilles Peskinee0866522019-02-19 19:44:00 +01003616 TEST_ASSERT( function_output_length == output2_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003617 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003618 PSA_ASSERT( psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003619 output + total_output_length,
3620 output_buffer_size - total_output_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003621 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003622 total_output_length += function_output_length;
Gilles Peskine8817f612018-12-18 00:18:46 +01003623 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003624
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003625 ASSERT_COMPARE( expected_output->x, expected_output->len,
3626 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003627
3628exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003629 psa_cipher_abort( &operation );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003630 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003631 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003632 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003633}
3634/* END_CASE */
3635
Gilles Peskine50e586b2018-06-08 14:28:46 +02003636/* BEGIN_CASE */
3637void cipher_decrypt( int alg_arg, int key_type_arg,
Gilles Peskine423005e2019-05-06 15:22:57 +02003638 data_t *key, data_t *iv,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003639 data_t *input, data_t *expected_output,
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003640 int expected_status_arg )
Gilles Peskine50e586b2018-06-08 14:28:46 +02003641{
Ronald Cron91e95152020-07-30 17:48:03 +02003642 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003643 psa_status_t status;
3644 psa_key_type_t key_type = key_type_arg;
3645 psa_algorithm_t alg = alg_arg;
Gilles Peskineb866e2b2018-06-21 09:25:10 +02003646 psa_status_t expected_status = expected_status_arg;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003647 unsigned char *output = NULL;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003648 size_t output_buffer_size = 0;
3649 size_t function_output_length = 0;
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003650 size_t total_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003651 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003652 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003653
Gilles Peskine8817f612018-12-18 00:18:46 +01003654 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003655
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003656 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
3657 psa_set_key_algorithm( &attributes, alg );
3658 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003659
Gilles Peskine73676cb2019-05-15 20:15:10 +02003660 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003661
Gilles Peskine8817f612018-12-18 00:18:46 +01003662 PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
3663 handle, alg ) );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003664
Steven Cooreman177deba2020-09-07 17:14:14 +02003665 if( iv->len > 0 )
3666 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003667 PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003668 }
Gilles Peskine50e586b2018-06-08 14:28:46 +02003669
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003670 output_buffer_size = ( (size_t) input->len +
3671 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003672 ASSERT_ALLOC( output, output_buffer_size );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003673
Gilles Peskine8817f612018-12-18 00:18:46 +01003674 PSA_ASSERT( psa_cipher_update( &operation,
3675 input->x, input->len,
3676 output, output_buffer_size,
3677 &function_output_length ) );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003678 total_output_length += function_output_length;
Gilles Peskine50e586b2018-06-08 14:28:46 +02003679 status = psa_cipher_finish( &operation,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003680 output + total_output_length,
3681 output_buffer_size - total_output_length,
Gilles Peskine50e586b2018-06-08 14:28:46 +02003682 &function_output_length );
Gilles Peskinea7ec95f2018-06-08 14:40:59 +02003683 total_output_length += function_output_length;
Gilles Peskinefe11b722018-12-18 00:24:04 +01003684 TEST_EQUAL( status, expected_status );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003685
3686 if( expected_status == PSA_SUCCESS )
3687 {
Gilles Peskine8817f612018-12-18 00:18:46 +01003688 PSA_ASSERT( psa_cipher_abort( &operation ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003689 ASSERT_COMPARE( expected_output->x, expected_output->len,
3690 output, total_output_length );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003691 }
3692
Gilles Peskine50e586b2018-06-08 14:28:46 +02003693exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003694 psa_cipher_abort( &operation );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003695 mbedtls_free( output );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003696 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003697 PSA_DONE( );
Gilles Peskine50e586b2018-06-08 14:28:46 +02003698}
3699/* END_CASE */
3700
Gilles Peskine50e586b2018-06-08 14:28:46 +02003701/* BEGIN_CASE */
3702void cipher_verify_output( int alg_arg, int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003703 data_t *key,
3704 data_t *input )
mohammad1603d7d7ba52018-03-12 18:51:53 +02003705{
Ronald Cron91e95152020-07-30 17:48:03 +02003706 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003707 psa_key_type_t key_type = key_type_arg;
3708 psa_algorithm_t alg = alg_arg;
mohammad1603e6b67a12018-03-12 10:38:49 -07003709 unsigned char iv[16] = {0};
mohammad1603d7d7ba52018-03-12 18:51:53 +02003710 size_t iv_size = 16;
3711 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003712 unsigned char *output1 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003713 size_t output1_size = 0;
3714 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003715 unsigned char *output2 = NULL;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003716 size_t output2_size = 0;
3717 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003718 size_t function_output_length = 0;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003719 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3720 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003721 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003722
Gilles Peskine8817f612018-12-18 00:18:46 +01003723 PSA_ASSERT( psa_crypto_init( ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003724
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003725 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3726 psa_set_key_algorithm( &attributes, alg );
3727 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003728
Gilles Peskine73676cb2019-05-15 20:15:10 +02003729 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003730
Gilles Peskine8817f612018-12-18 00:18:46 +01003731 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3732 handle, alg ) );
3733 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3734 handle, alg ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003735
Steven Cooreman177deba2020-09-07 17:14:14 +02003736 if( alg != PSA_ALG_ECB_NO_PADDING )
3737 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003738 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3739 iv, iv_size,
3740 &iv_length ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003741 }
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003742 output1_size = ( (size_t) input->len +
3743 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003744 ASSERT_ALLOC( output1, output1_size );
Moran Pekerded84402018-06-06 16:36:50 +03003745
Gilles Peskine8817f612018-12-18 00:18:46 +01003746 PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
3747 output1, output1_size,
3748 &output1_length ) );
3749 PSA_ASSERT( psa_cipher_finish( &operation1,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003750 output1 + output1_length,
3751 output1_size - output1_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003752 &function_output_length ) );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003753
Gilles Peskine048b7f02018-06-08 14:20:49 +02003754 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003755
Gilles Peskine8817f612018-12-18 00:18:46 +01003756 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003757
3758 output2_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003759 ASSERT_ALLOC( output2, output2_size );
Moran Pekerded84402018-06-06 16:36:50 +03003760
Steven Cooreman177deba2020-09-07 17:14:14 +02003761 if( iv_length > 0 )
3762 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003763 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3764 iv, iv_length ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003765 }
3766
Gilles Peskine8817f612018-12-18 00:18:46 +01003767 PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
3768 output2, output2_size,
3769 &output2_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003770 function_output_length = 0;
Gilles Peskine8817f612018-12-18 00:18:46 +01003771 PSA_ASSERT( psa_cipher_finish( &operation2,
3772 output2 + output2_length,
Gilles Peskineee46fe72019-02-19 19:05:33 +01003773 output2_size - output2_length,
Gilles Peskine8817f612018-12-18 00:18:46 +01003774 &function_output_length ) );
Moran Pekerded84402018-06-06 16:36:50 +03003775
Gilles Peskine048b7f02018-06-08 14:20:49 +02003776 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003777
Gilles Peskine8817f612018-12-18 00:18:46 +01003778 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
Moran Pekerded84402018-06-06 16:36:50 +03003779
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003780 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
Moran Pekerded84402018-06-06 16:36:50 +03003781
3782exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003783 psa_cipher_abort( &operation1 );
3784 psa_cipher_abort( &operation2 );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003785 mbedtls_free( output1 );
3786 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003787 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003788 PSA_DONE( );
Moran Pekerded84402018-06-06 16:36:50 +03003789}
3790/* END_CASE */
3791
3792/* BEGIN_CASE */
Gilles Peskine50e586b2018-06-08 14:28:46 +02003793void cipher_verify_output_multipart( int alg_arg,
3794 int key_type_arg,
itayzafrir3e02b3b2018-06-12 17:06:52 +03003795 data_t *key,
3796 data_t *input,
Gilles Peskinee0866522019-02-19 19:44:00 +01003797 int first_part_size_arg )
Moran Pekerded84402018-06-06 16:36:50 +03003798{
Ronald Cron91e95152020-07-30 17:48:03 +02003799 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003800 psa_key_type_t key_type = key_type_arg;
3801 psa_algorithm_t alg = alg_arg;
Gilles Peskinee0866522019-02-19 19:44:00 +01003802 size_t first_part_size = first_part_size_arg;
Moran Pekerded84402018-06-06 16:36:50 +03003803 unsigned char iv[16] = {0};
3804 size_t iv_size = 16;
3805 size_t iv_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003806 unsigned char *output1 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003807 size_t output1_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003808 size_t output1_length = 0;
itayzafrir3e02b3b2018-06-12 17:06:52 +03003809 unsigned char *output2 = NULL;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003810 size_t output2_buffer_size = 0;
Moran Pekerded84402018-06-06 16:36:50 +03003811 size_t output2_length = 0;
Gilles Peskine048b7f02018-06-08 14:20:49 +02003812 size_t function_output_length;
Jaeden Amero5bae2272019-01-04 11:48:27 +00003813 psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
3814 psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003815 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Moran Pekerded84402018-06-06 16:36:50 +03003816
Gilles Peskine8817f612018-12-18 00:18:46 +01003817 PSA_ASSERT( psa_crypto_init( ) );
Moran Pekerded84402018-06-06 16:36:50 +03003818
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003819 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3820 psa_set_key_algorithm( &attributes, alg );
3821 psa_set_key_type( &attributes, key_type );
Moran Pekered346952018-07-05 15:22:45 +03003822
Gilles Peskine73676cb2019-05-15 20:15:10 +02003823 PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
Moran Pekerded84402018-06-06 16:36:50 +03003824
Gilles Peskine8817f612018-12-18 00:18:46 +01003825 PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
3826 handle, alg ) );
3827 PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
3828 handle, alg ) );
Moran Pekerded84402018-06-06 16:36:50 +03003829
Steven Cooreman177deba2020-09-07 17:14:14 +02003830 if( alg != PSA_ALG_ECB_NO_PADDING )
3831 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003832 PSA_ASSERT( psa_cipher_generate_iv( &operation1,
3833 iv, iv_size,
3834 &iv_length ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003835 }
3836
Gilles Peskine9d8eea72018-12-17 23:34:57 +01003837 output1_buffer_size = ( (size_t) input->len +
3838 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003839 ASSERT_ALLOC( output1, output1_buffer_size );
Moran Pekerded84402018-06-06 16:36:50 +03003840
Gilles Peskinee0866522019-02-19 19:44:00 +01003841 TEST_ASSERT( first_part_size <= input->len );
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003842
Gilles Peskine8817f612018-12-18 00:18:46 +01003843 PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
3844 output1, output1_buffer_size,
3845 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003846 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003847
Gilles Peskine8817f612018-12-18 00:18:46 +01003848 PSA_ASSERT( psa_cipher_update( &operation1,
3849 input->x + first_part_size,
3850 input->len - first_part_size,
3851 output1, output1_buffer_size,
3852 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003853 output1_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003854
Gilles Peskine8817f612018-12-18 00:18:46 +01003855 PSA_ASSERT( psa_cipher_finish( &operation1,
3856 output1 + output1_length,
3857 output1_buffer_size - output1_length,
3858 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003859 output1_length += function_output_length;
mohammad1603d7d7ba52018-03-12 18:51:53 +02003860
Gilles Peskine8817f612018-12-18 00:18:46 +01003861 PSA_ASSERT( psa_cipher_abort( &operation1 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003862
Gilles Peskine048b7f02018-06-08 14:20:49 +02003863 output2_buffer_size = output1_length;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003864 ASSERT_ALLOC( output2, output2_buffer_size );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003865
Steven Cooreman177deba2020-09-07 17:14:14 +02003866 if( iv_length > 0 )
3867 {
Steven Cooremana6033e92020-08-25 11:47:50 +02003868 PSA_ASSERT( psa_cipher_set_iv( &operation2,
3869 iv, iv_length ) );
Steven Cooremaned3c9ec2020-07-06 14:08:59 +02003870 }
Moran Pekerded84402018-06-06 16:36:50 +03003871
Gilles Peskine8817f612018-12-18 00:18:46 +01003872 PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
3873 output2, output2_buffer_size,
3874 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003875 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003876
Gilles Peskine8817f612018-12-18 00:18:46 +01003877 PSA_ASSERT( psa_cipher_update( &operation2,
3878 output1 + first_part_size,
3879 output1_length - first_part_size,
3880 output2, output2_buffer_size,
3881 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003882 output2_length += function_output_length;
Moran Pekerded84402018-06-06 16:36:50 +03003883
Gilles Peskine8817f612018-12-18 00:18:46 +01003884 PSA_ASSERT( psa_cipher_finish( &operation2,
3885 output2 + output2_length,
3886 output2_buffer_size - output2_length,
3887 &function_output_length ) );
Gilles Peskine048b7f02018-06-08 14:20:49 +02003888 output2_length += function_output_length;
Gilles Peskine4ca9c3f2018-06-06 18:44:09 +02003889
Gilles Peskine8817f612018-12-18 00:18:46 +01003890 PSA_ASSERT( psa_cipher_abort( &operation2 ) );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003891
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003892 ASSERT_COMPARE( input->x, input->len, output2, output2_length );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003893
3894exit:
Gilles Peskine64f13ef2020-08-25 23:15:20 +02003895 psa_cipher_abort( &operation1 );
3896 psa_cipher_abort( &operation2 );
itayzafrir3e02b3b2018-06-12 17:06:52 +03003897 mbedtls_free( output1 );
3898 mbedtls_free( output2 );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003899 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003900 PSA_DONE( );
mohammad1603d7d7ba52018-03-12 18:51:53 +02003901}
3902/* END_CASE */
Gilles Peskine7268afc2018-06-06 15:19:24 +02003903
Gilles Peskine20035e32018-02-03 22:44:14 +01003904/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003905void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003906 int alg_arg,
Gilles Peskine7da96b02018-08-17 18:45:42 +02003907 data_t *nonce,
3908 data_t *additional_data,
3909 data_t *input_data,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003910 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003911{
Ronald Cron91e95152020-07-30 17:48:03 +02003912 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003913 psa_key_type_t key_type = key_type_arg;
3914 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003915 unsigned char *output_data = NULL;
3916 size_t output_size = 0;
3917 size_t output_length = 0;
3918 unsigned char *output_data2 = NULL;
3919 size_t output_length2 = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003920 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine4abf7412018-06-18 16:35:34 +02003921 psa_status_t expected_result = expected_result_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003922 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003923
Gilles Peskine4abf7412018-06-18 16:35:34 +02003924 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003925 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3926 * should be exact. */
3927 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
3928 TEST_EQUAL( output_size,
3929 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003930 ASSERT_ALLOC( output_data, output_size );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003931
Gilles Peskine8817f612018-12-18 00:18:46 +01003932 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003933
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003934 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
3935 psa_set_key_algorithm( &attributes, alg );
3936 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003937
Gilles Peskine049c7532019-05-15 20:22:09 +02003938 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
3939 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003940
Gilles Peskinefe11b722018-12-18 00:24:04 +01003941 TEST_EQUAL( psa_aead_encrypt( handle, alg,
3942 nonce->x, nonce->len,
3943 additional_data->x,
3944 additional_data->len,
3945 input_data->x, input_data->len,
3946 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003947 &output_length ),
3948 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003949
3950 if( PSA_SUCCESS == expected_result )
3951 {
Gilles Peskine8cebbba2018-09-27 13:54:18 +02003952 ASSERT_ALLOC( output_data2, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003953
Gilles Peskine003a4a92019-05-14 16:09:40 +02003954 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
3955 * should be exact. */
3956 TEST_EQUAL( input_data->len,
3957 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) );
3958
Gilles Peskinefe11b722018-12-18 00:24:04 +01003959 TEST_EQUAL( psa_aead_decrypt( handle, alg,
3960 nonce->x, nonce->len,
3961 additional_data->x,
3962 additional_data->len,
3963 output_data, output_length,
3964 output_data2, output_length,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01003965 &output_length2 ),
3966 expected_result );
Gilles Peskine2d277862018-06-18 15:41:12 +02003967
Gilles Peskinebd7dea92018-09-27 13:57:19 +02003968 ASSERT_COMPARE( input_data->x, input_data->len,
3969 output_data2, output_length2 );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003970 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003971
Gilles Peskinea1cac842018-06-11 19:33:02 +02003972exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01003973 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003974 mbedtls_free( output_data );
3975 mbedtls_free( output_data2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02003976 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02003977}
3978/* END_CASE */
3979
3980/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02003981void aead_encrypt( int key_type_arg, data_t *key_data,
3982 int alg_arg,
3983 data_t *nonce,
3984 data_t *additional_data,
3985 data_t *input_data,
3986 data_t *expected_result )
Gilles Peskinea1cac842018-06-11 19:33:02 +02003987{
Ronald Cron91e95152020-07-30 17:48:03 +02003988 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003989 psa_key_type_t key_type = key_type_arg;
3990 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003991 unsigned char *output_data = NULL;
3992 size_t output_size = 0;
3993 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003994 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02003995 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02003996
Gilles Peskine4abf7412018-06-18 16:35:34 +02003997 output_size = input_data->len + tag_length;
Gilles Peskine003a4a92019-05-14 16:09:40 +02003998 /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE
3999 * should be exact. */
4000 TEST_EQUAL( output_size,
4001 PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004002 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02004003
Gilles Peskine8817f612018-12-18 00:18:46 +01004004 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004005
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004006 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
4007 psa_set_key_algorithm( &attributes, alg );
4008 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004009
Gilles Peskine049c7532019-05-15 20:22:09 +02004010 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4011 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004012
Gilles Peskine8817f612018-12-18 00:18:46 +01004013 PSA_ASSERT( psa_aead_encrypt( handle, alg,
4014 nonce->x, nonce->len,
4015 additional_data->x, additional_data->len,
4016 input_data->x, input_data->len,
4017 output_data, output_size,
4018 &output_length ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004019
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004020 ASSERT_COMPARE( expected_result->x, expected_result->len,
4021 output_data, output_length );
Gilles Peskine2d277862018-06-18 15:41:12 +02004022
Gilles Peskinea1cac842018-06-11 19:33:02 +02004023exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004024 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004025 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004026 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004027}
4028/* END_CASE */
4029
4030/* BEGIN_CASE */
Gilles Peskine7da96b02018-08-17 18:45:42 +02004031void aead_decrypt( int key_type_arg, data_t *key_data,
4032 int alg_arg,
4033 data_t *nonce,
4034 data_t *additional_data,
4035 data_t *input_data,
4036 data_t *expected_data,
4037 int expected_result_arg )
Gilles Peskinea1cac842018-06-11 19:33:02 +02004038{
Ronald Cron91e95152020-07-30 17:48:03 +02004039 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinea1cac842018-06-11 19:33:02 +02004040 psa_key_type_t key_type = key_type_arg;
4041 psa_algorithm_t alg = alg_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02004042 unsigned char *output_data = NULL;
4043 size_t output_size = 0;
4044 size_t output_length = 0;
Gilles Peskine003a4a92019-05-14 16:09:40 +02004045 size_t tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004046 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine4abf7412018-06-18 16:35:34 +02004047 psa_status_t expected_result = expected_result_arg;
Gilles Peskinea1cac842018-06-11 19:33:02 +02004048
Gilles Peskine003a4a92019-05-14 16:09:40 +02004049 output_size = input_data->len - tag_length;
4050 /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE
4051 * should be exact. */
4052 if( expected_result != PSA_ERROR_INVALID_ARGUMENT )
4053 TEST_EQUAL( output_size,
4054 PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004055 ASSERT_ALLOC( output_data, output_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02004056
Gilles Peskine8817f612018-12-18 00:18:46 +01004057 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004058
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004059 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4060 psa_set_key_algorithm( &attributes, alg );
4061 psa_set_key_type( &attributes, key_type );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004062
Gilles Peskine049c7532019-05-15 20:22:09 +02004063 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4064 &handle ) );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004065
Gilles Peskinefe11b722018-12-18 00:24:04 +01004066 TEST_EQUAL( psa_aead_decrypt( handle, alg,
4067 nonce->x, nonce->len,
4068 additional_data->x,
4069 additional_data->len,
4070 input_data->x, input_data->len,
4071 output_data, output_size,
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004072 &output_length ),
4073 expected_result );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004074
Gilles Peskine2d277862018-06-18 15:41:12 +02004075 if( expected_result == PSA_SUCCESS )
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004076 ASSERT_COMPARE( expected_data->x, expected_data->len,
4077 output_data, output_length );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004078
Gilles Peskinea1cac842018-06-11 19:33:02 +02004079exit:
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004080 psa_destroy_key( handle );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004081 mbedtls_free( output_data );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004082 PSA_DONE( );
Gilles Peskinea1cac842018-06-11 19:33:02 +02004083}
4084/* END_CASE */
4085
4086/* BEGIN_CASE */
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02004087void signature_size( int type_arg,
4088 int bits,
4089 int alg_arg,
4090 int expected_size_arg )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004091{
4092 psa_key_type_t type = type_arg;
4093 psa_algorithm_t alg = alg_arg;
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004094 size_t actual_size = PSA_SIGN_OUTPUT_SIZE( type, bits, alg );
Gilles Peskine841b14b2019-11-26 17:37:37 +01004095
Gilles Peskinefe11b722018-12-18 00:24:04 +01004096 TEST_EQUAL( actual_size, (size_t) expected_size_arg );
Gilles Peskine841b14b2019-11-26 17:37:37 +01004097#if defined(MBEDTLS_TEST_DEPRECATED)
4098 TEST_EQUAL( actual_size,
4099 PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg ) );
4100#endif /* MBEDTLS_TEST_DEPRECATED */
4101
Gilles Peskinee59236f2018-01-27 23:32:46 +01004102exit:
4103 ;
4104}
4105/* END_CASE */
4106
4107/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03004108void sign_deterministic( int key_type_arg, data_t *key_data,
4109 int alg_arg, data_t *input_data,
4110 data_t *output_data )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004111{
Ronald Cron91e95152020-07-30 17:48:03 +02004112 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004113 psa_key_type_t key_type = key_type_arg;
4114 psa_algorithm_t alg = alg_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01004115 size_t key_bits;
Gilles Peskine20035e32018-02-03 22:44:14 +01004116 unsigned char *signature = NULL;
4117 size_t signature_size;
4118 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004119 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01004120
Gilles Peskine8817f612018-12-18 00:18:46 +01004121 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01004122
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004123 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004124 psa_set_key_algorithm( &attributes, alg );
4125 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07004126
Gilles Peskine049c7532019-05-15 20:22:09 +02004127 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4128 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004129 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4130 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine20035e32018-02-03 22:44:14 +01004131
Gilles Peskine860ce9d2018-06-28 12:23:00 +02004132 /* Allocate a buffer which has the size advertized by the
4133 * library. */
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004134 signature_size = PSA_SIGN_OUTPUT_SIZE( key_type,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02004135 key_bits, alg );
Gilles Peskine20035e32018-02-03 22:44:14 +01004136 TEST_ASSERT( signature_size != 0 );
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004137 TEST_ASSERT( signature_size <= PSA_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004138 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01004139
Gilles Peskine860ce9d2018-06-28 12:23:00 +02004140 /* Perform the signature. */
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004141 PSA_ASSERT( psa_sign_hash( handle, alg,
4142 input_data->x, input_data->len,
4143 signature, signature_size,
4144 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02004145 /* Verify that the signature is what is expected. */
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004146 ASSERT_COMPARE( output_data->x, output_data->len,
4147 signature, signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01004148
Gilles Peskine0627f982019-11-26 19:12:16 +01004149#if defined(MBEDTLS_TEST_DEPRECATED)
Gilles Peskine895242b2019-11-29 12:15:40 +01004150 memset( signature, 0, signature_size );
4151 signature_length = INVALID_EXPORT_LENGTH;
Gilles Peskine0627f982019-11-26 19:12:16 +01004152 PSA_ASSERT( psa_asymmetric_sign( handle, alg,
4153 input_data->x, input_data->len,
4154 signature, signature_size,
4155 &signature_length ) );
4156 ASSERT_COMPARE( output_data->x, output_data->len,
4157 signature, signature_length );
4158#endif /* MBEDTLS_TEST_DEPRECATED */
4159
Gilles Peskine20035e32018-02-03 22:44:14 +01004160exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004161 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004162 psa_destroy_key( handle );
Gilles Peskine0189e752018-02-03 23:57:22 +01004163 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004164 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01004165}
4166/* END_CASE */
4167
4168/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03004169void sign_fail( int key_type_arg, data_t *key_data,
4170 int alg_arg, data_t *input_data,
Gilles Peskine860ce9d2018-06-28 12:23:00 +02004171 int signature_size_arg, int expected_status_arg )
Gilles Peskine20035e32018-02-03 22:44:14 +01004172{
Ronald Cron91e95152020-07-30 17:48:03 +02004173 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01004174 psa_key_type_t key_type = key_type_arg;
4175 psa_algorithm_t alg = alg_arg;
Gilles Peskine860ce9d2018-06-28 12:23:00 +02004176 size_t signature_size = signature_size_arg;
Gilles Peskine20035e32018-02-03 22:44:14 +01004177 psa_status_t actual_status;
4178 psa_status_t expected_status = expected_status_arg;
Gilles Peskine40f68b92018-03-07 16:43:36 +01004179 unsigned char *signature = NULL;
Gilles Peskine93aa0332018-02-03 23:58:03 +01004180 size_t signature_length = 0xdeadbeef;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004181 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine20035e32018-02-03 22:44:14 +01004182
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004183 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01004184
Gilles Peskine8817f612018-12-18 00:18:46 +01004185 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01004186
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004187 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004188 psa_set_key_algorithm( &attributes, alg );
4189 psa_set_key_type( &attributes, key_type );
mohammad1603a97cb8c2018-03-28 03:46:26 -07004190
Gilles Peskine049c7532019-05-15 20:22:09 +02004191 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4192 &handle ) );
Gilles Peskine20035e32018-02-03 22:44:14 +01004193
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004194 actual_status = psa_sign_hash( handle, alg,
4195 input_data->x, input_data->len,
4196 signature, signature_size,
4197 &signature_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004198 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine860ce9d2018-06-28 12:23:00 +02004199 /* The value of *signature_length is unspecified on error, but
4200 * whatever it is, it should be less than signature_size, so that
4201 * if the caller tries to read *signature_length bytes without
4202 * checking the error code then they don't overflow a buffer. */
4203 TEST_ASSERT( signature_length <= signature_size );
Gilles Peskine20035e32018-02-03 22:44:14 +01004204
Gilles Peskine895242b2019-11-29 12:15:40 +01004205#if defined(MBEDTLS_TEST_DEPRECATED)
4206 signature_length = INVALID_EXPORT_LENGTH;
4207 TEST_EQUAL( psa_asymmetric_sign( handle, alg,
4208 input_data->x, input_data->len,
4209 signature, signature_size,
4210 &signature_length ),
4211 expected_status );
4212 TEST_ASSERT( signature_length <= signature_size );
4213#endif /* MBEDTLS_TEST_DEPRECATED */
4214
Gilles Peskine20035e32018-02-03 22:44:14 +01004215exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004216 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004217 psa_destroy_key( handle );
Gilles Peskine20035e32018-02-03 22:44:14 +01004218 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004219 PSA_DONE( );
Gilles Peskine20035e32018-02-03 22:44:14 +01004220}
4221/* END_CASE */
mohammad16038cc1cee2018-03-28 01:21:33 +03004222
4223/* BEGIN_CASE */
Gilles Peskine9911b022018-06-29 17:30:48 +02004224void sign_verify( int key_type_arg, data_t *key_data,
4225 int alg_arg, data_t *input_data )
4226{
Ronald Cron91e95152020-07-30 17:48:03 +02004227 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02004228 psa_key_type_t key_type = key_type_arg;
4229 psa_algorithm_t alg = alg_arg;
4230 size_t key_bits;
4231 unsigned char *signature = NULL;
4232 size_t signature_size;
4233 size_t signature_length = 0xdeadbeef;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004234 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine9911b022018-06-29 17:30:48 +02004235
Gilles Peskine8817f612018-12-18 00:18:46 +01004236 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02004237
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004238 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004239 psa_set_key_algorithm( &attributes, alg );
4240 psa_set_key_type( &attributes, key_type );
Gilles Peskine9911b022018-06-29 17:30:48 +02004241
Gilles Peskine049c7532019-05-15 20:22:09 +02004242 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4243 &handle ) );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004244 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4245 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine9911b022018-06-29 17:30:48 +02004246
4247 /* Allocate a buffer which has the size advertized by the
4248 * library. */
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004249 signature_size = PSA_SIGN_OUTPUT_SIZE( key_type,
Gilles Peskine9911b022018-06-29 17:30:48 +02004250 key_bits, alg );
4251 TEST_ASSERT( signature_size != 0 );
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004252 TEST_ASSERT( signature_size <= PSA_SIGNATURE_MAX_SIZE );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004253 ASSERT_ALLOC( signature, signature_size );
Gilles Peskine9911b022018-06-29 17:30:48 +02004254
4255 /* Perform the signature. */
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004256 PSA_ASSERT( psa_sign_hash( handle, alg,
4257 input_data->x, input_data->len,
4258 signature, signature_size,
4259 &signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02004260 /* Check that the signature length looks sensible. */
4261 TEST_ASSERT( signature_length <= signature_size );
4262 TEST_ASSERT( signature_length > 0 );
4263
4264 /* Use the library to verify that the signature is correct. */
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004265 PSA_ASSERT( psa_verify_hash( handle, alg,
4266 input_data->x, input_data->len,
4267 signature, signature_length ) );
Gilles Peskine9911b022018-06-29 17:30:48 +02004268
4269 if( input_data->len != 0 )
4270 {
4271 /* Flip a bit in the input and verify that the signature is now
4272 * detected as invalid. Flip a bit at the beginning, not at the end,
4273 * because ECDSA may ignore the last few bits of the input. */
4274 input_data->x[0] ^= 1;
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004275 TEST_EQUAL( psa_verify_hash( handle, alg,
4276 input_data->x, input_data->len,
4277 signature, signature_length ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004278 PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine9911b022018-06-29 17:30:48 +02004279 }
4280
4281exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004282 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004283 psa_destroy_key( handle );
Gilles Peskine9911b022018-06-29 17:30:48 +02004284 mbedtls_free( signature );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004285 PSA_DONE( );
Gilles Peskine9911b022018-06-29 17:30:48 +02004286}
4287/* END_CASE */
4288
4289/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03004290void asymmetric_verify( int key_type_arg, data_t *key_data,
4291 int alg_arg, data_t *hash_data,
4292 data_t *signature_data )
itayzafrir5c753392018-05-08 11:18:38 +03004293{
Ronald Cron91e95152020-07-30 17:48:03 +02004294 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03004295 psa_key_type_t key_type = key_type_arg;
4296 psa_algorithm_t alg = alg_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004297 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
itayzafrir5c753392018-05-08 11:18:38 +03004298
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004299 TEST_ASSERT( signature_data->len <= PSA_SIGNATURE_MAX_SIZE );
Gilles Peskine69c12672018-06-28 00:07:19 +02004300
Gilles Peskine8817f612018-12-18 00:18:46 +01004301 PSA_ASSERT( psa_crypto_init( ) );
itayzafrir5c753392018-05-08 11:18:38 +03004302
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004303 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004304 psa_set_key_algorithm( &attributes, alg );
4305 psa_set_key_type( &attributes, key_type );
itayzafrir5c753392018-05-08 11:18:38 +03004306
Gilles Peskine049c7532019-05-15 20:22:09 +02004307 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4308 &handle ) );
itayzafrir5c753392018-05-08 11:18:38 +03004309
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004310 PSA_ASSERT( psa_verify_hash( handle, alg,
4311 hash_data->x, hash_data->len,
4312 signature_data->x, signature_data->len ) );
Gilles Peskine0627f982019-11-26 19:12:16 +01004313
4314#if defined(MBEDTLS_TEST_DEPRECATED)
4315 PSA_ASSERT( psa_asymmetric_verify( handle, alg,
4316 hash_data->x, hash_data->len,
4317 signature_data->x,
4318 signature_data->len ) );
4319
4320#endif /* MBEDTLS_TEST_DEPRECATED */
4321
itayzafrir5c753392018-05-08 11:18:38 +03004322exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004323 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004324 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004325 PSA_DONE( );
itayzafrir5c753392018-05-08 11:18:38 +03004326}
4327/* END_CASE */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004328
4329/* BEGIN_CASE */
itayzafrir3e02b3b2018-06-12 17:06:52 +03004330void asymmetric_verify_fail( int key_type_arg, data_t *key_data,
4331 int alg_arg, data_t *hash_data,
4332 data_t *signature_data,
4333 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004334{
Ronald Cron91e95152020-07-30 17:48:03 +02004335 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004336 psa_key_type_t key_type = key_type_arg;
4337 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004338 psa_status_t actual_status;
4339 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004340 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004341
Gilles Peskine8817f612018-12-18 00:18:46 +01004342 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004343
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004344 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004345 psa_set_key_algorithm( &attributes, alg );
4346 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004347
Gilles Peskine049c7532019-05-15 20:22:09 +02004348 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4349 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004350
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01004351 actual_status = psa_verify_hash( handle, alg,
4352 hash_data->x, hash_data->len,
4353 signature_data->x, signature_data->len );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004354 TEST_EQUAL( actual_status, expected_status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004355
Gilles Peskine895242b2019-11-29 12:15:40 +01004356#if defined(MBEDTLS_TEST_DEPRECATED)
4357 TEST_EQUAL( psa_asymmetric_verify( handle, alg,
4358 hash_data->x, hash_data->len,
4359 signature_data->x, signature_data->len ),
4360 expected_status );
4361#endif /* MBEDTLS_TEST_DEPRECATED */
4362
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004363exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004364 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004365 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004366 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004367}
4368/* END_CASE */
4369
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004370/* BEGIN_CASE */
Gilles Peskine656896e2018-06-29 19:12:28 +02004371void asymmetric_encrypt( int key_type_arg,
4372 data_t *key_data,
4373 int alg_arg,
4374 data_t *input_data,
Gilles Peskine68428122018-06-30 18:42:41 +02004375 data_t *label,
Gilles Peskine656896e2018-06-29 19:12:28 +02004376 int expected_output_length_arg,
4377 int expected_status_arg )
4378{
Ronald Cron91e95152020-07-30 17:48:03 +02004379 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02004380 psa_key_type_t key_type = key_type_arg;
4381 psa_algorithm_t alg = alg_arg;
4382 size_t expected_output_length = expected_output_length_arg;
4383 size_t key_bits;
4384 unsigned char *output = NULL;
4385 size_t output_size;
4386 size_t output_length = ~0;
4387 psa_status_t actual_status;
4388 psa_status_t expected_status = expected_status_arg;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004389 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine656896e2018-06-29 19:12:28 +02004390
Gilles Peskine8817f612018-12-18 00:18:46 +01004391 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004392
Gilles Peskine656896e2018-06-29 19:12:28 +02004393 /* Import the key */
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004394 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
4395 psa_set_key_algorithm( &attributes, alg );
4396 psa_set_key_type( &attributes, key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02004397 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4398 &handle ) );
Gilles Peskine656896e2018-06-29 19:12:28 +02004399
4400 /* Determine the maximum output length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004401 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4402 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine656896e2018-06-29 19:12:28 +02004403 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004404 ASSERT_ALLOC( output, output_size );
Gilles Peskine656896e2018-06-29 19:12:28 +02004405
4406 /* Encrypt the input */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004407 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine656896e2018-06-29 19:12:28 +02004408 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004409 label->x, label->len,
Gilles Peskine656896e2018-06-29 19:12:28 +02004410 output, output_size,
4411 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004412 TEST_EQUAL( actual_status, expected_status );
4413 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine656896e2018-06-29 19:12:28 +02004414
Gilles Peskine68428122018-06-30 18:42:41 +02004415 /* If the label is empty, the test framework puts a non-null pointer
4416 * in label->x. Test that a null pointer works as well. */
4417 if( label->len == 0 )
4418 {
4419 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004420 if( output_size != 0 )
4421 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004422 actual_status = psa_asymmetric_encrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004423 input_data->x, input_data->len,
4424 NULL, label->len,
4425 output, output_size,
4426 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004427 TEST_EQUAL( actual_status, expected_status );
4428 TEST_EQUAL( output_length, expected_output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004429 }
4430
Gilles Peskine656896e2018-06-29 19:12:28 +02004431exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004432 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004433 psa_destroy_key( handle );
Gilles Peskine656896e2018-06-29 19:12:28 +02004434 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004435 PSA_DONE( );
Gilles Peskine656896e2018-06-29 19:12:28 +02004436}
4437/* END_CASE */
4438
4439/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004440void asymmetric_encrypt_decrypt( int key_type_arg,
4441 data_t *key_data,
4442 int alg_arg,
4443 data_t *input_data,
4444 data_t *label )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004445{
Ronald Cron91e95152020-07-30 17:48:03 +02004446 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004447 psa_key_type_t key_type = key_type_arg;
4448 psa_algorithm_t alg = alg_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004449 size_t key_bits;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004450 unsigned char *output = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004451 size_t output_size;
4452 size_t output_length = ~0;
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03004453 unsigned char *output2 = NULL;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004454 size_t output2_size;
4455 size_t output2_length = ~0;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004456 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004457
Gilles Peskine8817f612018-12-18 00:18:46 +01004458 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004459
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004460 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
4461 psa_set_key_algorithm( &attributes, alg );
4462 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004463
Gilles Peskine049c7532019-05-15 20:22:09 +02004464 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4465 &handle ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004466
4467 /* Determine the maximum ciphertext length */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02004468 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
4469 key_bits = psa_get_key_bits( &attributes );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004470 output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004471 ASSERT_ALLOC( output, output_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004472 output2_size = input_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004473 ASSERT_ALLOC( output2, output2_size );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004474
Gilles Peskineeebd7382018-06-08 18:11:54 +02004475 /* We test encryption by checking that encrypt-then-decrypt gives back
4476 * the original plaintext because of the non-optional random
4477 * part of encryption process which prevents using fixed vectors. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004478 PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
4479 input_data->x, input_data->len,
4480 label->x, label->len,
4481 output, output_size,
4482 &output_length ) );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004483 /* We don't know what ciphertext length to expect, but check that
4484 * it looks sensible. */
4485 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein0f3bdbd2018-05-02 23:56:12 +03004486
Gilles Peskine8817f612018-12-18 00:18:46 +01004487 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4488 output, output_length,
4489 label->x, label->len,
4490 output2, output2_size,
4491 &output2_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004492 ASSERT_COMPARE( input_data->x, input_data->len,
4493 output2, output2_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004494
4495exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004496 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004497 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004498 mbedtls_free( output );
4499 mbedtls_free( output2 );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004500 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004501}
4502/* END_CASE */
4503
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004504/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004505void asymmetric_decrypt( int key_type_arg,
4506 data_t *key_data,
4507 int alg_arg,
4508 data_t *input_data,
4509 data_t *label,
Gilles Peskine66763a02018-06-29 21:54:10 +02004510 data_t *expected_data )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004511{
Ronald Cron91e95152020-07-30 17:48:03 +02004512 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004513 psa_key_type_t key_type = key_type_arg;
4514 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004515 unsigned char *output = NULL;
Nir Sonnenscheind70bc482018-06-04 16:31:13 +03004516 size_t output_size = 0;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004517 size_t output_length = ~0;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004518 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004519
Jaeden Amero412654a2019-02-06 12:57:46 +00004520 output_size = expected_data->len;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004521 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004522
Gilles Peskine8817f612018-12-18 00:18:46 +01004523 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004524
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004525 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4526 psa_set_key_algorithm( &attributes, alg );
4527 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004528
Gilles Peskine049c7532019-05-15 20:22:09 +02004529 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4530 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004531
Gilles Peskine8817f612018-12-18 00:18:46 +01004532 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4533 input_data->x, input_data->len,
4534 label->x, label->len,
4535 output,
4536 output_size,
4537 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004538 ASSERT_COMPARE( expected_data->x, expected_data->len,
4539 output, output_length );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004540
Gilles Peskine68428122018-06-30 18:42:41 +02004541 /* If the label is empty, the test framework puts a non-null pointer
4542 * in label->x. Test that a null pointer works as well. */
4543 if( label->len == 0 )
4544 {
4545 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004546 if( output_size != 0 )
4547 memset( output, 0, output_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004548 PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
4549 input_data->x, input_data->len,
4550 NULL, label->len,
4551 output,
4552 output_size,
4553 &output_length ) );
Gilles Peskinebd7dea92018-09-27 13:57:19 +02004554 ASSERT_COMPARE( expected_data->x, expected_data->len,
4555 output, output_length );
Gilles Peskine68428122018-06-30 18:42:41 +02004556 }
4557
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004558exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004559 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004560 psa_destroy_key( handle );
itayzafrir3e02b3b2018-06-12 17:06:52 +03004561 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004562 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004563}
4564/* END_CASE */
4565
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004566/* BEGIN_CASE */
Gilles Peskine68428122018-06-30 18:42:41 +02004567void asymmetric_decrypt_fail( int key_type_arg,
4568 data_t *key_data,
4569 int alg_arg,
4570 data_t *input_data,
4571 data_t *label,
Jaeden Amerof8daab72019-02-06 12:57:46 +00004572 int output_size_arg,
Gilles Peskine2d277862018-06-18 15:41:12 +02004573 int expected_status_arg )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004574{
Ronald Cron91e95152020-07-30 17:48:03 +02004575 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004576 psa_key_type_t key_type = key_type_arg;
4577 psa_algorithm_t alg = alg_arg;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004578 unsigned char *output = NULL;
Jaeden Amerof8daab72019-02-06 12:57:46 +00004579 size_t output_size = output_size_arg;
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004580 size_t output_length = ~0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004581 psa_status_t actual_status;
4582 psa_status_t expected_status = expected_status_arg;
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004583 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004584
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004585 ASSERT_ALLOC( output, output_size );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004586
Gilles Peskine8817f612018-12-18 00:18:46 +01004587 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004588
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004589 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
4590 psa_set_key_algorithm( &attributes, alg );
4591 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheind7082602018-06-04 16:45:27 +03004592
Gilles Peskine049c7532019-05-15 20:22:09 +02004593 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
4594 &handle ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004595
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004596 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004597 input_data->x, input_data->len,
Gilles Peskine68428122018-06-30 18:42:41 +02004598 label->x, label->len,
Gilles Peskine4abf7412018-06-18 16:35:34 +02004599 output, output_size,
Gilles Peskine2d277862018-06-18 15:41:12 +02004600 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004601 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004602 TEST_ASSERT( output_length <= output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004603
Gilles Peskine68428122018-06-30 18:42:41 +02004604 /* If the label is empty, the test framework puts a non-null pointer
4605 * in label->x. Test that a null pointer works as well. */
4606 if( label->len == 0 )
4607 {
4608 output_length = ~0;
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02004609 if( output_size != 0 )
4610 memset( output, 0, output_size );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004611 actual_status = psa_asymmetric_decrypt( handle, alg,
Gilles Peskine68428122018-06-30 18:42:41 +02004612 input_data->x, input_data->len,
4613 NULL, label->len,
4614 output, output_size,
4615 &output_length );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004616 TEST_EQUAL( actual_status, expected_status );
Gilles Peskine55c94dd2018-06-30 18:54:48 +02004617 TEST_ASSERT( output_length <= output_size );
Gilles Peskine68428122018-06-30 18:42:41 +02004618 }
4619
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004620exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02004621 psa_reset_key_attributes( &attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004622 psa_destroy_key( handle );
Gilles Peskine2d277862018-06-18 15:41:12 +02004623 mbedtls_free( output );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004624 PSA_DONE( );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03004625}
Gilles Peskine5b051bc2018-05-31 13:25:48 +02004626/* END_CASE */
Gilles Peskine05d69892018-06-19 22:00:52 +02004627
4628/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004629void key_derivation_init( )
Jaeden Amerod94d6712019-01-04 14:11:48 +00004630{
4631 /* Test each valid way of initializing the object, except for `= {0}`, as
4632 * Clang 5 complains when `-Wmissing-field-initializers` is used, even
4633 * though it's OK by the C standard. We could test for this, but we'd need
4634 * to supress the Clang warning for the test. */
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004635 size_t capacity;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004636 psa_key_derivation_operation_t func = psa_key_derivation_operation_init( );
4637 psa_key_derivation_operation_t init = PSA_KEY_DERIVATION_OPERATION_INIT;
4638 psa_key_derivation_operation_t zero;
Jaeden Amerod94d6712019-01-04 14:11:48 +00004639
4640 memset( &zero, 0, sizeof( zero ) );
4641
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004642 /* A default operation should not be able to report its capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004643 TEST_EQUAL( psa_key_derivation_get_capacity( &func, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004644 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004645 TEST_EQUAL( psa_key_derivation_get_capacity( &init, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004646 PSA_ERROR_BAD_STATE );
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004647 TEST_EQUAL( psa_key_derivation_get_capacity( &zero, &capacity ),
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004648 PSA_ERROR_BAD_STATE );
Jaeden Amero5229bbb2019-02-07 16:33:37 +00004649
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004650 /* A default operation should be abortable without error. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004651 PSA_ASSERT( psa_key_derivation_abort(&func) );
4652 PSA_ASSERT( psa_key_derivation_abort(&init) );
4653 PSA_ASSERT( psa_key_derivation_abort(&zero) );
Jaeden Amerod94d6712019-01-04 14:11:48 +00004654}
4655/* END_CASE */
4656
Janos Follath16de4a42019-06-13 16:32:24 +01004657/* BEGIN_CASE */
4658void derive_setup( int alg_arg, int expected_status_arg )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004659{
Gilles Peskineea0fb492018-07-12 17:17:20 +02004660 psa_algorithm_t alg = alg_arg;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004661 psa_status_t expected_status = expected_status_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004662 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004663
Gilles Peskine8817f612018-12-18 00:18:46 +01004664 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004665
Janos Follath16de4a42019-06-13 16:32:24 +01004666 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004667 expected_status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004668
4669exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004670 psa_key_derivation_abort( &operation );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004671 PSA_DONE( );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004672}
4673/* END_CASE */
4674
Janos Follathaf3c2a02019-06-12 12:34:34 +01004675/* BEGIN_CASE */
Janos Follatha27c9272019-06-14 09:59:36 +01004676void derive_set_capacity( int alg_arg, int capacity_arg,
4677 int expected_status_arg )
4678{
4679 psa_algorithm_t alg = alg_arg;
4680 size_t capacity = capacity_arg;
4681 psa_status_t expected_status = expected_status_arg;
4682 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4683
4684 PSA_ASSERT( psa_crypto_init( ) );
4685
4686 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4687
4688 TEST_EQUAL( psa_key_derivation_set_capacity( &operation, capacity ),
4689 expected_status );
4690
4691exit:
4692 psa_key_derivation_abort( &operation );
4693 PSA_DONE( );
4694}
4695/* END_CASE */
4696
4697/* BEGIN_CASE */
Janos Follathaf3c2a02019-06-12 12:34:34 +01004698void derive_input( int alg_arg,
Gilles Peskine6842ba42019-09-23 13:49:33 +02004699 int step_arg1, int key_type_arg1, data_t *input1,
Janos Follathaf3c2a02019-06-12 12:34:34 +01004700 int expected_status_arg1,
Gilles Peskine2058c072019-09-24 17:19:33 +02004701 int step_arg2, int key_type_arg2, data_t *input2,
Janos Follathaf3c2a02019-06-12 12:34:34 +01004702 int expected_status_arg2,
Gilles Peskine2058c072019-09-24 17:19:33 +02004703 int step_arg3, int key_type_arg3, data_t *input3,
Gilles Peskine1a2904c2019-09-24 17:45:07 +02004704 int expected_status_arg3,
4705 int output_key_type_arg, int expected_output_status_arg )
Janos Follathaf3c2a02019-06-12 12:34:34 +01004706{
4707 psa_algorithm_t alg = alg_arg;
Gilles Peskine6842ba42019-09-23 13:49:33 +02004708 psa_key_derivation_step_t steps[] = {step_arg1, step_arg2, step_arg3};
4709 psa_key_type_t key_types[] = {key_type_arg1, key_type_arg2, key_type_arg3};
Janos Follathaf3c2a02019-06-12 12:34:34 +01004710 psa_status_t expected_statuses[] = {expected_status_arg1,
4711 expected_status_arg2,
4712 expected_status_arg3};
4713 data_t *inputs[] = {input1, input2, input3};
Ronald Cron91e95152020-07-30 17:48:03 +02004714 psa_key_handle_t handles[] = { PSA_KEY_HANDLE_INIT,
4715 PSA_KEY_HANDLE_INIT,
4716 PSA_KEY_HANDLE_INIT};
Janos Follathaf3c2a02019-06-12 12:34:34 +01004717 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
4718 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
4719 size_t i;
Gilles Peskine1a2904c2019-09-24 17:45:07 +02004720 psa_key_type_t output_key_type = output_key_type_arg;
Ronald Cron91e95152020-07-30 17:48:03 +02004721 psa_key_handle_t output_handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine1a2904c2019-09-24 17:45:07 +02004722 psa_status_t expected_output_status = expected_output_status_arg;
4723 psa_status_t actual_output_status;
Janos Follathaf3c2a02019-06-12 12:34:34 +01004724
4725 PSA_ASSERT( psa_crypto_init( ) );
4726
4727 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4728 psa_set_key_algorithm( &attributes, alg );
Janos Follathaf3c2a02019-06-12 12:34:34 +01004729
4730 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4731
4732 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
4733 {
Gilles Peskineb8965192019-09-24 16:21:10 +02004734 if( key_types[i] != PSA_KEY_TYPE_NONE )
Janos Follathaf3c2a02019-06-12 12:34:34 +01004735 {
Gilles Peskine6842ba42019-09-23 13:49:33 +02004736 psa_set_key_type( &attributes, key_types[i] );
4737 PSA_ASSERT( psa_import_key( &attributes,
4738 inputs[i]->x, inputs[i]->len,
4739 &handles[i] ) );
Steven Cooreman0ee0d522020-10-05 16:03:42 +02004740 if( PSA_KEY_TYPE_IS_KEY_PAIR( key_types[i] ) &&
4741 steps[i] == PSA_KEY_DERIVATION_INPUT_SECRET )
4742 {
4743 // When taking a private key as secret input, use key agreement
4744 // to add the shared secret to the derivation
4745 TEST_EQUAL( key_agreement_with_self( &operation, handles[i] ),
4746 expected_statuses[i] );
4747 }
4748 else
4749 {
4750 TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
4751 handles[i] ),
4752 expected_statuses[i] );
4753 }
Gilles Peskine6842ba42019-09-23 13:49:33 +02004754 }
4755 else
4756 {
4757 TEST_EQUAL( psa_key_derivation_input_bytes(
4758 &operation, steps[i],
4759 inputs[i]->x, inputs[i]->len ),
4760 expected_statuses[i] );
Janos Follathaf3c2a02019-06-12 12:34:34 +01004761 }
4762 }
4763
Gilles Peskine1a2904c2019-09-24 17:45:07 +02004764 if( output_key_type != PSA_KEY_TYPE_NONE )
4765 {
4766 psa_reset_key_attributes( &attributes );
4767 psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
4768 psa_set_key_bits( &attributes, 8 );
4769 actual_output_status =
4770 psa_key_derivation_output_key( &attributes, &operation,
4771 &output_handle );
4772 }
4773 else
4774 {
4775 uint8_t buffer[1];
4776 actual_output_status =
4777 psa_key_derivation_output_bytes( &operation,
4778 buffer, sizeof( buffer ) );
4779 }
4780 TEST_EQUAL( actual_output_status, expected_output_status );
4781
Janos Follathaf3c2a02019-06-12 12:34:34 +01004782exit:
4783 psa_key_derivation_abort( &operation );
4784 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4785 psa_destroy_key( handles[i] );
Gilles Peskine1a2904c2019-09-24 17:45:07 +02004786 psa_destroy_key( output_handle );
Janos Follathaf3c2a02019-06-12 12:34:34 +01004787 PSA_DONE( );
4788}
4789/* END_CASE */
4790
Janos Follathd958bb72019-07-03 15:02:16 +01004791/* BEGIN_CASE */
4792void test_derive_invalid_key_derivation_state( int alg_arg )
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004793{
Janos Follathd958bb72019-07-03 15:02:16 +01004794 psa_algorithm_t alg = alg_arg;
Ronald Cron91e95152020-07-30 17:48:03 +02004795 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Nir Sonnenschein4eda37b2018-10-31 12:15:58 +02004796 size_t key_type = PSA_KEY_TYPE_DERIVE;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004797 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Janos Follathd958bb72019-07-03 15:02:16 +01004798 unsigned char input1[] = "Input 1";
4799 size_t input1_length = sizeof( input1 );
4800 unsigned char input2[] = "Input 2";
4801 size_t input2_length = sizeof( input2 );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004802 uint8_t buffer[42];
Nir Sonnenschein1caf6d22018-11-01 12:27:20 +02004803 size_t capacity = sizeof( buffer );
Nir Sonnenscheindd69d8b2018-11-01 12:24:23 +02004804 const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4805 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4806 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004807 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004808
Gilles Peskine8817f612018-12-18 00:18:46 +01004809 PSA_ASSERT( psa_crypto_init( ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004810
Gilles Peskine2c2cf0e2019-04-19 19:58:20 +02004811 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4812 psa_set_key_algorithm( &attributes, alg );
4813 psa_set_key_type( &attributes, key_type );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004814
Gilles Peskine73676cb2019-05-15 20:15:10 +02004815 PSA_ASSERT( psa_import_key( &attributes,
4816 key_data, sizeof( key_data ),
4817 &handle ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004818
4819 /* valid key derivation */
Janos Follathd958bb72019-07-03 15:02:16 +01004820 if( !setup_key_derivation_wrap( &operation, handle, alg,
4821 input1, input1_length,
4822 input2, input2_length,
4823 capacity ) )
4824 goto exit;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004825
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004826 /* state of operation shouldn't allow additional generation */
Janos Follathd958bb72019-07-03 15:02:16 +01004827 TEST_EQUAL( psa_key_derivation_setup( &operation, alg ),
Gilles Peskinef812dcf2018-12-18 00:33:25 +01004828 PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004829
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004830 PSA_ASSERT( psa_key_derivation_output_bytes( &operation, buffer, capacity ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004831
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004832 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, buffer, capacity ),
David Saadab4ecc272019-02-14 13:48:10 +02004833 PSA_ERROR_INSUFFICIENT_DATA );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004834
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004835exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004836 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01004837 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004838 PSA_DONE( );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004839}
4840/* END_CASE */
4841
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004842/* BEGIN_CASE */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004843void test_derive_invalid_key_derivation_tests( )
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004844{
4845 uint8_t output_buffer[16];
4846 size_t buffer_size = 16;
4847 size_t capacity = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004848 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004849
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004850 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4851 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004852 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004853
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004854 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004855 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004856
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004857 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004858
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004859 TEST_ASSERT( psa_key_derivation_output_bytes( &operation,
4860 output_buffer, buffer_size )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004861 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004862
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004863 TEST_ASSERT( psa_key_derivation_get_capacity( &operation, &capacity )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004864 == PSA_ERROR_BAD_STATE );
Nir Sonnenscheinb46e7ca2018-10-25 14:46:09 +03004865
4866exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004867 psa_key_derivation_abort( &operation );
Nir Sonnenscheine5204c92018-10-22 17:24:55 +03004868}
4869/* END_CASE */
4870
4871/* BEGIN_CASE */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004872void derive_output( int alg_arg,
Gilles Peskine1468da72019-05-29 17:35:49 +02004873 int step1_arg, data_t *input1,
4874 int step2_arg, data_t *input2,
4875 int step3_arg, data_t *input3,
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004876 int requested_capacity_arg,
4877 data_t *expected_output1,
4878 data_t *expected_output2 )
4879{
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004880 psa_algorithm_t alg = alg_arg;
Gilles Peskine1468da72019-05-29 17:35:49 +02004881 psa_key_derivation_step_t steps[] = {step1_arg, step2_arg, step3_arg};
4882 data_t *inputs[] = {input1, input2, input3};
Ronald Cron91e95152020-07-30 17:48:03 +02004883 psa_key_handle_t handles[] = { PSA_KEY_HANDLE_INIT,
4884 PSA_KEY_HANDLE_INIT,
4885 PSA_KEY_HANDLE_INIT};
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004886 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004887 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004888 uint8_t *expected_outputs[2] =
4889 {expected_output1->x, expected_output2->x};
4890 size_t output_sizes[2] =
4891 {expected_output1->len, expected_output2->len};
4892 size_t output_buffer_size = 0;
4893 uint8_t *output_buffer = NULL;
4894 size_t expected_capacity;
4895 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004896 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004897 psa_status_t status;
Gilles Peskine1468da72019-05-29 17:35:49 +02004898 size_t i;
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004899
4900 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4901 {
4902 if( output_sizes[i] > output_buffer_size )
4903 output_buffer_size = output_sizes[i];
4904 if( output_sizes[i] == 0 )
4905 expected_outputs[i] = NULL;
4906 }
Gilles Peskine8cebbba2018-09-27 13:54:18 +02004907 ASSERT_ALLOC( output_buffer, output_buffer_size );
Gilles Peskine8817f612018-12-18 00:18:46 +01004908 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004909
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004910 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
4911 psa_set_key_algorithm( &attributes, alg );
4912 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004913
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004914 /* Extraction phase. */
Gilles Peskine1468da72019-05-29 17:35:49 +02004915 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
4916 PSA_ASSERT( psa_key_derivation_set_capacity( &operation,
4917 requested_capacity ) );
4918 for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004919 {
Gilles Peskine1468da72019-05-29 17:35:49 +02004920 switch( steps[i] )
4921 {
4922 case 0:
4923 break;
4924 case PSA_KEY_DERIVATION_INPUT_SECRET:
4925 PSA_ASSERT( psa_import_key( &attributes,
4926 inputs[i]->x, inputs[i]->len,
4927 &handles[i] ) );
4928 PSA_ASSERT( psa_key_derivation_input_key(
4929 &operation, steps[i],
4930 handles[i] ) );
4931 break;
4932 default:
4933 PSA_ASSERT( psa_key_derivation_input_bytes(
4934 &operation, steps[i],
4935 inputs[i]->x, inputs[i]->len ) );
4936 break;
4937 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004938 }
Gilles Peskine1468da72019-05-29 17:35:49 +02004939
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004940 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004941 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004942 TEST_EQUAL( current_capacity, requested_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004943 expected_capacity = requested_capacity;
4944
4945 /* Expansion phase. */
4946 for( i = 0; i < ARRAY_LENGTH( expected_outputs ); i++ )
4947 {
4948 /* Read some bytes. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004949 status = psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004950 output_buffer, output_sizes[i] );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004951 if( expected_capacity == 0 && output_sizes[i] == 0 )
4952 {
4953 /* Reading 0 bytes when 0 bytes are available can go either way. */
4954 TEST_ASSERT( status == PSA_SUCCESS ||
David Saadab4ecc272019-02-14 13:48:10 +02004955 status == PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004956 continue;
4957 }
4958 else if( expected_capacity == 0 ||
4959 output_sizes[i] > expected_capacity )
4960 {
4961 /* Capacity exceeded. */
David Saadab4ecc272019-02-14 13:48:10 +02004962 TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004963 expected_capacity = 0;
4964 continue;
4965 }
4966 /* Success. Check the read data. */
Gilles Peskine8817f612018-12-18 00:18:46 +01004967 PSA_ASSERT( status );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004968 if( output_sizes[i] != 0 )
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01004969 ASSERT_COMPARE( output_buffer, output_sizes[i],
4970 expected_outputs[i], output_sizes[i] );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004971 /* Check the operation status. */
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004972 expected_capacity -= output_sizes[i];
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004973 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02004974 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01004975 TEST_EQUAL( expected_capacity, current_capacity );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004976 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004977 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004978
4979exit:
4980 mbedtls_free( output_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004981 psa_key_derivation_abort( &operation );
Gilles Peskine1468da72019-05-29 17:35:49 +02004982 for( i = 0; i < ARRAY_LENGTH( handles ); i++ )
4983 psa_destroy_key( handles[i] );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02004984 PSA_DONE( );
Gilles Peskine96ee5c72018-07-12 17:24:54 +02004985}
4986/* END_CASE */
4987
4988/* BEGIN_CASE */
Gilles Peskined54931c2018-07-17 21:06:59 +02004989void derive_full( int alg_arg,
4990 data_t *key_data,
Janos Follath47f27ed2019-06-25 13:24:52 +01004991 data_t *input1,
4992 data_t *input2,
Gilles Peskined54931c2018-07-17 21:06:59 +02004993 int requested_capacity_arg )
4994{
Ronald Cron91e95152020-07-30 17:48:03 +02004995 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004996 psa_algorithm_t alg = alg_arg;
4997 size_t requested_capacity = requested_capacity_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004998 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02004999 unsigned char output_buffer[16];
5000 size_t expected_capacity = requested_capacity;
5001 size_t current_capacity;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005002 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskined54931c2018-07-17 21:06:59 +02005003
Gilles Peskine8817f612018-12-18 00:18:46 +01005004 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02005005
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005006 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
5007 psa_set_key_algorithm( &attributes, alg );
5008 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskined54931c2018-07-17 21:06:59 +02005009
Gilles Peskine049c7532019-05-15 20:22:09 +02005010 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
5011 &handle ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02005012
Janos Follathf2815ea2019-07-03 12:41:36 +01005013 if( !setup_key_derivation_wrap( &operation, handle, alg,
5014 input1->x, input1->len,
5015 input2->x, input2->len,
5016 requested_capacity ) )
5017 goto exit;
Janos Follath47f27ed2019-06-25 13:24:52 +01005018
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005019 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005020 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01005021 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02005022
5023 /* Expansion phase. */
5024 while( current_capacity > 0 )
5025 {
5026 size_t read_size = sizeof( output_buffer );
5027 if( read_size > current_capacity )
5028 read_size = current_capacity;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005029 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005030 output_buffer,
5031 read_size ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02005032 expected_capacity -= read_size;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005033 PSA_ASSERT( psa_key_derivation_get_capacity( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005034 &current_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01005035 TEST_EQUAL( current_capacity, expected_capacity );
Gilles Peskined54931c2018-07-17 21:06:59 +02005036 }
5037
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005038 /* Check that the operation refuses to go over capacity. */
5039 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output_buffer, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02005040 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskined54931c2018-07-17 21:06:59 +02005041
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005042 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskined54931c2018-07-17 21:06:59 +02005043
5044exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005045 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005046 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005047 PSA_DONE( );
Gilles Peskined54931c2018-07-17 21:06:59 +02005048}
5049/* END_CASE */
5050
Janos Follathe60c9052019-07-03 13:51:30 +01005051/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02005052void derive_key_exercise( int alg_arg,
5053 data_t *key_data,
Janos Follathe60c9052019-07-03 13:51:30 +01005054 data_t *input1,
5055 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02005056 int derived_type_arg,
5057 int derived_bits_arg,
5058 int derived_usage_arg,
5059 int derived_alg_arg )
5060{
Ronald Cron91e95152020-07-30 17:48:03 +02005061 psa_key_handle_t base_handle = PSA_KEY_HANDLE_INIT;
5062 psa_key_handle_t derived_handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02005063 psa_algorithm_t alg = alg_arg;
5064 psa_key_type_t derived_type = derived_type_arg;
5065 size_t derived_bits = derived_bits_arg;
5066 psa_key_usage_t derived_usage = derived_usage_arg;
5067 psa_algorithm_t derived_alg = derived_alg_arg;
5068 size_t capacity = PSA_BITS_TO_BYTES( derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005069 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005070 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005071 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02005072
Gilles Peskine8817f612018-12-18 00:18:46 +01005073 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005074
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005075 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
5076 psa_set_key_algorithm( &attributes, alg );
5077 psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005078 PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
5079 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005080
5081 /* Derive a key. */
Janos Follathe60c9052019-07-03 13:51:30 +01005082 if ( setup_key_derivation_wrap( &operation, base_handle, alg,
5083 input1->x, input1->len,
5084 input2->x, input2->len, capacity ) )
5085 goto exit;
5086
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005087 psa_set_key_usage_flags( &attributes, derived_usage );
5088 psa_set_key_algorithm( &attributes, derived_alg );
5089 psa_set_key_type( &attributes, derived_type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005090 psa_set_key_bits( &attributes, derived_bits );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005091 PSA_ASSERT( psa_key_derivation_output_key( &attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005092 &derived_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005093
5094 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005095 PSA_ASSERT( psa_get_key_attributes( derived_handle, &got_attributes ) );
5096 TEST_EQUAL( psa_get_key_type( &got_attributes ), derived_type );
5097 TEST_EQUAL( psa_get_key_bits( &got_attributes ), derived_bits );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005098
5099 /* Exercise the derived key. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005100 if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
Gilles Peskine0386fba2018-07-12 17:29:22 +02005101 goto exit;
5102
5103exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005104 psa_key_derivation_abort( &operation );
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005105 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005106 psa_destroy_key( base_handle );
5107 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005108 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005109}
5110/* END_CASE */
5111
Janos Follath42fd8882019-07-03 14:17:09 +01005112/* BEGIN_CASE */
Gilles Peskine0386fba2018-07-12 17:29:22 +02005113void derive_key_export( int alg_arg,
5114 data_t *key_data,
Janos Follath42fd8882019-07-03 14:17:09 +01005115 data_t *input1,
5116 data_t *input2,
Gilles Peskine0386fba2018-07-12 17:29:22 +02005117 int bytes1_arg,
5118 int bytes2_arg )
5119{
Ronald Cron91e95152020-07-30 17:48:03 +02005120 psa_key_handle_t base_handle = PSA_KEY_HANDLE_INIT;
5121 psa_key_handle_t derived_handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02005122 psa_algorithm_t alg = alg_arg;
5123 size_t bytes1 = bytes1_arg;
5124 size_t bytes2 = bytes2_arg;
5125 size_t capacity = bytes1 + bytes2;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005126 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine8cebbba2018-09-27 13:54:18 +02005127 uint8_t *output_buffer = NULL;
5128 uint8_t *export_buffer = NULL;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005129 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5130 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine0386fba2018-07-12 17:29:22 +02005131 size_t length;
5132
Gilles Peskine8cebbba2018-09-27 13:54:18 +02005133 ASSERT_ALLOC( output_buffer, capacity );
5134 ASSERT_ALLOC( export_buffer, capacity );
Gilles Peskine8817f612018-12-18 00:18:46 +01005135 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005136
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005137 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
5138 psa_set_key_algorithm( &base_attributes, alg );
5139 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005140 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
5141 &base_handle ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005142
5143 /* Derive some material and output it. */
Janos Follath42fd8882019-07-03 14:17:09 +01005144 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
5145 input1->x, input1->len,
5146 input2->x, input2->len, capacity ) )
5147 goto exit;
5148
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005149 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005150 output_buffer,
5151 capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005152 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005153
5154 /* Derive the same output again, but this time store it in key objects. */
Janos Follath42fd8882019-07-03 14:17:09 +01005155 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
5156 input1->x, input1->len,
5157 input2->x, input2->len, capacity ) )
5158 goto exit;
5159
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005160 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
5161 psa_set_key_algorithm( &derived_attributes, 0 );
5162 psa_set_key_type( &derived_attributes, PSA_KEY_TYPE_RAW_DATA );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005163 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes1 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005164 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005165 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01005166 PSA_ASSERT( psa_export_key( derived_handle,
5167 export_buffer, bytes1,
5168 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01005169 TEST_EQUAL( length, bytes1 );
Gilles Peskine8817f612018-12-18 00:18:46 +01005170 PSA_ASSERT( psa_destroy_key( derived_handle ) );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005171 psa_set_key_bits( &derived_attributes, PSA_BYTES_TO_BITS( bytes2 ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005172 PSA_ASSERT( psa_key_derivation_output_key( &derived_attributes, &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005173 &derived_handle ) );
Gilles Peskine8817f612018-12-18 00:18:46 +01005174 PSA_ASSERT( psa_export_key( derived_handle,
5175 export_buffer + bytes1, bytes2,
5176 &length ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01005177 TEST_EQUAL( length, bytes2 );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005178
5179 /* Compare the outputs from the two runs. */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01005180 ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
5181 export_buffer, capacity );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005182
5183exit:
5184 mbedtls_free( output_buffer );
5185 mbedtls_free( export_buffer );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005186 psa_key_derivation_abort( &operation );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005187 psa_destroy_key( base_handle );
5188 psa_destroy_key( derived_handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005189 PSA_DONE( );
Gilles Peskine0386fba2018-07-12 17:29:22 +02005190}
5191/* END_CASE */
5192
5193/* BEGIN_CASE */
Gilles Peskine7c227ae2019-07-31 15:14:44 +02005194void derive_key( int alg_arg,
5195 data_t *key_data, data_t *input1, data_t *input2,
5196 int type_arg, int bits_arg,
5197 int expected_status_arg )
Gilles Peskinec744d992019-07-30 17:26:54 +02005198{
Ronald Cron91e95152020-07-30 17:48:03 +02005199 psa_key_handle_t base_handle = PSA_KEY_HANDLE_INIT;
5200 psa_key_handle_t derived_handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinec744d992019-07-30 17:26:54 +02005201 psa_algorithm_t alg = alg_arg;
Gilles Peskine7c227ae2019-07-31 15:14:44 +02005202 psa_key_type_t type = type_arg;
Gilles Peskinec744d992019-07-30 17:26:54 +02005203 size_t bits = bits_arg;
5204 psa_status_t expected_status = expected_status_arg;
5205 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
5206 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5207 psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT;
5208
5209 PSA_ASSERT( psa_crypto_init( ) );
5210
5211 psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE );
5212 psa_set_key_algorithm( &base_attributes, alg );
5213 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
5214 PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len,
5215 &base_handle ) );
5216
5217 if( !setup_key_derivation_wrap( &operation, base_handle, alg,
5218 input1->x, input1->len,
5219 input2->x, input2->len, SIZE_MAX ) )
5220 goto exit;
5221
5222 psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT );
5223 psa_set_key_algorithm( &derived_attributes, 0 );
Gilles Peskine7c227ae2019-07-31 15:14:44 +02005224 psa_set_key_type( &derived_attributes, type );
Gilles Peskinec744d992019-07-30 17:26:54 +02005225 psa_set_key_bits( &derived_attributes, bits );
5226 TEST_EQUAL( psa_key_derivation_output_key( &derived_attributes, &operation,
5227 &derived_handle ),
5228 expected_status );
5229
5230exit:
5231 psa_key_derivation_abort( &operation );
5232 psa_destroy_key( base_handle );
5233 psa_destroy_key( derived_handle );
5234 PSA_DONE( );
5235}
5236/* END_CASE */
5237
5238/* BEGIN_CASE */
Gilles Peskine01d718c2018-09-18 12:01:02 +02005239void key_agreement_setup( int alg_arg,
Steven Cooremance48e852020-10-05 16:02:45 +02005240 int our_key_type_arg, int our_key_alg_arg,
5241 data_t *our_key_data, data_t *peer_key_data,
Gilles Peskine01d718c2018-09-18 12:01:02 +02005242 int expected_status_arg )
5243{
Ronald Cron91e95152020-07-30 17:48:03 +02005244 psa_key_handle_t our_key = PSA_KEY_HANDLE_INIT;
Gilles Peskine01d718c2018-09-18 12:01:02 +02005245 psa_algorithm_t alg = alg_arg;
Steven Cooremanfa5e6312020-10-15 17:07:12 +02005246 psa_algorithm_t our_key_alg = our_key_alg_arg;
Gilles Peskine01d718c2018-09-18 12:01:02 +02005247 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005248 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005249 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine77f40d82019-04-11 21:27:06 +02005250 psa_status_t expected_status = expected_status_arg;
5251 psa_status_t status;
Gilles Peskine01d718c2018-09-18 12:01:02 +02005252
Gilles Peskine8817f612018-12-18 00:18:46 +01005253 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02005254
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005255 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
Steven Cooremanfa5e6312020-10-15 17:07:12 +02005256 psa_set_key_algorithm( &attributes, our_key_alg );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005257 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02005258 PSA_ASSERT( psa_import_key( &attributes,
5259 our_key_data->x, our_key_data->len,
5260 &our_key ) );
Gilles Peskine01d718c2018-09-18 12:01:02 +02005261
Gilles Peskine77f40d82019-04-11 21:27:06 +02005262 /* The tests currently include inputs that should fail at either step.
5263 * Test cases that fail at the setup step should be changed to call
5264 * key_derivation_setup instead, and this function should be renamed
5265 * to key_agreement_fail. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005266 status = psa_key_derivation_setup( &operation, alg );
Gilles Peskine77f40d82019-04-11 21:27:06 +02005267 if( status == PSA_SUCCESS )
5268 {
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005269 TEST_EQUAL( psa_key_derivation_key_agreement(
5270 &operation, PSA_KEY_DERIVATION_INPUT_SECRET,
5271 our_key,
5272 peer_key_data->x, peer_key_data->len ),
Gilles Peskine77f40d82019-04-11 21:27:06 +02005273 expected_status );
5274 }
5275 else
5276 {
5277 TEST_ASSERT( status == expected_status );
5278 }
Gilles Peskine01d718c2018-09-18 12:01:02 +02005279
5280exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005281 psa_key_derivation_abort( &operation );
Gilles Peskine01d718c2018-09-18 12:01:02 +02005282 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005283 PSA_DONE( );
Gilles Peskine01d718c2018-09-18 12:01:02 +02005284}
5285/* END_CASE */
5286
5287/* BEGIN_CASE */
Gilles Peskinef0cba732019-04-11 22:12:38 +02005288void raw_key_agreement( int alg_arg,
5289 int our_key_type_arg, data_t *our_key_data,
5290 data_t *peer_key_data,
5291 data_t *expected_output )
5292{
Ronald Cron91e95152020-07-30 17:48:03 +02005293 psa_key_handle_t our_key = PSA_KEY_HANDLE_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02005294 psa_algorithm_t alg = alg_arg;
5295 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005296 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinef0cba732019-04-11 22:12:38 +02005297 unsigned char *output = NULL;
5298 size_t output_length = ~0;
5299
5300 ASSERT_ALLOC( output, expected_output->len );
5301 PSA_ASSERT( psa_crypto_init( ) );
5302
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005303 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
5304 psa_set_key_algorithm( &attributes, alg );
5305 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02005306 PSA_ASSERT( psa_import_key( &attributes,
5307 our_key_data->x, our_key_data->len,
5308 &our_key ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02005309
Gilles Peskinebe697d82019-05-16 18:00:41 +02005310 PSA_ASSERT( psa_raw_key_agreement( alg, our_key,
5311 peer_key_data->x, peer_key_data->len,
5312 output, expected_output->len,
5313 &output_length ) );
Gilles Peskinef0cba732019-04-11 22:12:38 +02005314 ASSERT_COMPARE( output, output_length,
5315 expected_output->x, expected_output->len );
5316
5317exit:
5318 mbedtls_free( output );
5319 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005320 PSA_DONE( );
Gilles Peskinef0cba732019-04-11 22:12:38 +02005321}
5322/* END_CASE */
5323
5324/* BEGIN_CASE */
Gilles Peskine59685592018-09-18 12:11:34 +02005325void key_agreement_capacity( int alg_arg,
5326 int our_key_type_arg, data_t *our_key_data,
5327 data_t *peer_key_data,
5328 int expected_capacity_arg )
5329{
Ronald Cron91e95152020-07-30 17:48:03 +02005330 psa_key_handle_t our_key = PSA_KEY_HANDLE_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02005331 psa_algorithm_t alg = alg_arg;
5332 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005333 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005334 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02005335 size_t actual_capacity;
Gilles Peskinebf491972018-10-25 22:36:12 +02005336 unsigned char output[16];
Gilles Peskine59685592018-09-18 12:11:34 +02005337
Gilles Peskine8817f612018-12-18 00:18:46 +01005338 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02005339
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005340 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
5341 psa_set_key_algorithm( &attributes, alg );
5342 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02005343 PSA_ASSERT( psa_import_key( &attributes,
5344 our_key_data->x, our_key_data->len,
5345 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02005346
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005347 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005348 PSA_ASSERT( psa_key_derivation_key_agreement(
5349 &operation,
5350 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
5351 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02005352 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
5353 {
5354 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005355 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02005356 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02005357 NULL, 0 ) );
5358 }
Gilles Peskine59685592018-09-18 12:11:34 +02005359
Gilles Peskinebf491972018-10-25 22:36:12 +02005360 /* Test the advertized capacity. */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005361 PSA_ASSERT( psa_key_derivation_get_capacity(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005362 &operation, &actual_capacity ) );
Gilles Peskinefe11b722018-12-18 00:24:04 +01005363 TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
Gilles Peskine59685592018-09-18 12:11:34 +02005364
Gilles Peskinebf491972018-10-25 22:36:12 +02005365 /* Test the actual capacity by reading the output. */
5366 while( actual_capacity > sizeof( output ) )
5367 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005368 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005369 output, sizeof( output ) ) );
Gilles Peskinebf491972018-10-25 22:36:12 +02005370 actual_capacity -= sizeof( output );
5371 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005372 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005373 output, actual_capacity ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005374 TEST_EQUAL( psa_key_derivation_output_bytes( &operation, output, 1 ),
David Saadab4ecc272019-02-14 13:48:10 +02005375 PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskinebf491972018-10-25 22:36:12 +02005376
Gilles Peskine59685592018-09-18 12:11:34 +02005377exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005378 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02005379 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005380 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02005381}
5382/* END_CASE */
5383
5384/* BEGIN_CASE */
5385void key_agreement_output( int alg_arg,
5386 int our_key_type_arg, data_t *our_key_data,
5387 data_t *peer_key_data,
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02005388 data_t *expected_output1, data_t *expected_output2 )
Gilles Peskine59685592018-09-18 12:11:34 +02005389{
Ronald Cron91e95152020-07-30 17:48:03 +02005390 psa_key_handle_t our_key = PSA_KEY_HANDLE_INIT;
Gilles Peskine59685592018-09-18 12:11:34 +02005391 psa_algorithm_t alg = alg_arg;
5392 psa_key_type_t our_key_type = our_key_type_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005393 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005394 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02005395 uint8_t *actual_output = NULL;
Gilles Peskine59685592018-09-18 12:11:34 +02005396
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02005397 ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
5398 expected_output2->len ) );
Gilles Peskine59685592018-09-18 12:11:34 +02005399
Gilles Peskine8817f612018-12-18 00:18:46 +01005400 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine59685592018-09-18 12:11:34 +02005401
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005402 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
5403 psa_set_key_algorithm( &attributes, alg );
5404 psa_set_key_type( &attributes, our_key_type );
Gilles Peskine049c7532019-05-15 20:22:09 +02005405 PSA_ASSERT( psa_import_key( &attributes,
5406 our_key_data->x, our_key_data->len,
5407 &our_key ) );
Gilles Peskine59685592018-09-18 12:11:34 +02005408
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005409 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005410 PSA_ASSERT( psa_key_derivation_key_agreement(
5411 &operation,
5412 PSA_KEY_DERIVATION_INPUT_SECRET, our_key,
5413 peer_key_data->x, peer_key_data->len ) );
Gilles Peskinef8a9d942019-04-11 22:13:20 +02005414 if( PSA_ALG_IS_HKDF( PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ) ) )
5415 {
5416 /* The test data is for info="" */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005417 PSA_ASSERT( psa_key_derivation_input_bytes( &operation,
Gilles Peskine03410b52019-05-16 16:05:19 +02005418 PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskinef8a9d942019-04-11 22:13:20 +02005419 NULL, 0 ) );
5420 }
Gilles Peskine59685592018-09-18 12:11:34 +02005421
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005422 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005423 actual_output,
5424 expected_output1->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01005425 ASSERT_COMPARE( actual_output, expected_output1->len,
5426 expected_output1->x, expected_output1->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02005427 if( expected_output2->len != 0 )
5428 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005429 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005430 actual_output,
5431 expected_output2->len ) );
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01005432 ASSERT_COMPARE( actual_output, expected_output2->len,
5433 expected_output2->x, expected_output2->len );
Gilles Peskine3ec8ed82018-10-25 22:37:15 +02005434 }
Gilles Peskine59685592018-09-18 12:11:34 +02005435
5436exit:
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005437 psa_key_derivation_abort( &operation );
Gilles Peskine59685592018-09-18 12:11:34 +02005438 psa_destroy_key( our_key );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005439 PSA_DONE( );
Gilles Peskine59685592018-09-18 12:11:34 +02005440 mbedtls_free( actual_output );
5441}
5442/* END_CASE */
5443
5444/* BEGIN_CASE */
Gilles Peskinea50d7392018-06-21 10:22:13 +02005445void generate_random( int bytes_arg )
Gilles Peskine05d69892018-06-19 22:00:52 +02005446{
Gilles Peskinea50d7392018-06-21 10:22:13 +02005447 size_t bytes = bytes_arg;
5448 const unsigned char trail[] = "don't overwrite me";
Gilles Peskine8cebbba2018-09-27 13:54:18 +02005449 unsigned char *output = NULL;
5450 unsigned char *changed = NULL;
Gilles Peskinea50d7392018-06-21 10:22:13 +02005451 size_t i;
5452 unsigned run;
Gilles Peskine05d69892018-06-19 22:00:52 +02005453
Simon Butcher49f8e312020-03-03 15:51:50 +00005454 TEST_ASSERT( bytes_arg >= 0 );
5455
Gilles Peskine8cebbba2018-09-27 13:54:18 +02005456 ASSERT_ALLOC( output, bytes + sizeof( trail ) );
5457 ASSERT_ALLOC( changed, bytes );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005458 memcpy( output + bytes, trail, sizeof( trail ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02005459
Gilles Peskine8817f612018-12-18 00:18:46 +01005460 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine05d69892018-06-19 22:00:52 +02005461
Gilles Peskinea50d7392018-06-21 10:22:13 +02005462 /* Run several times, to ensure that every output byte will be
5463 * nonzero at least once with overwhelming probability
5464 * (2^(-8*number_of_runs)). */
5465 for( run = 0; run < 10; run++ )
Gilles Peskine05d69892018-06-19 22:00:52 +02005466 {
Gilles Peskinef7ab5ad2018-09-26 18:19:24 +02005467 if( bytes != 0 )
5468 memset( output, 0, bytes );
Gilles Peskine8817f612018-12-18 00:18:46 +01005469 PSA_ASSERT( psa_generate_random( output, bytes ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005470
5471 /* Check that no more than bytes have been overwritten */
Gilles Peskine0dfba2d2018-12-18 00:40:50 +01005472 ASSERT_COMPARE( output + bytes, sizeof( trail ),
5473 trail, sizeof( trail ) );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005474
5475 for( i = 0; i < bytes; i++ )
5476 {
5477 if( output[i] != 0 )
5478 ++changed[i];
5479 }
Gilles Peskine05d69892018-06-19 22:00:52 +02005480 }
Gilles Peskinea50d7392018-06-21 10:22:13 +02005481
5482 /* Check that every byte was changed to nonzero at least once. This
5483 * validates that psa_generate_random is overwriting every byte of
5484 * the output buffer. */
5485 for( i = 0; i < bytes; i++ )
5486 {
5487 TEST_ASSERT( changed[i] != 0 );
5488 }
Gilles Peskine05d69892018-06-19 22:00:52 +02005489
5490exit:
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005491 PSA_DONE( );
Gilles Peskinea50d7392018-06-21 10:22:13 +02005492 mbedtls_free( output );
5493 mbedtls_free( changed );
Gilles Peskine05d69892018-06-19 22:00:52 +02005494}
5495/* END_CASE */
Gilles Peskine12313cd2018-06-20 00:20:32 +02005496
5497/* BEGIN_CASE */
5498void generate_key( int type_arg,
5499 int bits_arg,
5500 int usage_arg,
5501 int alg_arg,
5502 int expected_status_arg )
5503{
Ronald Cron91e95152020-07-30 17:48:03 +02005504 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005505 psa_key_type_t type = type_arg;
5506 psa_key_usage_t usage = usage_arg;
5507 size_t bits = bits_arg;
5508 psa_algorithm_t alg = alg_arg;
5509 psa_status_t expected_status = expected_status_arg;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005510 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005511 psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005512
Gilles Peskine8817f612018-12-18 00:18:46 +01005513 PSA_ASSERT( psa_crypto_init( ) );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005514
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005515 psa_set_key_usage_flags( &attributes, usage );
5516 psa_set_key_algorithm( &attributes, alg );
5517 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005518 psa_set_key_bits( &attributes, bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005519
5520 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005521 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005522 if( expected_status != PSA_SUCCESS )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005523 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005524
5525 /* Test the key information */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02005526 PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
5527 TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
5528 TEST_EQUAL( psa_get_key_bits( &got_attributes ), bits );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005529
Gilles Peskine818ca122018-06-20 18:16:48 +02005530 /* Do something with the key according to its type and permitted usage. */
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005531 if( ! exercise_key( handle, usage, alg ) )
Gilles Peskine02b75072018-07-01 22:31:34 +02005532 goto exit;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005533
5534exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005535 psa_reset_key_attributes( &got_attributes );
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005536 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005537 PSA_DONE( );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005538}
5539/* END_CASE */
itayzafrir0adf0fc2018-09-06 16:24:41 +03005540
Gilles Peskinee56e8782019-04-26 17:34:02 +02005541/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V15 */
5542void generate_key_rsa( int bits_arg,
5543 data_t *e_arg,
5544 int expected_status_arg )
5545{
Ronald Cron91e95152020-07-30 17:48:03 +02005546 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
Gilles Peskinec93b80c2019-05-16 19:39:54 +02005547 psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
Gilles Peskinee56e8782019-04-26 17:34:02 +02005548 size_t bits = bits_arg;
5549 psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
5550 psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW;
5551 psa_status_t expected_status = expected_status_arg;
5552 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5553 uint8_t *exported = NULL;
5554 size_t exported_size =
5555 PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
5556 size_t exported_length = SIZE_MAX;
5557 uint8_t *e_read_buffer = NULL;
5558 int is_default_public_exponent = 0;
Gilles Peskineaa02c172019-04-28 11:44:17 +02005559 size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE( type, bits );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005560 size_t e_read_length = SIZE_MAX;
5561
5562 if( e_arg->len == 0 ||
5563 ( e_arg->len == 3 &&
5564 e_arg->x[0] == 1 && e_arg->x[1] == 0 && e_arg->x[2] == 1 ) )
5565 {
5566 is_default_public_exponent = 1;
5567 e_read_size = 0;
5568 }
5569 ASSERT_ALLOC( e_read_buffer, e_read_size );
5570 ASSERT_ALLOC( exported, exported_size );
5571
5572 PSA_ASSERT( psa_crypto_init( ) );
5573
5574 psa_set_key_usage_flags( &attributes, usage );
5575 psa_set_key_algorithm( &attributes, alg );
5576 PSA_ASSERT( psa_set_key_domain_parameters( &attributes, type,
5577 e_arg->x, e_arg->len ) );
5578 psa_set_key_bits( &attributes, bits );
5579
5580 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005581 TEST_EQUAL( psa_generate_key( &attributes, &handle ), expected_status );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005582 if( expected_status != PSA_SUCCESS )
5583 goto exit;
5584
5585 /* Test the key information */
5586 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
5587 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5588 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5589 PSA_ASSERT( psa_get_key_domain_parameters( &attributes,
5590 e_read_buffer, e_read_size,
5591 &e_read_length ) );
5592 if( is_default_public_exponent )
5593 TEST_EQUAL( e_read_length, 0 );
5594 else
5595 ASSERT_COMPARE( e_read_buffer, e_read_length, e_arg->x, e_arg->len );
5596
5597 /* Do something with the key according to its type and permitted usage. */
5598 if( ! exercise_key( handle, usage, alg ) )
5599 goto exit;
5600
5601 /* Export the key and check the public exponent. */
5602 PSA_ASSERT( psa_export_public_key( handle,
5603 exported, exported_size,
5604 &exported_length ) );
5605 {
5606 uint8_t *p = exported;
5607 uint8_t *end = exported + exported_length;
5608 size_t len;
5609 /* RSAPublicKey ::= SEQUENCE {
5610 * modulus INTEGER, -- n
5611 * publicExponent INTEGER } -- e
5612 */
5613 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005614 MBEDTLS_ASN1_SEQUENCE |
5615 MBEDTLS_ASN1_CONSTRUCTED ) );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005616 TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) );
5617 TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len,
5618 MBEDTLS_ASN1_INTEGER ) );
5619 if( len >= 1 && p[0] == 0 )
5620 {
5621 ++p;
5622 --len;
5623 }
5624 if( e_arg->len == 0 )
5625 {
5626 TEST_EQUAL( len, 3 );
5627 TEST_EQUAL( p[0], 1 );
5628 TEST_EQUAL( p[1], 0 );
5629 TEST_EQUAL( p[2], 1 );
5630 }
5631 else
5632 ASSERT_COMPARE( p, len, e_arg->x, e_arg->len );
5633 }
5634
5635exit:
5636 psa_reset_key_attributes( &attributes );
5637 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005638 PSA_DONE( );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005639 mbedtls_free( e_read_buffer );
5640 mbedtls_free( exported );
5641}
5642/* END_CASE */
5643
Darryl Greend49a4992018-06-18 17:27:26 +01005644/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005645void persistent_key_load_key_from_storage( data_t *data,
5646 int type_arg, int bits_arg,
5647 int usage_flags_arg, int alg_arg,
5648 int generation_method )
Darryl Greend49a4992018-06-18 17:27:26 +01005649{
Ronald Cron71016a92020-08-28 19:01:50 +02005650 mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make( 1, 1 );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005651 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cron91e95152020-07-30 17:48:03 +02005652 psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
5653 psa_key_handle_t base_key = PSA_KEY_HANDLE_INIT;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005654 psa_key_type_t type = type_arg;
5655 size_t bits = bits_arg;
5656 psa_key_usage_t usage_flags = usage_flags_arg;
5657 psa_algorithm_t alg = alg_arg;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005658 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Darryl Greend49a4992018-06-18 17:27:26 +01005659 unsigned char *first_export = NULL;
5660 unsigned char *second_export = NULL;
5661 size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
5662 size_t first_exported_length;
5663 size_t second_exported_length;
5664
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005665 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5666 {
5667 ASSERT_ALLOC( first_export, export_size );
5668 ASSERT_ALLOC( second_export, export_size );
5669 }
Darryl Greend49a4992018-06-18 17:27:26 +01005670
Gilles Peskine8817f612018-12-18 00:18:46 +01005671 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005672
Gilles Peskinec87af662019-05-15 16:12:22 +02005673 psa_set_key_id( &attributes, key_id );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005674 psa_set_key_usage_flags( &attributes, usage_flags );
5675 psa_set_key_algorithm( &attributes, alg );
5676 psa_set_key_type( &attributes, type );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +02005677 psa_set_key_bits( &attributes, bits );
Darryl Greend49a4992018-06-18 17:27:26 +01005678
Darryl Green0c6575a2018-11-07 16:05:30 +00005679 switch( generation_method )
5680 {
5681 case IMPORT_KEY:
5682 /* Import the key */
Gilles Peskine049c7532019-05-15 20:22:09 +02005683 PSA_ASSERT( psa_import_key( &attributes, data->x, data->len,
5684 &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005685 break;
Darryl Greend49a4992018-06-18 17:27:26 +01005686
Darryl Green0c6575a2018-11-07 16:05:30 +00005687 case GENERATE_KEY:
5688 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005689 PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005690 break;
5691
5692 case DERIVE_KEY:
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005693 {
5694 /* Create base key */
5695 psa_algorithm_t derive_alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 );
5696 psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
5697 psa_set_key_usage_flags( &base_attributes,
5698 PSA_KEY_USAGE_DERIVE );
5699 psa_set_key_algorithm( &base_attributes, derive_alg );
5700 psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE );
Gilles Peskine049c7532019-05-15 20:22:09 +02005701 PSA_ASSERT( psa_import_key( &base_attributes,
5702 data->x, data->len,
5703 &base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005704 /* Derive a key. */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005705 PSA_ASSERT( psa_key_derivation_setup( &operation, derive_alg ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005706 PSA_ASSERT( psa_key_derivation_input_key(
5707 &operation,
5708 PSA_KEY_DERIVATION_INPUT_SECRET, base_key ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005709 PSA_ASSERT( psa_key_derivation_input_bytes(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005710 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005711 NULL, 0 ) );
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005712 PSA_ASSERT( psa_key_derivation_output_key( &attributes,
5713 &operation,
5714 &handle ) );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005715 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005716 PSA_ASSERT( psa_destroy_key( base_key ) );
Ronald Cron91e95152020-07-30 17:48:03 +02005717 base_key = PSA_KEY_HANDLE_INIT;
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005718 }
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005719 break;
Darryl Green0c6575a2018-11-07 16:05:30 +00005720 }
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005721 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005722
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005723 /* Export the key if permitted by the key policy. */
5724 if( usage_flags & PSA_KEY_USAGE_EXPORT )
5725 {
5726 PSA_ASSERT( psa_export_key( handle,
5727 first_export, export_size,
5728 &first_exported_length ) );
5729 if( generation_method == IMPORT_KEY )
5730 ASSERT_COMPARE( data->x, data->len,
5731 first_export, first_exported_length );
5732 }
Darryl Greend49a4992018-06-18 17:27:26 +01005733
5734 /* Shutdown and restart */
Gilles Peskine76b29a72019-05-28 14:08:50 +02005735 PSA_ASSERT( psa_close_key( handle ) );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005736 PSA_DONE();
Gilles Peskine8817f612018-12-18 00:18:46 +01005737 PSA_ASSERT( psa_crypto_init() );
Darryl Greend49a4992018-06-18 17:27:26 +01005738
Darryl Greend49a4992018-06-18 17:27:26 +01005739 /* Check key slot still contains key data */
Gilles Peskine225010f2019-05-06 18:44:55 +02005740 PSA_ASSERT( psa_open_key( key_id, &handle ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005741 PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
Ronald Cronecfb2372020-07-23 17:13:42 +02005742 TEST_ASSERT( mbedtls_svc_key_id_equal(
5743 psa_get_key_id( &attributes ), key_id ) );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005744 TEST_EQUAL( psa_get_key_lifetime( &attributes ),
5745 PSA_KEY_LIFETIME_PERSISTENT );
5746 TEST_EQUAL( psa_get_key_type( &attributes ), type );
5747 TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
5748 TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
5749 TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
Darryl Greend49a4992018-06-18 17:27:26 +01005750
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005751 /* Export the key again if permitted by the key policy. */
5752 if( usage_flags & PSA_KEY_USAGE_EXPORT )
Darryl Green0c6575a2018-11-07 16:05:30 +00005753 {
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005754 PSA_ASSERT( psa_export_key( handle,
5755 second_export, export_size,
5756 &second_exported_length ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005757 ASSERT_COMPARE( first_export, first_exported_length,
5758 second_export, second_exported_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005759 }
5760
5761 /* Do something with the key according to its type and permitted usage. */
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005762 if( ! exercise_key( handle, usage_flags, alg ) )
Darryl Green0c6575a2018-11-07 16:05:30 +00005763 goto exit;
Darryl Greend49a4992018-06-18 17:27:26 +01005764
5765exit:
Gilles Peskinea1ace9c2019-04-26 16:03:33 +02005766 psa_reset_key_attributes( &attributes );
Darryl Greend49a4992018-06-18 17:27:26 +01005767 mbedtls_free( first_export );
5768 mbedtls_free( second_export );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005769 psa_key_derivation_abort( &operation );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005770 psa_destroy_key( base_key );
Ronald Cronc26f8d42020-09-01 10:51:51 +02005771 if( psa_key_handle_is_null( handle ) )
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005772 {
5773 /* In case there was a test failure after creating the persistent key
5774 * but while it was not open, try to re-open the persistent key
5775 * to delete it. */
Gilles Peskinee92c68a2020-08-26 00:06:25 +02005776 (void) psa_open_key( key_id, &handle );
Gilles Peskine5c648ab2019-04-19 14:06:53 +02005777 }
Gilles Peskinebdf309c2018-12-03 15:36:32 +01005778 psa_destroy_key( handle );
Gilles Peskine1153e7b2019-05-28 15:10:21 +02005779 PSA_DONE();
Darryl Greend49a4992018-06-18 17:27:26 +01005780}
5781/* END_CASE */