blob: 72c41fa7940b7f26189b44d13242cfed68b05fd9 [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
itayzafrir10366702018-07-11 13:44:41 +030047/* Use key slot 1 for our cipher key. Key slot 0 is reserved as unused. */
48static const psa_key_slot_t key_slot_cipher = 1;
49
50static psa_status_t set_key_policy( psa_key_slot_t key_slot,
51 psa_key_usage_t key_usage,
52 psa_algorithm_t alg )
53{
54 psa_status_t status;
55 psa_key_policy_t policy;
56
57 psa_key_policy_init( &policy );
58 psa_key_policy_set_usage( &policy, key_usage, alg );
59 status = psa_set_key_policy( key_slot, &policy );
60 ASSERT_STATUS( status, PSA_SUCCESS );
61exit:
62 return( status );
63}
64
65static psa_status_t cipher_operation( psa_cipher_operation_t *operation,
66 const uint8_t * input,
67 size_t input_size,
68 size_t part_size,
69 uint8_t * output,
70 size_t output_size,
71 size_t *output_len )
72{
73 psa_status_t status;
74 size_t bytes_to_write = 0, bytes_written = 0, len = 0;
75
76 *output_len = 0;
77 while( bytes_written != input_size )
78 {
79 bytes_to_write = ( input_size - bytes_written > part_size ?
80 part_size :
81 input_size - bytes_written );
82
83 status = psa_cipher_update( operation, input + bytes_written,
84 bytes_to_write, output + *output_len,
85 output_size - *output_len, &len );
86 ASSERT_STATUS( status, PSA_SUCCESS );
87
88 bytes_written += bytes_to_write;
89 *output_len += len;
90 }
91
92 status = psa_cipher_finish( operation, output + *output_len,
93 output_size - *output_len, &len );
94 ASSERT_STATUS( status, PSA_SUCCESS );
95 *output_len += len;
96
97exit:
98 return( status );
99}
100
101static psa_status_t cipher_encrypt( psa_key_slot_t key_slot,
102 psa_algorithm_t alg,
103 uint8_t * iv,
104 size_t iv_size,
105 const uint8_t * input,
106 size_t input_size,
107 size_t part_size,
108 uint8_t * output,
109 size_t output_size,
110 size_t *output_len )
111{
112 psa_status_t status;
113 psa_cipher_operation_t operation;
114 size_t iv_len = 0;
115
116 memset( &operation, 0, sizeof( operation ) );
117 status = psa_cipher_encrypt_setup( &operation, key_slot, alg );
118 ASSERT_STATUS( status, PSA_SUCCESS );
119
120 status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len );
121 ASSERT_STATUS( status, PSA_SUCCESS );
122
123 status = cipher_operation( &operation, input, input_size, part_size,
124 output, output_size, output_len );
125 ASSERT_STATUS( status, PSA_SUCCESS );
126
127exit:
128 psa_cipher_abort( &operation );
129 return( status );
130}
131
132static psa_status_t cipher_decrypt( psa_key_slot_t key_slot,
133 psa_algorithm_t alg,
134 const uint8_t * iv,
135 size_t iv_size,
136 const uint8_t * input,
137 size_t input_size,
138 size_t part_size,
139 uint8_t * output,
140 size_t output_size,
141 size_t *output_len )
142{
143 psa_status_t status;
144 psa_cipher_operation_t operation;
145
146 memset( &operation, 0, sizeof( operation ) );
147 status = psa_cipher_decrypt_setup( &operation, key_slot, alg );
148 ASSERT_STATUS( status, PSA_SUCCESS );
149
150 status = psa_cipher_set_iv( &operation, iv, iv_size );
151 ASSERT_STATUS( status, PSA_SUCCESS );
152
153 status = cipher_operation( &operation, input, input_size, part_size,
154 output, output_size, output_len );
155 ASSERT_STATUS( status, PSA_SUCCESS );
156
157exit:
158 psa_cipher_abort( &operation );
159 return( status );
160}
161
162static psa_status_t
163cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
164{
165 enum {
166 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
167 key_bits = 256,
168 part_size = block_size,
169 };
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200170 const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
itayzafrir10366702018-07-11 13:44:41 +0300171
172 psa_status_t status;
173 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
182 status = set_key_policy( key_slot_cipher,
183 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
184 alg );
185 ASSERT_STATUS( status, PSA_SUCCESS );
186
187 status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
188 NULL, 0 );
189 ASSERT_STATUS( status, PSA_SUCCESS );
190
191 status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ),
192 input, sizeof( input ), part_size,
193 encrypt, sizeof( encrypt ), &output_len );
194 ASSERT_STATUS( status, PSA_SUCCESS );
195
196 status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ),
197 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:
205 psa_destroy_key( key_slot_cipher );
206 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;
221 size_t output_len = 0;
222 uint8_t iv[block_size], input[input_size],
223 encrypt[input_size + block_size], decrypt[input_size + block_size];
224
225 status = psa_generate_random( input, sizeof( input ) );
226 ASSERT_STATUS( status, PSA_SUCCESS );
227
228 status = set_key_policy( key_slot_cipher,
229 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
230 alg );
231 ASSERT_STATUS( status, PSA_SUCCESS );
232
233 status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
234 NULL, 0 );
235 ASSERT_STATUS( status, PSA_SUCCESS );
236
237 status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ),
238 input, sizeof( input ), part_size,
239 encrypt, sizeof( encrypt ), &output_len );
240 ASSERT_STATUS( status, PSA_SUCCESS );
241
242 status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ),
243 encrypt, output_len, part_size,
244 decrypt, sizeof( decrypt ), &output_len );
245 ASSERT_STATUS( status, PSA_SUCCESS );
246
247 status = memcmp( input, decrypt, sizeof( input ) );
248 ASSERT_STATUS( status, PSA_SUCCESS );
249
250exit:
251 psa_destroy_key( key_slot_cipher );
252 return( status );
253}
254
itayzafrir44b09d22018-07-12 13:06:41 +0300255static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
256{
257 enum {
258 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
259 key_bits = 256,
260 input_size = 100,
261 part_size = 10,
262 };
263 const psa_algorithm_t alg = PSA_ALG_CTR;
264
265 psa_status_t status;
266 size_t output_len = 0;
267 uint8_t iv[block_size], input[input_size], encrypt[input_size],
268 decrypt[input_size];
269
270 status = psa_generate_random( input, sizeof( input ) );
271 ASSERT_STATUS( status, PSA_SUCCESS );
272
273 status = set_key_policy( key_slot_cipher,
274 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
275 alg );
276 ASSERT_STATUS( status, PSA_SUCCESS );
277
278 status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
279 NULL, 0 );
280 ASSERT_STATUS( status, PSA_SUCCESS );
281
282 status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ),
283 input, sizeof( input ), part_size,
284 encrypt, sizeof( encrypt ), &output_len );
285 ASSERT_STATUS( status, PSA_SUCCESS );
286
287 status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ),
288 encrypt, output_len, part_size,
289 decrypt, sizeof( decrypt ), &output_len );
290 ASSERT_STATUS( status, PSA_SUCCESS );
291
292 status = memcmp( input, decrypt, sizeof( input ) );
293 ASSERT_STATUS( status, PSA_SUCCESS );
294
295exit:
296 psa_destroy_key( key_slot_cipher );
297 return( status );
298}
299
itayzafrir10366702018-07-11 13:44:41 +0300300static void cipher_examples( void )
301{
302 psa_status_t status;
303
304 mbedtls_printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
305 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
306 if( status == PSA_SUCCESS )
307 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300308
309 mbedtls_printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
310 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
311 if( status == PSA_SUCCESS )
312 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300313
314 mbedtls_printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
315 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
316 if( status == PSA_SUCCESS )
317 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300318}
319
itayzafrira3ff8a62018-07-10 10:10:21 +0300320int main( void )
321{
itayzafrir10366702018-07-11 13:44:41 +0300322 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
323 cipher_examples( );
324exit:
325 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300326 return( 0 );
327}
itayzafrir18ac3312018-07-17 09:28:11 +0300328#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
329 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */