blob: 72fa12fcbed7f6e96070077d9195ab92b0af84a0 [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 Peskine3a4f1f82019-04-26 13:49:28 +0200167 status = psa_generate_key( &attributes, &key_handle, NULL, 0 );
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 Peskined40c1fb2019-01-19 12:20:52 +0100209 status = psa_allocate_key( &key_handle );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100210 ASSERT_STATUS( status, PSA_SUCCESS );
211
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200212 psa_set_key_usage_flags( &attributes,
213 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
214 psa_set_key_algorithm( &attributes, alg );
215 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200216 psa_set_key_bits( &attributes, key_bits );
itayzafrira2d08042018-07-12 10:27:58 +0300217
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200218 status = psa_generate_key( &attributes, &key_handle, NULL, 0 );
itayzafrira2d08042018-07-12 10:27:58 +0300219 ASSERT_STATUS( status, PSA_SUCCESS );
220
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100221 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300222 input, sizeof( input ), part_size,
223 encrypt, sizeof( encrypt ), &output_len );
224 ASSERT_STATUS( status, PSA_SUCCESS );
225
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100226 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300227 encrypt, output_len, part_size,
228 decrypt, sizeof( decrypt ), &output_len );
229 ASSERT_STATUS( status, PSA_SUCCESS );
230
231 status = memcmp( input, decrypt, sizeof( input ) );
232 ASSERT_STATUS( status, PSA_SUCCESS );
233
234exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100235 psa_destroy_key( key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300236 return( status );
237}
238
itayzafrir44b09d22018-07-12 13:06:41 +0300239static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
240{
241 enum {
242 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
243 key_bits = 256,
244 input_size = 100,
245 part_size = 10,
246 };
247 const psa_algorithm_t alg = PSA_ALG_CTR;
248
249 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200250 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100251 psa_key_handle_t key_handle = 0;
itayzafrir44b09d22018-07-12 13:06:41 +0300252 size_t output_len = 0;
253 uint8_t iv[block_size], input[input_size], encrypt[input_size],
254 decrypt[input_size];
255
256 status = psa_generate_random( input, sizeof( input ) );
257 ASSERT_STATUS( status, PSA_SUCCESS );
258
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200259 psa_set_key_usage_flags( &attributes,
260 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
261 psa_set_key_algorithm( &attributes, alg );
262 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200263 psa_set_key_bits( &attributes, key_bits );
itayzafrir44b09d22018-07-12 13:06:41 +0300264
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200265 status = psa_generate_key( &attributes, &key_handle, NULL, 0 );
itayzafrir44b09d22018-07-12 13:06:41 +0300266 ASSERT_STATUS( status, PSA_SUCCESS );
267
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100268 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300269 input, sizeof( input ), part_size,
270 encrypt, sizeof( encrypt ), &output_len );
271 ASSERT_STATUS( status, PSA_SUCCESS );
272
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100273 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300274 encrypt, output_len, part_size,
275 decrypt, sizeof( decrypt ), &output_len );
276 ASSERT_STATUS( status, PSA_SUCCESS );
277
278 status = memcmp( input, decrypt, sizeof( input ) );
279 ASSERT_STATUS( status, PSA_SUCCESS );
280
281exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100282 psa_destroy_key( key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300283 return( status );
284}
285
itayzafrir10366702018-07-11 13:44:41 +0300286static void cipher_examples( void )
287{
288 psa_status_t status;
289
Jaeden Amerofa30c332018-12-21 18:42:18 +0000290 printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300291 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
292 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000293 printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300294
Jaeden Amerofa30c332018-12-21 18:42:18 +0000295 printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300296 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
297 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000298 printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300299
Jaeden Amerofa30c332018-12-21 18:42:18 +0000300 printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300301 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
302 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000303 printf( "\tsuccess!\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300304}
305
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000306#if defined(MBEDTLS_CHECK_PARAMS)
307#include "mbedtls/platform_util.h"
308void mbedtls_param_failed( const char *failure_condition,
309 const char *file,
310 int line )
311{
Jaeden Amerofa30c332018-12-21 18:42:18 +0000312 printf( "%s:%i: Input param failed - %s\n",
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000313 file, line, failure_condition );
Jaeden Amerofa30c332018-12-21 18:42:18 +0000314 exit( EXIT_FAILURE );
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000315}
316#endif
317
itayzafrira3ff8a62018-07-10 10:10:21 +0300318int main( void )
319{
itayzafrir10366702018-07-11 13:44:41 +0300320 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
321 cipher_examples( );
322exit:
323 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300324 return( 0 );
325}
itayzafrir18ac3312018-07-17 09:28:11 +0300326#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
327 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */