blob: 97beb0eb4bd1072a8e458757a0349157ff459370 [file] [log] [blame]
Bence Szépkúti700ee442020-05-26 00:33:31 +02001/*
2 * Copyright (C) 2018-2019, ARM Limited, All Rights Reserved
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 * This file is part of mbed TLS (https://tls.mbed.org)
18 */
19
itayzafrir10366702018-07-11 13:44:41 +030020#include "psa/crypto.h"
21#include <string.h>
itayzafrir10366702018-07-11 13:44:41 +030022#include <stdio.h>
Jaeden Amerodb29ab52019-02-12 16:40:27 +000023#include <stdlib.h>
itayzafrir10366702018-07-11 13:44:41 +030024
25#define ASSERT( predicate ) \
26 do \
27 { \
28 if( ! ( predicate ) ) \
29 { \
Jaeden Amerofa30c332018-12-21 18:42:18 +000030 printf( "\tassertion failed at %s:%d - '%s'\r\n", \
31 __FILE__, __LINE__, #predicate); \
itayzafrir10366702018-07-11 13:44:41 +030032 goto exit; \
33 } \
34 } while ( 0 )
35
36#define ASSERT_STATUS( actual, expected ) \
37 do \
38 { \
39 if( ( actual ) != ( expected ) ) \
40 { \
Jaeden Amerofa30c332018-12-21 18:42:18 +000041 printf( "\tassertion failed at %s:%d - " \
42 "actual:%d expected:%d\r\n", __FILE__, __LINE__, \
itayzafrir10366702018-07-11 13:44:41 +030043 (psa_status_t) actual, (psa_status_t) expected ); \
44 goto exit; \
45 } \
46 } while ( 0 )
47
itayzafrir18ac3312018-07-17 09:28:11 +030048#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_AES_C) || \
49 !defined(MBEDTLS_CIPHER_MODE_CBC) || !defined(MBEDTLS_CIPHER_MODE_CTR) || \
50 !defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
51int main( void )
52{
Jaeden Amerofa30c332018-12-21 18:42:18 +000053 printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or "
54 "MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR "
55 "and/or MBEDTLS_CIPHER_MODE_WITH_PADDING "
56 "not defined.\r\n" );
itayzafrir18ac3312018-07-17 09:28:11 +030057 return( 0 );
58}
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:
94 return( status );
95}
96
Gilles Peskineb0edfb52018-12-03 16:24:51 +010097static psa_status_t cipher_encrypt( psa_key_handle_t key_handle,
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 ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100113 status = psa_cipher_encrypt_setup( &operation, key_handle, 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 );
125 return( status );
126}
127
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100128static psa_status_t cipher_decrypt( psa_key_handle_t key_handle,
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 ) );
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100143 status = psa_cipher_decrypt_setup( &operation, key_handle, 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 );
155 return( status );
156}
157
158static psa_status_t
159cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
160{
161 enum {
162 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
163 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;
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 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
Gilles Peskine35ef36b2019-05-16 19:42:05 +0200186 status = psa_generate_key( &attributes, &key_handle );
itayzafrir10366702018-07-11 13:44:41 +0300187 ASSERT_STATUS( status, PSA_SUCCESS );
188
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100189 status = cipher_encrypt( key_handle, 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
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100194 status = cipher_decrypt( key_handle, 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:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100203 psa_destroy_key( key_handle );
itayzafrir10366702018-07-11 13:44:41 +0300204 return( status );
205}
206
itayzafrira2d08042018-07-12 10:27:58 +0300207static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void )
208{
209 enum {
210 block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
211 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;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100220 psa_key_handle_t key_handle = 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
Gilles Peskine35ef36b2019-05-16 19:42:05 +0200234 status = psa_generate_key( &attributes, &key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300235 ASSERT_STATUS( status, PSA_SUCCESS );
236
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100237 status = cipher_encrypt( key_handle, 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
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100242 status = cipher_decrypt( key_handle, 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:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100251 psa_destroy_key( key_handle );
itayzafrira2d08042018-07-12 10:27:58 +0300252 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;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200266 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100267 psa_key_handle_t key_handle = 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
Gilles Peskine35ef36b2019-05-16 19:42:05 +0200281 status = psa_generate_key( &attributes, &key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300282 ASSERT_STATUS( status, PSA_SUCCESS );
283
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100284 status = cipher_encrypt( key_handle, 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
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100289 status = cipher_decrypt( key_handle, 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:
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100298 psa_destroy_key( key_handle );
itayzafrir44b09d22018-07-12 13:06:41 +0300299 return( status );
300}
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
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000322#if defined(MBEDTLS_CHECK_PARAMS)
323#include "mbedtls/platform_util.h"
324void mbedtls_param_failed( const char *failure_condition,
325 const char *file,
326 int line )
327{
Jaeden Amerofa30c332018-12-21 18:42:18 +0000328 printf( "%s:%i: Input param failed - %s\n",
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000329 file, line, failure_condition );
Jaeden Amerofa30c332018-12-21 18:42:18 +0000330 exit( EXIT_FAILURE );
Jaeden Amero44a59ab2019-02-11 13:24:47 +0000331}
332#endif
333
itayzafrira3ff8a62018-07-10 10:10:21 +0300334int main( void )
335{
itayzafrir10366702018-07-11 13:44:41 +0300336 ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
337 cipher_examples( );
338exit:
339 mbedtls_psa_crypto_free( );
itayzafrira3ff8a62018-07-10 10:10:21 +0300340 return( 0 );
341}
itayzafrir18ac3312018-07-17 09:28:11 +0300342#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
343 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */