blob: d7a667b7ff5e57aaec06054b34aa75814bca2b78 [file] [log] [blame]
itayzafrir10366702018-07-11 13:44:41 +03001#include "psa/crypto.h"
2#include <string.h>
3
4#if defined(MBEDTLS_PLATFORM_C)
5#include "mbedtls/platform.h"
6#else
7#include <stdio.h>
8#define mbedtls_printf printf
9#endif
10
11#define ASSERT( predicate ) \
12 do \
13 { \
14 if( ! ( predicate ) ) \
15 { \
16 mbedtls_printf( "\tassertion failed at %s:%d - '%s'\r\n", \
17 __FILE__, __LINE__, #predicate); \
18 goto exit; \
19 } \
20 } while ( 0 )
21
22#define ASSERT_STATUS( actual, expected ) \
23 do \
24 { \
25 if( ( actual ) != ( expected ) ) \
26 { \
27 mbedtls_printf( "\tassertion failed at %s:%d - " \
28 "actual:%d expected:%d\r\n", __FILE__, __LINE__, \
29 (psa_status_t) actual, (psa_status_t) expected ); \
30 goto exit; \
31 } \
32 } while ( 0 )
33
itayzafrir18ac3312018-07-17 09:28:11 +030034#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_AES_C) || \
35 !defined(MBEDTLS_CIPHER_MODE_CBC) || !defined(MBEDTLS_CIPHER_MODE_CTR) || \
36 !defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
37int main( void )
38{
39 mbedtls_printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or "
40 "MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR "
41 "and/or MBEDTLS_CIPHER_MODE_WITH_PADDING "
42 "not defined.\r\n" );
43 return( 0 );
44}
45#else
46
Gilles Peskineb0edfb52018-12-03 16:24:51 +010047static psa_status_t set_key_policy( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +030048 psa_key_usage_t key_usage,
49 psa_algorithm_t alg )
50{
51 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +000052 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
itayzafrir10366702018-07-11 13:44:41 +030053
itayzafrir10366702018-07-11 13:44:41 +030054 psa_key_policy_set_usage( &policy, key_usage, alg );
Gilles Peskineb0edfb52018-12-03 16:24:51 +010055 status = psa_set_key_policy( key_handle, &policy );
itayzafrir10366702018-07-11 13:44:41 +030056 ASSERT_STATUS( status, PSA_SUCCESS );
57exit:
58 return( status );
59}
60
61static psa_status_t cipher_operation( psa_cipher_operation_t *operation,
62 const uint8_t * input,
63 size_t input_size,
64 size_t part_size,
65 uint8_t * output,
66 size_t output_size,
67 size_t *output_len )
68{
69 psa_status_t status;
70 size_t bytes_to_write = 0, bytes_written = 0, len = 0;
71
72 *output_len = 0;
73 while( bytes_written != input_size )
74 {
75 bytes_to_write = ( input_size - bytes_written > part_size ?
76 part_size :
77 input_size - bytes_written );
78
79 status = psa_cipher_update( operation, input + bytes_written,
80 bytes_to_write, output + *output_len,
81 output_size - *output_len, &len );
82 ASSERT_STATUS( status, PSA_SUCCESS );
83
84 bytes_written += bytes_to_write;
85 *output_len += len;
86 }
87
88 status = psa_cipher_finish( operation, output + *output_len,
89 output_size - *output_len, &len );
90 ASSERT_STATUS( status, PSA_SUCCESS );
91 *output_len += len;
92
93exit:
94 return( status );
95}
96
Gilles Peskineb0edfb52018-12-03 16:24:51 +010097static psa_status_t cipher_encrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +030098 psa_algorithm_t alg,
99 uint8_t * iv,
100 size_t iv_size,
101 const uint8_t * input,
102 size_t input_size,
103 size_t part_size,
104 uint8_t * output,
105 size_t output_size,
106 size_t *output_len )
107{
108 psa_status_t status;
109 psa_cipher_operation_t operation;
110 size_t iv_len = 0;
111
112 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100113 status = psa_cipher_encrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +0300114 ASSERT_STATUS( status, PSA_SUCCESS );
115
116 status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len );
117 ASSERT_STATUS( status, PSA_SUCCESS );
118
119 status = cipher_operation( &operation, input, input_size, part_size,
120 output, output_size, output_len );
121 ASSERT_STATUS( status, PSA_SUCCESS );
122
123exit:
124 psa_cipher_abort( &operation );
125 return( status );
126}
127
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100128static psa_status_t cipher_decrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300129 psa_algorithm_t alg,
130 const uint8_t * iv,
131 size_t iv_size,
132 const uint8_t * input,
133 size_t input_size,
134 size_t part_size,
135 uint8_t * output,
136 size_t output_size,
137 size_t *output_len )
138{
139 psa_status_t status;
140 psa_cipher_operation_t operation;
141
142 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100143 status = psa_cipher_decrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +0300144 ASSERT_STATUS( status, PSA_SUCCESS );
145
146 status = psa_cipher_set_iv( &operation, iv, iv_size );
147 ASSERT_STATUS( status, PSA_SUCCESS );
148
149 status = cipher_operation( &operation, input, input_size, part_size,
150 output, output_size, output_len );
151 ASSERT_STATUS( status, PSA_SUCCESS );
152
153exit:
154 psa_cipher_abort( &operation );
155 return( status );
156}
157
158static psa_status_t
159cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
160{
161 enum {
162 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
163 key_bits = 256,
164 part_size = block_size,
165 };
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200166 const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
itayzafrir10366702018-07-11 13:44:41 +0300167
168 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100169 psa_key_handle_t key_handle = 0;
itayzafrir10366702018-07-11 13:44:41 +0300170 size_t output_len = 0;
171 uint8_t iv[block_size];
172 uint8_t input[block_size];
173 uint8_t encrypt[block_size];
174 uint8_t decrypt[block_size];
175
176 status = psa_generate_random( input, sizeof( input ) );
177 ASSERT_STATUS( status, PSA_SUCCESS );
178
Gilles Peskined40c1fb2019-01-19 12:20:52 +0100179 status = psa_allocate_key( &key_handle );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100180 ASSERT_STATUS( status, PSA_SUCCESS );
181
182 status = set_key_policy( key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300183 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
184 alg );
185 ASSERT_STATUS( status, PSA_SUCCESS );
186
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100187 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrir10366702018-07-11 13:44:41 +0300188 NULL, 0 );
189 ASSERT_STATUS( status, PSA_SUCCESS );
190
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100191 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300192 input, sizeof( input ), part_size,
193 encrypt, sizeof( encrypt ), &output_len );
194 ASSERT_STATUS( status, PSA_SUCCESS );
195
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100196 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300197 encrypt, output_len, part_size,
198 decrypt, sizeof( decrypt ), &output_len );
199 ASSERT_STATUS( status, PSA_SUCCESS );
200
201 status = memcmp( input, decrypt, sizeof( input ) );
202 ASSERT_STATUS( status, PSA_SUCCESS );
203
204exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100205 psa_destroy_key( key_handle );
itayzafrir10366702018-07-11 13:44:41 +0300206 return( status );
207}
208
itayzafrira2d08042018-07-12 10:27:58 +0300209static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void )
210{
211 enum {
212 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
213 key_bits = 256,
214 input_size = 100,
215 part_size = 10,
216 };
217
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200218 const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
itayzafrira2d08042018-07-12 10:27:58 +0300219
220 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100221 psa_key_handle_t key_handle = 0;
itayzafrira2d08042018-07-12 10:27:58 +0300222 size_t output_len = 0;
223 uint8_t iv[block_size], input[input_size],
224 encrypt[input_size + block_size], decrypt[input_size + block_size];
225
226 status = psa_generate_random( input, sizeof( input ) );
227 ASSERT_STATUS( status, PSA_SUCCESS );
228
Gilles Peskined40c1fb2019-01-19 12:20:52 +0100229 status = psa_allocate_key( &key_handle );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100230 ASSERT_STATUS( status, PSA_SUCCESS );
231
232 status = set_key_policy( key_handle,
itayzafrira2d08042018-07-12 10:27:58 +0300233 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
234 alg );
235 ASSERT_STATUS( status, PSA_SUCCESS );
236
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100237 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrira2d08042018-07-12 10:27:58 +0300238 NULL, 0 );
239 ASSERT_STATUS( status, PSA_SUCCESS );
240
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100241 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300242 input, sizeof( input ), part_size,
243 encrypt, sizeof( encrypt ), &output_len );
244 ASSERT_STATUS( status, PSA_SUCCESS );
245
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100246 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300247 encrypt, output_len, part_size,
248 decrypt, sizeof( decrypt ), &output_len );
249 ASSERT_STATUS( status, PSA_SUCCESS );
250
251 status = memcmp( input, decrypt, sizeof( input ) );
252 ASSERT_STATUS( status, PSA_SUCCESS );
253
254exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100255 psa_destroy_key( key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300256 return( status );
257}
258
itayzafrir44b09d22018-07-12 13:06:41 +0300259static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
260{
261 enum {
262 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
263 key_bits = 256,
264 input_size = 100,
265 part_size = 10,
266 };
267 const psa_algorithm_t alg = PSA_ALG_CTR;
268
269 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100270 psa_key_handle_t key_handle = 0;
itayzafrir44b09d22018-07-12 13:06:41 +0300271 size_t output_len = 0;
272 uint8_t iv[block_size], input[input_size], encrypt[input_size],
273 decrypt[input_size];
274
275 status = psa_generate_random( input, sizeof( input ) );
276 ASSERT_STATUS( status, PSA_SUCCESS );
277
Gilles Peskined40c1fb2019-01-19 12:20:52 +0100278 status = psa_allocate_key( &key_handle );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100279 ASSERT_STATUS( status, PSA_SUCCESS );
280 status = set_key_policy( key_handle,
itayzafrir44b09d22018-07-12 13:06:41 +0300281 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
282 alg );
283 ASSERT_STATUS( status, PSA_SUCCESS );
284
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100285 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrir44b09d22018-07-12 13:06:41 +0300286 NULL, 0 );
287 ASSERT_STATUS( status, PSA_SUCCESS );
288
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100289 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300290 input, sizeof( input ), part_size,
291 encrypt, sizeof( encrypt ), &output_len );
292 ASSERT_STATUS( status, PSA_SUCCESS );
293
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100294 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300295 encrypt, output_len, part_size,
296 decrypt, sizeof( decrypt ), &output_len );
297 ASSERT_STATUS( status, PSA_SUCCESS );
298
299 status = memcmp( input, decrypt, sizeof( input ) );
300 ASSERT_STATUS( status, PSA_SUCCESS );
301
302exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100303 psa_destroy_key( key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300304 return( status );
305}
306
itayzafrir10366702018-07-11 13:44:41 +0300307static void cipher_examples( void )
308{
309 psa_status_t status;
310
311 mbedtls_printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
312 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
313 if( status == PSA_SUCCESS )
314 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300315
316 mbedtls_printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
317 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
318 if( status == PSA_SUCCESS )
319 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300320
321 mbedtls_printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
322 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
323 if( status == PSA_SUCCESS )
324 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300325}
326
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000327#if defined(MBEDTLS_CHECK_PARAMS)
328#include "mbedtls/platform_util.h"
329void mbedtls_param_failed( const char *failure_condition,
330 const char *file,
331 int line )
332{
333 mbedtls_printf( "%s:%i: Input param failed - %s\n",
334 file, line, failure_condition );
335 mbedtls_exit( MBEDTLS_EXIT_FAILURE );
336}
337#endif
338
itayzafrira3ff8a62018-07-10 10:10:21 +0300339int main( void )
340{
itayzafrir10366702018-07-11 13:44:41 +0300341 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
342 cipher_examples( );
343exit:
344 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300345 return( 0 );
346}
itayzafrir18ac3312018-07-17 09:28:11 +0300347#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
348 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */