blob: 090875613f35f10a8490e61bc420f4b3a71c51a9 [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>
Jaeden Amerodb29ab52019-02-12 16:40:27 +00008#include <stdlib.h>
9#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
itayzafrir10366702018-07-11 13:44:41 +030010#define mbedtls_printf printf
Jaeden Amerodb29ab52019-02-12 16:40:27 +000011#define mbedtls_exit exit
itayzafrir10366702018-07-11 13:44:41 +030012#endif
13
14#define ASSERT( predicate ) \
15 do \
16 { \
17 if( ! ( predicate ) ) \
18 { \
19 mbedtls_printf( "\tassertion failed at %s:%d - '%s'\r\n", \
20 __FILE__, __LINE__, #predicate); \
21 goto exit; \
22 } \
23 } while ( 0 )
24
25#define ASSERT_STATUS( actual, expected ) \
26 do \
27 { \
28 if( ( actual ) != ( expected ) ) \
29 { \
30 mbedtls_printf( "\tassertion failed at %s:%d - " \
31 "actual:%d expected:%d\r\n", __FILE__, __LINE__, \
32 (psa_status_t) actual, (psa_status_t) expected ); \
33 goto exit; \
34 } \
35 } while ( 0 )
36
itayzafrir18ac3312018-07-17 09:28:11 +030037#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_AES_C) || \
38 !defined(MBEDTLS_CIPHER_MODE_CBC) || !defined(MBEDTLS_CIPHER_MODE_CTR) || \
39 !defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
40int main( void )
41{
42 mbedtls_printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or "
43 "MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR "
44 "and/or MBEDTLS_CIPHER_MODE_WITH_PADDING "
45 "not defined.\r\n" );
46 return( 0 );
47}
48#else
49
Gilles Peskineb0edfb52018-12-03 16:24:51 +010050static psa_status_t set_key_policy( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +030051 psa_key_usage_t key_usage,
52 psa_algorithm_t alg )
53{
54 psa_status_t status;
Jaeden Amero70261c52019-01-04 11:47:20 +000055 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
itayzafrir10366702018-07-11 13:44:41 +030056
itayzafrir10366702018-07-11 13:44:41 +030057 psa_key_policy_set_usage( &policy, key_usage, alg );
Gilles Peskineb0edfb52018-12-03 16:24:51 +010058 status = psa_set_key_policy( key_handle, &policy );
itayzafrir10366702018-07-11 13:44:41 +030059 ASSERT_STATUS( status, PSA_SUCCESS );
60exit:
61 return( status );
62}
63
64static psa_status_t cipher_operation( psa_cipher_operation_t *operation,
65 const uint8_t * input,
66 size_t input_size,
67 size_t part_size,
68 uint8_t * output,
69 size_t output_size,
70 size_t *output_len )
71{
72 psa_status_t status;
73 size_t bytes_to_write = 0, bytes_written = 0, len = 0;
74
75 *output_len = 0;
76 while( bytes_written != input_size )
77 {
78 bytes_to_write = ( input_size - bytes_written > part_size ?
79 part_size :
80 input_size - bytes_written );
81
82 status = psa_cipher_update( operation, input + bytes_written,
83 bytes_to_write, output + *output_len,
84 output_size - *output_len, &len );
85 ASSERT_STATUS( status, PSA_SUCCESS );
86
87 bytes_written += bytes_to_write;
88 *output_len += len;
89 }
90
91 status = psa_cipher_finish( operation, output + *output_len,
92 output_size - *output_len, &len );
93 ASSERT_STATUS( status, PSA_SUCCESS );
94 *output_len += len;
95
96exit:
97 return( status );
98}
99
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100100static psa_status_t cipher_encrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300101 psa_algorithm_t alg,
102 uint8_t * iv,
103 size_t iv_size,
104 const uint8_t * input,
105 size_t input_size,
106 size_t part_size,
107 uint8_t * output,
108 size_t output_size,
109 size_t *output_len )
110{
111 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +0000112 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +0300113 size_t iv_len = 0;
114
115 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100116 status = psa_cipher_encrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +0300117 ASSERT_STATUS( status, PSA_SUCCESS );
118
119 status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len );
120 ASSERT_STATUS( status, PSA_SUCCESS );
121
122 status = cipher_operation( &operation, input, input_size, part_size,
123 output, output_size, output_len );
124 ASSERT_STATUS( status, PSA_SUCCESS );
125
126exit:
127 psa_cipher_abort( &operation );
128 return( status );
129}
130
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100131static psa_status_t cipher_decrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300132 psa_algorithm_t alg,
133 const uint8_t * iv,
134 size_t iv_size,
135 const uint8_t * input,
136 size_t input_size,
137 size_t part_size,
138 uint8_t * output,
139 size_t output_size,
140 size_t *output_len )
141{
142 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +0000143 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +0300144
145 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100146 status = psa_cipher_decrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +0300147 ASSERT_STATUS( status, PSA_SUCCESS );
148
149 status = psa_cipher_set_iv( &operation, iv, iv_size );
150 ASSERT_STATUS( status, PSA_SUCCESS );
151
152 status = cipher_operation( &operation, input, input_size, part_size,
153 output, output_size, output_len );
154 ASSERT_STATUS( status, PSA_SUCCESS );
155
156exit:
157 psa_cipher_abort( &operation );
158 return( status );
159}
160
161static psa_status_t
162cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
163{
164 enum {
165 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
166 key_bits = 256,
167 part_size = block_size,
168 };
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200169 const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
itayzafrir10366702018-07-11 13:44:41 +0300170
171 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100172 psa_key_handle_t key_handle = 0;
itayzafrir10366702018-07-11 13:44:41 +0300173 size_t output_len = 0;
174 uint8_t iv[block_size];
175 uint8_t input[block_size];
176 uint8_t encrypt[block_size];
177 uint8_t decrypt[block_size];
178
179 status = psa_generate_random( input, sizeof( input ) );
180 ASSERT_STATUS( status, PSA_SUCCESS );
181
Gilles Peskined40c1fb2019-01-19 12:20:52 +0100182 status = psa_allocate_key( &key_handle );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100183 ASSERT_STATUS( status, PSA_SUCCESS );
184
185 status = set_key_policy( key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300186 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
187 alg );
188 ASSERT_STATUS( status, PSA_SUCCESS );
189
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100190 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrir10366702018-07-11 13:44:41 +0300191 NULL, 0 );
192 ASSERT_STATUS( status, PSA_SUCCESS );
193
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100194 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300195 input, sizeof( input ), part_size,
196 encrypt, sizeof( encrypt ), &output_len );
197 ASSERT_STATUS( status, PSA_SUCCESS );
198
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100199 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300200 encrypt, output_len, part_size,
201 decrypt, sizeof( decrypt ), &output_len );
202 ASSERT_STATUS( status, PSA_SUCCESS );
203
204 status = memcmp( input, decrypt, sizeof( input ) );
205 ASSERT_STATUS( status, PSA_SUCCESS );
206
207exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100208 psa_destroy_key( key_handle );
itayzafrir10366702018-07-11 13:44:41 +0300209 return( status );
210}
211
itayzafrira2d08042018-07-12 10:27:58 +0300212static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void )
213{
214 enum {
215 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
216 key_bits = 256,
217 input_size = 100,
218 part_size = 10,
219 };
220
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200221 const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
itayzafrira2d08042018-07-12 10:27:58 +0300222
223 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100224 psa_key_handle_t key_handle = 0;
itayzafrira2d08042018-07-12 10:27:58 +0300225 size_t output_len = 0;
226 uint8_t iv[block_size], input[input_size],
227 encrypt[input_size + block_size], decrypt[input_size + block_size];
228
229 status = psa_generate_random( input, sizeof( input ) );
230 ASSERT_STATUS( status, PSA_SUCCESS );
231
Gilles Peskined40c1fb2019-01-19 12:20:52 +0100232 status = psa_allocate_key( &key_handle );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100233 ASSERT_STATUS( status, PSA_SUCCESS );
234
235 status = set_key_policy( key_handle,
itayzafrira2d08042018-07-12 10:27:58 +0300236 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
237 alg );
238 ASSERT_STATUS( status, PSA_SUCCESS );
239
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100240 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrira2d08042018-07-12 10:27:58 +0300241 NULL, 0 );
242 ASSERT_STATUS( status, PSA_SUCCESS );
243
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100244 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300245 input, sizeof( input ), part_size,
246 encrypt, sizeof( encrypt ), &output_len );
247 ASSERT_STATUS( status, PSA_SUCCESS );
248
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100249 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300250 encrypt, output_len, part_size,
251 decrypt, sizeof( decrypt ), &output_len );
252 ASSERT_STATUS( status, PSA_SUCCESS );
253
254 status = memcmp( input, decrypt, sizeof( input ) );
255 ASSERT_STATUS( status, PSA_SUCCESS );
256
257exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100258 psa_destroy_key( key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300259 return( status );
260}
261
itayzafrir44b09d22018-07-12 13:06:41 +0300262static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
263{
264 enum {
265 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
266 key_bits = 256,
267 input_size = 100,
268 part_size = 10,
269 };
270 const psa_algorithm_t alg = PSA_ALG_CTR;
271
272 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100273 psa_key_handle_t key_handle = 0;
itayzafrir44b09d22018-07-12 13:06:41 +0300274 size_t output_len = 0;
275 uint8_t iv[block_size], input[input_size], encrypt[input_size],
276 decrypt[input_size];
277
278 status = psa_generate_random( input, sizeof( input ) );
279 ASSERT_STATUS( status, PSA_SUCCESS );
280
Gilles Peskined40c1fb2019-01-19 12:20:52 +0100281 status = psa_allocate_key( &key_handle );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100282 ASSERT_STATUS( status, PSA_SUCCESS );
283 status = set_key_policy( key_handle,
itayzafrir44b09d22018-07-12 13:06:41 +0300284 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
285 alg );
286 ASSERT_STATUS( status, PSA_SUCCESS );
287
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100288 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrir44b09d22018-07-12 13:06:41 +0300289 NULL, 0 );
290 ASSERT_STATUS( status, PSA_SUCCESS );
291
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100292 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300293 input, sizeof( input ), part_size,
294 encrypt, sizeof( encrypt ), &output_len );
295 ASSERT_STATUS( status, PSA_SUCCESS );
296
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100297 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300298 encrypt, output_len, part_size,
299 decrypt, sizeof( decrypt ), &output_len );
300 ASSERT_STATUS( status, PSA_SUCCESS );
301
302 status = memcmp( input, decrypt, sizeof( input ) );
303 ASSERT_STATUS( status, PSA_SUCCESS );
304
305exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100306 psa_destroy_key( key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300307 return( status );
308}
309
itayzafrir10366702018-07-11 13:44:41 +0300310static void cipher_examples( void )
311{
312 psa_status_t status;
313
314 mbedtls_printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
315 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
316 if( status == PSA_SUCCESS )
317 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300318
319 mbedtls_printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
320 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
321 if( status == PSA_SUCCESS )
322 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300323
324 mbedtls_printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
325 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
326 if( status == PSA_SUCCESS )
327 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300328}
329
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000330#if defined(MBEDTLS_CHECK_PARAMS)
331#include "mbedtls/platform_util.h"
332void mbedtls_param_failed( const char *failure_condition,
333 const char *file,
334 int line )
335{
336 mbedtls_printf( "%s:%i: Input param failed - %s\n",
337 file, line, failure_condition );
338 mbedtls_exit( MBEDTLS_EXIT_FAILURE );
339}
340#endif
341
itayzafrira3ff8a62018-07-10 10:10:21 +0300342int main( void )
343{
itayzafrir10366702018-07-11 13:44:41 +0300344 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
345 cipher_examples( );
346exit:
347 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300348 return( 0 );
349}
itayzafrir18ac3312018-07-17 09:28:11 +0300350#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
351 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */