blob: f156b7b26189ab7f6dfe6492184be43511fce13e [file] [log] [blame]
itayzafrir10366702018-07-11 13:44:41 +03001#include "psa/crypto.h"
2#include <string.h>
itayzafrir10366702018-07-11 13:44:41 +03003#include <stdio.h>
Jaeden Amerodb29ab52019-02-12 16:40:27 +00004#include <stdlib.h>
itayzafrir10366702018-07-11 13:44:41 +03005
6#define ASSERT( predicate ) \
7 do \
8 { \
9 if( ! ( predicate ) ) \
10 { \
Jaeden Amerofa30c332018-12-21 18:42:18 +000011 printf( "\tassertion failed at %s:%d - '%s'\r\n", \
12 __FILE__, __LINE__, #predicate); \
itayzafrir10366702018-07-11 13:44:41 +030013 goto exit; \
14 } \
15 } while ( 0 )
16
17#define ASSERT_STATUS( actual, expected ) \
18 do \
19 { \
20 if( ( actual ) != ( expected ) ) \
21 { \
Jaeden Amerofa30c332018-12-21 18:42:18 +000022 printf( "\tassertion failed at %s:%d - " \
23 "actual:%d expected:%d\r\n", __FILE__, __LINE__, \
itayzafrir10366702018-07-11 13:44:41 +030024 (psa_status_t) actual, (psa_status_t) expected ); \
25 goto exit; \
26 } \
27 } while ( 0 )
28
itayzafrir18ac3312018-07-17 09:28:11 +030029#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_AES_C) || \
30 !defined(MBEDTLS_CIPHER_MODE_CBC) || !defined(MBEDTLS_CIPHER_MODE_CTR) || \
31 !defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
32int main( void )
33{
Jaeden Amerofa30c332018-12-21 18:42:18 +000034 printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or "
35 "MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR "
36 "and/or MBEDTLS_CIPHER_MODE_WITH_PADDING "
37 "not defined.\r\n" );
itayzafrir18ac3312018-07-17 09:28:11 +030038 return( 0 );
39}
40#else
41
itayzafrir10366702018-07-11 13:44:41 +030042static psa_status_t cipher_operation( psa_cipher_operation_t *operation,
43 const uint8_t * input,
44 size_t input_size,
45 size_t part_size,
46 uint8_t * output,
47 size_t output_size,
48 size_t *output_len )
49{
50 psa_status_t status;
51 size_t bytes_to_write = 0, bytes_written = 0, len = 0;
52
53 *output_len = 0;
54 while( bytes_written != input_size )
55 {
56 bytes_to_write = ( input_size - bytes_written > part_size ?
57 part_size :
58 input_size - bytes_written );
59
60 status = psa_cipher_update( operation, input + bytes_written,
61 bytes_to_write, output + *output_len,
62 output_size - *output_len, &len );
63 ASSERT_STATUS( status, PSA_SUCCESS );
64
65 bytes_written += bytes_to_write;
66 *output_len += len;
67 }
68
69 status = psa_cipher_finish( operation, output + *output_len,
70 output_size - *output_len, &len );
71 ASSERT_STATUS( status, PSA_SUCCESS );
72 *output_len += len;
73
74exit:
75 return( status );
76}
77
Gilles Peskineb0edfb52018-12-03 16:24:51 +010078static psa_status_t cipher_encrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +030079 psa_algorithm_t alg,
80 uint8_t * iv,
81 size_t iv_size,
82 const uint8_t * input,
83 size_t input_size,
84 size_t part_size,
85 uint8_t * output,
86 size_t output_size,
87 size_t *output_len )
88{
89 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +000090 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +030091 size_t iv_len = 0;
92
93 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +010094 status = psa_cipher_encrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +030095 ASSERT_STATUS( status, PSA_SUCCESS );
96
97 status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len );
98 ASSERT_STATUS( status, PSA_SUCCESS );
99
100 status = cipher_operation( &operation, input, input_size, part_size,
101 output, output_size, output_len );
102 ASSERT_STATUS( status, PSA_SUCCESS );
103
104exit:
105 psa_cipher_abort( &operation );
106 return( status );
107}
108
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100109static psa_status_t cipher_decrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300110 psa_algorithm_t alg,
111 const uint8_t * iv,
112 size_t iv_size,
113 const uint8_t * input,
114 size_t input_size,
115 size_t part_size,
116 uint8_t * output,
117 size_t output_size,
118 size_t *output_len )
119{
120 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +0000121 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +0300122
123 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100124 status = psa_cipher_decrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +0300125 ASSERT_STATUS( status, PSA_SUCCESS );
126
127 status = psa_cipher_set_iv( &operation, iv, iv_size );
128 ASSERT_STATUS( status, PSA_SUCCESS );
129
130 status = cipher_operation( &operation, input, input_size, part_size,
131 output, output_size, output_len );
132 ASSERT_STATUS( status, PSA_SUCCESS );
133
134exit:
135 psa_cipher_abort( &operation );
136 return( status );
137}
138
139static psa_status_t
140cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
141{
142 enum {
143 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
144 key_bits = 256,
145 part_size = block_size,
146 };
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200147 const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
itayzafrir10366702018-07-11 13:44:41 +0300148
149 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200150 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100151 psa_key_handle_t key_handle = 0;
itayzafrir10366702018-07-11 13:44:41 +0300152 size_t output_len = 0;
153 uint8_t iv[block_size];
154 uint8_t input[block_size];
155 uint8_t encrypt[block_size];
156 uint8_t decrypt[block_size];
157
158 status = psa_generate_random( input, sizeof( input ) );
159 ASSERT_STATUS( status, PSA_SUCCESS );
160
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200161 psa_set_key_usage_flags( &attributes,
162 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
163 psa_set_key_algorithm( &attributes, alg );
164 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200165 psa_set_key_bits( &attributes, key_bits );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100166
Gilles Peskine35ef36b2019-05-16 19:42:05 +0200167 status = psa_generate_key( &attributes, &key_handle );
itayzafrir10366702018-07-11 13:44:41 +0300168 ASSERT_STATUS( status, PSA_SUCCESS );
169
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100170 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300171 input, sizeof( input ), part_size,
172 encrypt, sizeof( encrypt ), &output_len );
173 ASSERT_STATUS( status, PSA_SUCCESS );
174
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100175 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300176 encrypt, output_len, part_size,
177 decrypt, sizeof( decrypt ), &output_len );
178 ASSERT_STATUS( status, PSA_SUCCESS );
179
180 status = memcmp( input, decrypt, sizeof( input ) );
181 ASSERT_STATUS( status, PSA_SUCCESS );
182
183exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100184 psa_destroy_key( key_handle );
itayzafrir10366702018-07-11 13:44:41 +0300185 return( status );
186}
187
itayzafrira2d08042018-07-12 10:27:58 +0300188static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void )
189{
190 enum {
191 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
192 key_bits = 256,
193 input_size = 100,
194 part_size = 10,
195 };
196
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200197 const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
itayzafrira2d08042018-07-12 10:27:58 +0300198
199 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200200 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100201 psa_key_handle_t key_handle = 0;
itayzafrira2d08042018-07-12 10:27:58 +0300202 size_t output_len = 0;
203 uint8_t iv[block_size], input[input_size],
204 encrypt[input_size + block_size], decrypt[input_size + block_size];
205
206 status = psa_generate_random( input, sizeof( input ) );
207 ASSERT_STATUS( status, PSA_SUCCESS );
208
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200209 psa_set_key_usage_flags( &attributes,
210 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
211 psa_set_key_algorithm( &attributes, alg );
212 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200213 psa_set_key_bits( &attributes, key_bits );
itayzafrira2d08042018-07-12 10:27:58 +0300214
Gilles Peskine35ef36b2019-05-16 19:42:05 +0200215 status = psa_generate_key( &attributes, &key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300216 ASSERT_STATUS( status, PSA_SUCCESS );
217
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100218 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300219 input, sizeof( input ), part_size,
220 encrypt, sizeof( encrypt ), &output_len );
221 ASSERT_STATUS( status, PSA_SUCCESS );
222
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100223 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300224 encrypt, output_len, part_size,
225 decrypt, sizeof( decrypt ), &output_len );
226 ASSERT_STATUS( status, PSA_SUCCESS );
227
228 status = memcmp( input, decrypt, sizeof( input ) );
229 ASSERT_STATUS( status, PSA_SUCCESS );
230
231exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100232 psa_destroy_key( key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300233 return( status );
234}
235
itayzafrir44b09d22018-07-12 13:06:41 +0300236static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
237{
238 enum {
239 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
240 key_bits = 256,
241 input_size = 100,
242 part_size = 10,
243 };
244 const psa_algorithm_t alg = PSA_ALG_CTR;
245
246 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200247 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100248 psa_key_handle_t key_handle = 0;
itayzafrir44b09d22018-07-12 13:06:41 +0300249 size_t output_len = 0;
250 uint8_t iv[block_size], input[input_size], encrypt[input_size],
251 decrypt[input_size];
252
253 status = psa_generate_random( input, sizeof( input ) );
254 ASSERT_STATUS( status, PSA_SUCCESS );
255
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200256 psa_set_key_usage_flags( &attributes,
257 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
258 psa_set_key_algorithm( &attributes, alg );
259 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200260 psa_set_key_bits( &attributes, key_bits );
itayzafrir44b09d22018-07-12 13:06:41 +0300261
Gilles Peskine35ef36b2019-05-16 19:42:05 +0200262 status = psa_generate_key( &attributes, &key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300263 ASSERT_STATUS( status, PSA_SUCCESS );
264
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100265 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300266 input, sizeof( input ), part_size,
267 encrypt, sizeof( encrypt ), &output_len );
268 ASSERT_STATUS( status, PSA_SUCCESS );
269
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100270 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300271 encrypt, output_len, part_size,
272 decrypt, sizeof( decrypt ), &output_len );
273 ASSERT_STATUS( status, PSA_SUCCESS );
274
275 status = memcmp( input, decrypt, sizeof( input ) );
276 ASSERT_STATUS( status, PSA_SUCCESS );
277
278exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100279 psa_destroy_key( key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300280 return( status );
281}
282
itayzafrir10366702018-07-11 13:44:41 +0300283static void cipher_examples( void )
284{
285 psa_status_t status;
286
Jaeden Amerofa30c332018-12-21 18:42:18 +0000287 printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300288 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
289 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000290 printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300291
Jaeden Amerofa30c332018-12-21 18:42:18 +0000292 printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300293 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
294 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000295 printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300296
Jaeden Amerofa30c332018-12-21 18:42:18 +0000297 printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300298 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
299 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000300 printf( "\tsuccess!\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300301}
302
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000303#if defined(MBEDTLS_CHECK_PARAMS)
304#include "mbedtls/platform_util.h"
305void mbedtls_param_failed( const char *failure_condition,
306 const char *file,
307 int line )
308{
Jaeden Amerofa30c332018-12-21 18:42:18 +0000309 printf( "%s:%i: Input param failed - %s\n",
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000310 file, line, failure_condition );
Jaeden Amerofa30c332018-12-21 18:42:18 +0000311 exit( EXIT_FAILURE );
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000312}
313#endif
314
itayzafrira3ff8a62018-07-10 10:10:21 +0300315int main( void )
316{
itayzafrir10366702018-07-11 13:44:41 +0300317 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
318 cipher_examples( );
319exit:
320 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300321 return( 0 );
322}
itayzafrir18ac3312018-07-17 09:28:11 +0300323#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
324 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */