blob: 80fe67efdd7eca0e74e00dca110ffe6ef5f35feb [file] [log] [blame]
Bence Szépkúti700ee442020-05-26 00:33:31 +02001/*
Bence Szépkúti1e148272020-08-07 13:07:28 +02002 * Copyright The Mbed TLS Contributors
Bence Szépkúti86974652020-06-15 11:59:37 +02003 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Bence Szépkúti700ee442020-05-26 00:33:31 +020016 */
17
itayzafrir10366702018-07-11 13:44:41 +030018#include "psa/crypto.h"
19#include <string.h>
itayzafrir10366702018-07-11 13:44:41 +030020#include <stdio.h>
Jaeden Amerodb29ab52019-02-12 16:40:27 +000021#include <stdlib.h>
itayzafrir10366702018-07-11 13:44:41 +030022
23#define ASSERT( predicate ) \
24 do \
25 { \
26 if( ! ( predicate ) ) \
27 { \
Jaeden Amerofa30c332018-12-21 18:42:18 +000028 printf( "\tassertion failed at %s:%d - '%s'\r\n", \
29 __FILE__, __LINE__, #predicate); \
itayzafrir10366702018-07-11 13:44:41 +030030 goto exit; \
31 } \
32 } while ( 0 )
33
34#define ASSERT_STATUS( actual, expected ) \
35 do \
36 { \
37 if( ( actual ) != ( expected ) ) \
38 { \
Jaeden Amerofa30c332018-12-21 18:42:18 +000039 printf( "\tassertion failed at %s:%d - " \
40 "actual:%d expected:%d\r\n", __FILE__, __LINE__, \
itayzafrir10366702018-07-11 13:44:41 +030041 (psa_status_t) actual, (psa_status_t) expected ); \
42 goto exit; \
43 } \
44 } while ( 0 )
45
itayzafrir18ac3312018-07-17 09:28:11 +030046#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_AES_C) || \
47 !defined(MBEDTLS_CIPHER_MODE_CBC) || !defined(MBEDTLS_CIPHER_MODE_CTR) || \
Ronald Cronadc2ff22020-09-16 16:49:27 +020048 !defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) || \
49 defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
itayzafrir18ac3312018-07-17 09:28:11 +030050int main( void )
51{
Jaeden Amerofa30c332018-12-21 18:42:18 +000052 printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or "
53 "MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR "
54 "and/or MBEDTLS_CIPHER_MODE_WITH_PADDING "
Ronald Cronadc2ff22020-09-16 16:49:27 +020055 "not defined and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER"
56 " defined.\r\n" );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +020057 return 0 ;
itayzafrir18ac3312018-07-17 09:28:11 +030058}
59#else
60
itayzafrir10366702018-07-11 13:44:41 +030061static psa_status_t cipher_operation( psa_cipher_operation_t *operation,
62 const uint8_t * input,
63 size_t input_size,
64 size_t part_size,
65 uint8_t * output,
66 size_t output_size,
67 size_t *output_len )
68{
69 psa_status_t status;
70 size_t bytes_to_write = 0, bytes_written = 0, len = 0;
71
72 *output_len = 0;
73 while( bytes_written != input_size )
74 {
75 bytes_to_write = ( input_size - bytes_written > part_size ?
76 part_size :
77 input_size - bytes_written );
78
79 status = psa_cipher_update( operation, input + bytes_written,
80 bytes_to_write, output + *output_len,
81 output_size - *output_len, &len );
82 ASSERT_STATUS( status, PSA_SUCCESS );
83
84 bytes_written += bytes_to_write;
85 *output_len += len;
86 }
87
88 status = psa_cipher_finish( operation, output + *output_len,
89 output_size - *output_len, &len );
90 ASSERT_STATUS( status, PSA_SUCCESS );
91 *output_len += len;
92
93exit:
Mateusz Starzyke36f5b12021-07-22 16:43:35 +020094 return status ;
itayzafrir10366702018-07-11 13:44:41 +030095}
96
Ronald Cronadc2ff22020-09-16 16:49:27 +020097static psa_status_t cipher_encrypt( psa_key_id_t key,
itayzafrir10366702018-07-11 13:44:41 +030098 psa_algorithm_t alg,
99 uint8_t * iv,
100 size_t iv_size,
101 const uint8_t * input,
102 size_t input_size,
103 size_t part_size,
104 uint8_t * output,
105 size_t output_size,
106 size_t *output_len )
107{
108 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +0000109 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +0300110 size_t iv_len = 0;
111
112 memset( &operation, 0, sizeof( operation ) );
Ronald Cronadc2ff22020-09-16 16:49:27 +0200113 status = psa_cipher_encrypt_setup( &operation, key, alg );
itayzafrir10366702018-07-11 13:44:41 +0300114 ASSERT_STATUS( status, PSA_SUCCESS );
115
116 status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len );
117 ASSERT_STATUS( status, PSA_SUCCESS );
118
119 status = cipher_operation( &operation, input, input_size, part_size,
120 output, output_size, output_len );
121 ASSERT_STATUS( status, PSA_SUCCESS );
122
123exit:
124 psa_cipher_abort( &operation );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200125 return status ;
itayzafrir10366702018-07-11 13:44:41 +0300126}
127
Ronald Cronadc2ff22020-09-16 16:49:27 +0200128static psa_status_t cipher_decrypt( psa_key_id_t key,
itayzafrir10366702018-07-11 13:44:41 +0300129 psa_algorithm_t alg,
130 const uint8_t * iv,
131 size_t iv_size,
132 const uint8_t * input,
133 size_t input_size,
134 size_t part_size,
135 uint8_t * output,
136 size_t output_size,
137 size_t *output_len )
138{
139 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +0000140 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +0300141
142 memset( &operation, 0, sizeof( operation ) );
Ronald Cronadc2ff22020-09-16 16:49:27 +0200143 status = psa_cipher_decrypt_setup( &operation, key, alg );
itayzafrir10366702018-07-11 13:44:41 +0300144 ASSERT_STATUS( status, PSA_SUCCESS );
145
146 status = psa_cipher_set_iv( &operation, iv, iv_size );
147 ASSERT_STATUS( status, PSA_SUCCESS );
148
149 status = cipher_operation( &operation, input, input_size, part_size,
150 output, output_size, output_len );
151 ASSERT_STATUS( status, PSA_SUCCESS );
152
153exit:
154 psa_cipher_abort( &operation );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200155 return status ;
itayzafrir10366702018-07-11 13:44:41 +0300156}
157
158static psa_status_t
159cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
160{
161 enum {
gabor-mezei-armcbcec212020-12-18 14:23:51 +0100162 block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( PSA_KEY_TYPE_AES ),
itayzafrir10366702018-07-11 13:44:41 +0300163 key_bits = 256,
164 part_size = block_size,
165 };
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200166 const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
itayzafrir10366702018-07-11 13:44:41 +0300167
168 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200169 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronadc2ff22020-09-16 16:49:27 +0200170 psa_key_id_t key = 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 Peskinedfea0a252019-04-18 13:39:40 +0200180 psa_set_key_usage_flags( &attributes,
181 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
182 psa_set_key_algorithm( &attributes, alg );
183 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200184 psa_set_key_bits( &attributes, key_bits );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100185
Ronald Cronadc2ff22020-09-16 16:49:27 +0200186 status = psa_generate_key( &attributes, &key );
itayzafrir10366702018-07-11 13:44:41 +0300187 ASSERT_STATUS( status, PSA_SUCCESS );
188
Ronald Cronadc2ff22020-09-16 16:49:27 +0200189 status = cipher_encrypt( key, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300190 input, sizeof( input ), part_size,
191 encrypt, sizeof( encrypt ), &output_len );
192 ASSERT_STATUS( status, PSA_SUCCESS );
193
Ronald Cronadc2ff22020-09-16 16:49:27 +0200194 status = cipher_decrypt( key, alg, iv, sizeof( iv ),
itayzafrir10366702018-07-11 13:44:41 +0300195 encrypt, output_len, part_size,
196 decrypt, sizeof( decrypt ), &output_len );
197 ASSERT_STATUS( status, PSA_SUCCESS );
198
199 status = memcmp( input, decrypt, sizeof( input ) );
200 ASSERT_STATUS( status, PSA_SUCCESS );
201
202exit:
Ronald Cronadc2ff22020-09-16 16:49:27 +0200203 psa_destroy_key( key );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200204 return status ;
itayzafrir10366702018-07-11 13:44:41 +0300205}
206
itayzafrira2d08042018-07-12 10:27:58 +0300207static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void )
208{
209 enum {
gabor-mezei-armcbcec212020-12-18 14:23:51 +0100210 block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( PSA_KEY_TYPE_AES ),
itayzafrira2d08042018-07-12 10:27:58 +0300211 key_bits = 256,
212 input_size = 100,
213 part_size = 10,
214 };
215
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200216 const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
itayzafrira2d08042018-07-12 10:27:58 +0300217
218 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200219 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronadc2ff22020-09-16 16:49:27 +0200220 psa_key_id_t key = 0;
itayzafrira2d08042018-07-12 10:27:58 +0300221 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
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200228 psa_set_key_usage_flags( &attributes,
229 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
230 psa_set_key_algorithm( &attributes, alg );
231 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200232 psa_set_key_bits( &attributes, key_bits );
itayzafrira2d08042018-07-12 10:27:58 +0300233
Ronald Cronadc2ff22020-09-16 16:49:27 +0200234 status = psa_generate_key( &attributes, &key );
itayzafrira2d08042018-07-12 10:27:58 +0300235 ASSERT_STATUS( status, PSA_SUCCESS );
236
Ronald Cronadc2ff22020-09-16 16:49:27 +0200237 status = cipher_encrypt( key, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300238 input, sizeof( input ), part_size,
239 encrypt, sizeof( encrypt ), &output_len );
240 ASSERT_STATUS( status, PSA_SUCCESS );
241
Ronald Cronadc2ff22020-09-16 16:49:27 +0200242 status = cipher_decrypt( key, alg, iv, sizeof( iv ),
itayzafrira2d08042018-07-12 10:27:58 +0300243 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:
Ronald Cronadc2ff22020-09-16 16:49:27 +0200251 psa_destroy_key( key );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200252 return status ;
itayzafrira2d08042018-07-12 10:27:58 +0300253}
254
itayzafrir44b09d22018-07-12 13:06:41 +0300255static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
256{
257 enum {
gabor-mezei-armcbcec212020-12-18 14:23:51 +0100258 block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( PSA_KEY_TYPE_AES ),
itayzafrir44b09d22018-07-12 13:06:41 +0300259 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;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200266 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronadc2ff22020-09-16 16:49:27 +0200267 psa_key_id_t key = 0;
itayzafrir44b09d22018-07-12 13:06:41 +0300268 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
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200275 psa_set_key_usage_flags( &attributes,
276 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
277 psa_set_key_algorithm( &attributes, alg );
278 psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
Gilles Peskine3a4f1f82019-04-26 13:49:28 +0200279 psa_set_key_bits( &attributes, key_bits );
itayzafrir44b09d22018-07-12 13:06:41 +0300280
Ronald Cronadc2ff22020-09-16 16:49:27 +0200281 status = psa_generate_key( &attributes, &key );
itayzafrir44b09d22018-07-12 13:06:41 +0300282 ASSERT_STATUS( status, PSA_SUCCESS );
283
Ronald Cronadc2ff22020-09-16 16:49:27 +0200284 status = cipher_encrypt( key, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300285 input, sizeof( input ), part_size,
286 encrypt, sizeof( encrypt ), &output_len );
287 ASSERT_STATUS( status, PSA_SUCCESS );
288
Ronald Cronadc2ff22020-09-16 16:49:27 +0200289 status = cipher_decrypt( key, alg, iv, sizeof( iv ),
itayzafrir44b09d22018-07-12 13:06:41 +0300290 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:
Ronald Cronadc2ff22020-09-16 16:49:27 +0200298 psa_destroy_key( key );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200299 return status ;
itayzafrir44b09d22018-07-12 13:06:41 +0300300}
301
itayzafrir10366702018-07-11 13:44:41 +0300302static void cipher_examples( void )
303{
304 psa_status_t status;
305
Jaeden Amerofa30c332018-12-21 18:42:18 +0000306 printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" );
itayzafrir10366702018-07-11 13:44:41 +0300307 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( );
308 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000309 printf( "\tsuccess!\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300310
Jaeden Amerofa30c332018-12-21 18:42:18 +0000311 printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" );
itayzafrira2d08042018-07-12 10:27:58 +0300312 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( );
313 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000314 printf( "\tsuccess!\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300315
Jaeden Amerofa30c332018-12-21 18:42:18 +0000316 printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" );
itayzafrir44b09d22018-07-12 13:06:41 +0300317 status = cipher_example_encrypt_decrypt_aes_ctr_multi( );
318 if( status == PSA_SUCCESS )
Jaeden Amerofa30c332018-12-21 18:42:18 +0000319 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( );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200328 return 0 ;
itayzafrira3ff8a62018-07-10 10:10:21 +0300329}
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 */