blob: 53b6b2ae711a9443494740835f15573f7bd7f347 [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;
52 psa_key_policy_t policy;
53
54 psa_key_policy_init( &policy );
55 psa_key_policy_set_usage( &policy, key_usage, alg );
Gilles Peskineb0edfb52018-12-03 16:24:51 +010056 status = psa_set_key_policy( key_handle, &policy );
itayzafrir10366702018-07-11 13:44:41 +030057 ASSERT_STATUS( status, PSA_SUCCESS );
58exit:
59 return( status );
60}
61
62static psa_status_t cipher_operation( psa_cipher_operation_t *operation,
63 const uint8_t * input,
64 size_t input_size,
65 size_t part_size,
66 uint8_t * output,
67 size_t output_size,
68 size_t *output_len )
69{
70 psa_status_t status;
71 size_t bytes_to_write = 0, bytes_written = 0, len = 0;
72
73 *output_len = 0;
74 while( bytes_written != input_size )
75 {
76 bytes_to_write = ( input_size - bytes_written > part_size ?
77 part_size :
78 input_size - bytes_written );
79
80 status = psa_cipher_update( operation, input + bytes_written,
81 bytes_to_write, output + *output_len,
82 output_size - *output_len, &len );
83 ASSERT_STATUS( status, PSA_SUCCESS );
84
85 bytes_written += bytes_to_write;
86 *output_len += len;
87 }
88
89 status = psa_cipher_finish( operation, output + *output_len,
90 output_size - *output_len, &len );
91 ASSERT_STATUS( status, PSA_SUCCESS );
92 *output_len += len;
93
94exit:
95 return( status );
96}
97
Gilles Peskineb0edfb52018-12-03 16:24:51 +010098static psa_status_t cipher_encrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +030099 psa_algorithm_t alg,
100 uint8_t * iv,
101 size_t iv_size,
102 const uint8_t * input,
103 size_t input_size,
104 size_t part_size,
105 uint8_t * output,
106 size_t output_size,
107 size_t *output_len )
108{
109 psa_status_t status;
110 psa_cipher_operation_t operation;
111 size_t iv_len = 0;
112
113 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100114 status = psa_cipher_encrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +0300115 ASSERT_STATUS( status, PSA_SUCCESS );
116
117 status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len );
118 ASSERT_STATUS( status, PSA_SUCCESS );
119
120 status = cipher_operation( &operation, input, input_size, part_size,
121 output, output_size, output_len );
122 ASSERT_STATUS( status, PSA_SUCCESS );
123
124exit:
125 psa_cipher_abort( &operation );
126 return( status );
127}
128
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100129static psa_status_t cipher_decrypt( psa_key_handle_t key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300130 psa_algorithm_t alg,
131 const uint8_t * iv,
132 size_t iv_size,
133 const uint8_t * input,
134 size_t input_size,
135 size_t part_size,
136 uint8_t * output,
137 size_t output_size,
138 size_t *output_len )
139{
140 psa_status_t status;
141 psa_cipher_operation_t operation;
142
143 memset( &operation, 0, sizeof( operation ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100144 status = psa_cipher_decrypt_setup( &operation, key_handle, alg );
itayzafrir10366702018-07-11 13:44:41 +0300145 ASSERT_STATUS( status, PSA_SUCCESS );
146
147 status = psa_cipher_set_iv( &operation, iv, iv_size );
148 ASSERT_STATUS( status, PSA_SUCCESS );
149
150 status = cipher_operation( &operation, input, input_size, part_size,
151 output, output_size, output_len );
152 ASSERT_STATUS( status, PSA_SUCCESS );
153
154exit:
155 psa_cipher_abort( &operation );
156 return( status );
157}
158
159static psa_status_t
160cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
161{
162 enum {
163 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
164 key_bits = 256,
165 part_size = block_size,
166 };
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200167 const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
itayzafrir10366702018-07-11 13:44:41 +0300168
169 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100170 psa_key_handle_t key_handle = 0;
itayzafrir10366702018-07-11 13:44:41 +0300171 size_t output_len = 0;
172 uint8_t iv[block_size];
173 uint8_t input[block_size];
174 uint8_t encrypt[block_size];
175 uint8_t decrypt[block_size];
176
177 status = psa_generate_random( input, sizeof( input ) );
178 ASSERT_STATUS( status, PSA_SUCCESS );
179
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100180 status = psa_allocate_key( PSA_KEY_TYPE_AES, key_bits, &key_handle );
181 ASSERT_STATUS( status, PSA_SUCCESS );
182
183 status = set_key_policy( key_handle,
itayzafrir10366702018-07-11 13:44:41 +0300184 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
185 alg );
186 ASSERT_STATUS( status, PSA_SUCCESS );
187
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100188 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrir10366702018-07-11 13:44:41 +0300189 NULL, 0 );
190 ASSERT_STATUS( status, PSA_SUCCESS );
191
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100192 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300193 input, sizeof( input ), part_size,
194 encrypt, sizeof( encrypt ), &output_len );
195 ASSERT_STATUS( status, PSA_SUCCESS );
196
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100197 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300198 encrypt, output_len, part_size,
199 decrypt, sizeof( decrypt ), &output_len );
200 ASSERT_STATUS( status, PSA_SUCCESS );
201
202 status = memcmp( input, decrypt, sizeof( input ) );
203 ASSERT_STATUS( status, PSA_SUCCESS );
204
205exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100206 psa_destroy_key( key_handle );
itayzafrir10366702018-07-11 13:44:41 +0300207 return( status );
208}
209
itayzafrira2d08042018-07-12 10:27:58 +0300210static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void )
211{
212 enum {
213 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
214 key_bits = 256,
215 input_size = 100,
216 part_size = 10,
217 };
218
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200219 const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
itayzafrira2d08042018-07-12 10:27:58 +0300220
221 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100222 psa_key_handle_t key_handle = 0;
itayzafrira2d08042018-07-12 10:27:58 +0300223 size_t output_len = 0;
224 uint8_t iv[block_size], input[input_size],
225 encrypt[input_size + block_size], decrypt[input_size + block_size];
226
227 status = psa_generate_random( input, sizeof( input ) );
228 ASSERT_STATUS( status, PSA_SUCCESS );
229
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100230 status = psa_allocate_key( PSA_KEY_TYPE_AES, key_bits, &key_handle );
231 ASSERT_STATUS( status, PSA_SUCCESS );
232
233 status = set_key_policy( key_handle,
itayzafrira2d08042018-07-12 10:27:58 +0300234 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
235 alg );
236 ASSERT_STATUS( status, PSA_SUCCESS );
237
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100238 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrira2d08042018-07-12 10:27:58 +0300239 NULL, 0 );
240 ASSERT_STATUS( status, PSA_SUCCESS );
241
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100242 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300243 input, sizeof( input ), part_size,
244 encrypt, sizeof( encrypt ), &output_len );
245 ASSERT_STATUS( status, PSA_SUCCESS );
246
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100247 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300248 encrypt, output_len, part_size,
249 decrypt, sizeof( decrypt ), &output_len );
250 ASSERT_STATUS( status, PSA_SUCCESS );
251
252 status = memcmp( input, decrypt, sizeof( input ) );
253 ASSERT_STATUS( status, PSA_SUCCESS );
254
255exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100256 psa_destroy_key( key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300257 return( status );
258}
259
itayzafrir44b09d22018-07-12 13:06:41 +0300260static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
261{
262 enum {
263 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
264 key_bits = 256,
265 input_size = 100,
266 part_size = 10,
267 };
268 const psa_algorithm_t alg = PSA_ALG_CTR;
269
270 psa_status_t status;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100271 psa_key_handle_t key_handle = 0;
itayzafrir44b09d22018-07-12 13:06:41 +0300272 size_t output_len = 0;
273 uint8_t iv[block_size], input[input_size], encrypt[input_size],
274 decrypt[input_size];
275
276 status = psa_generate_random( input, sizeof( input ) );
277 ASSERT_STATUS( status, PSA_SUCCESS );
278
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100279 status = psa_allocate_key( PSA_KEY_TYPE_AES, key_bits, &key_handle );
280 ASSERT_STATUS( status, PSA_SUCCESS );
281 status = set_key_policy( key_handle,
itayzafrir44b09d22018-07-12 13:06:41 +0300282 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
283 alg );
284 ASSERT_STATUS( status, PSA_SUCCESS );
285
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100286 status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
itayzafrir44b09d22018-07-12 13:06:41 +0300287 NULL, 0 );
288 ASSERT_STATUS( status, PSA_SUCCESS );
289
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100290 status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300291 input, sizeof( input ), part_size,
292 encrypt, sizeof( encrypt ), &output_len );
293 ASSERT_STATUS( status, PSA_SUCCESS );
294
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100295 status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300296 encrypt, output_len, part_size,
297 decrypt, sizeof( decrypt ), &output_len );
298 ASSERT_STATUS( status, PSA_SUCCESS );
299
300 status = memcmp( input, decrypt, sizeof( input ) );
301 ASSERT_STATUS( status, PSA_SUCCESS );
302
303exit:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100304 psa_destroy_key( key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300305 return( status );
306}
307
itayzafrir10366702018-07-11 13:44:41 +0300308static void cipher_examples( void )
309{
310 psa_status_t status;
311
312 mbedtls_printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
313 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
314 if( status == PSA_SUCCESS )
315 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300316
317 mbedtls_printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
318 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
319 if( status == PSA_SUCCESS )
320 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300321
322 mbedtls_printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
323 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
324 if( status == PSA_SUCCESS )
325 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300326}
327
itayzafrira3ff8a62018-07-10 10:10:21 +0300328int main( void )
329{
itayzafrir10366702018-07-11 13:44:41 +0300330 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
331 cipher_examples( );
332exit:
333 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300334 return( 0 );
335}
itayzafrir18ac3312018-07-17 09:28:11 +0300336#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
337 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */