blob: e8b64f19a44b33cce29112f31c4a3906b64e6a2b [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 };
170 const psa_algorithm_t alg = PSA_ALG_CBC_BASE |
171 PSA_ALG_BLOCK_CIPHER_PAD_NONE;
172
173 psa_status_t status;
174 size_t output_len = 0;
175 uint8_t iv[block_size];
176 uint8_t input[block_size];
177 uint8_t encrypt[block_size];
178 uint8_t decrypt[block_size];
179
180 status = psa_generate_random( input, sizeof( input ) );
181 ASSERT_STATUS( status, PSA_SUCCESS );
182
183 status = set_key_policy( key_slot_cipher,
184 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
185 alg );
186 ASSERT_STATUS( status, PSA_SUCCESS );
187
188 status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
189 NULL, 0 );
190 ASSERT_STATUS( status, PSA_SUCCESS );
191
192 status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ),
193 input, sizeof( input ), part_size,
194 encrypt, sizeof( encrypt ), &output_len );
195 ASSERT_STATUS( status, PSA_SUCCESS );
196
197 status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ),
198 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:
206 psa_destroy_key( key_slot_cipher );
207 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
219 const psa_algorithm_t alg = PSA_ALG_CBC_BASE |
220 PSA_ALG_BLOCK_CIPHER_PAD_PKCS7;
221
222 psa_status_t status;
223 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
230 status = set_key_policy( key_slot_cipher,
231 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
232 alg );
233 ASSERT_STATUS( status, PSA_SUCCESS );
234
235 status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
236 NULL, 0 );
237 ASSERT_STATUS( status, PSA_SUCCESS );
238
239 status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ),
240 input, sizeof( input ), part_size,
241 encrypt, sizeof( encrypt ), &output_len );
242 ASSERT_STATUS( status, PSA_SUCCESS );
243
244 status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ),
245 encrypt, output_len, part_size,
246 decrypt, sizeof( decrypt ), &output_len );
247 ASSERT_STATUS( status, PSA_SUCCESS );
248
249 status = memcmp( input, decrypt, sizeof( input ) );
250 ASSERT_STATUS( status, PSA_SUCCESS );
251
252exit:
253 psa_destroy_key( key_slot_cipher );
254 return( status );
255}
256
itayzafrir44b09d22018-07-12 13:06:41 +0300257static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
258{
259 enum {
260 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
261 key_bits = 256,
262 input_size = 100,
263 part_size = 10,
264 };
265 const psa_algorithm_t alg = PSA_ALG_CTR;
266
267 psa_status_t status;
268 size_t output_len = 0;
269 uint8_t iv[block_size], input[input_size], encrypt[input_size],
270 decrypt[input_size];
271
272 status = psa_generate_random( input, sizeof( input ) );
273 ASSERT_STATUS( status, PSA_SUCCESS );
274
275 status = set_key_policy( key_slot_cipher,
276 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
277 alg );
278 ASSERT_STATUS( status, PSA_SUCCESS );
279
280 status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
281 NULL, 0 );
282 ASSERT_STATUS( status, PSA_SUCCESS );
283
284 status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ),
285 input, sizeof( input ), part_size,
286 encrypt, sizeof( encrypt ), &output_len );
287 ASSERT_STATUS( status, PSA_SUCCESS );
288
289 status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ),
290 encrypt, output_len, part_size,
291 decrypt, sizeof( decrypt ), &output_len );
292 ASSERT_STATUS( status, PSA_SUCCESS );
293
294 status = memcmp( input, decrypt, sizeof( input ) );
295 ASSERT_STATUS( status, PSA_SUCCESS );
296
297exit:
298 psa_destroy_key( key_slot_cipher );
299 return( status );
300}
301
itayzafrir10366702018-07-11 13:44:41 +0300302static void cipher_examples( void )
303{
304 psa_status_t status;
305
306 mbedtls_printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
307 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
308 if( status == PSA_SUCCESS )
309 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300310
311 mbedtls_printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
312 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
313 if( status == PSA_SUCCESS )
314 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300315
316 mbedtls_printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
317 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
318 if( status == PSA_SUCCESS )
319 mbedtls_printf( "\tsuccess!\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300320}
321
itayzafrira3ff8a62018-07-10 10:10:21 +0300322int main( void )
323{
itayzafrir10366702018-07-11 13:44:41 +0300324 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
325 cipher_examples( );
326exit:
327 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300328 return( 0 );
329}
itayzafrir18ac3312018-07-17 09:28:11 +0300330#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
331 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */