blob: b755f09ef2eacdd3f1ef21ee7ce461fa901567d6 [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
Dave Rodgman16799db2023-11-02 19:47:20 +00003 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Bence Szépkúti700ee442020-05-26 00:33:31 +02004 */
5
itayzafrir10366702018-07-11 13:44:41 +03006#include "psa/crypto.h"
7#include <string.h>
itayzafrir10366702018-07-11 13:44:41 +03008#include <stdio.h>
Jaeden Amerodb29ab52019-02-12 16:40:27 +00009#include <stdlib.h>
itayzafrir10366702018-07-11 13:44:41 +030010
Gilles Peskine449bd832023-01-11 14:50:10 +010011#define ASSERT(predicate) \
itayzafrir10366702018-07-11 13:44:41 +030012 do \
13 { \
Gilles Peskine449bd832023-01-11 14:50:10 +010014 if (!(predicate)) \
itayzafrir10366702018-07-11 13:44:41 +030015 { \
Gilles Peskine449bd832023-01-11 14:50:10 +010016 printf("\tassertion failed at %s:%d - '%s'\r\n", \
17 __FILE__, __LINE__, #predicate); \
itayzafrir10366702018-07-11 13:44:41 +030018 goto exit; \
19 } \
Gilles Peskine449bd832023-01-11 14:50:10 +010020 } while (0)
itayzafrir10366702018-07-11 13:44:41 +030021
Gilles Peskine449bd832023-01-11 14:50:10 +010022#define ASSERT_STATUS(actual, expected) \
itayzafrir10366702018-07-11 13:44:41 +030023 do \
24 { \
Gilles Peskine449bd832023-01-11 14:50:10 +010025 if ((actual) != (expected)) \
itayzafrir10366702018-07-11 13:44:41 +030026 { \
Gilles Peskine449bd832023-01-11 14:50:10 +010027 printf("\tassertion failed at %s:%d - " \
28 "actual:%d expected:%d\r\n", __FILE__, __LINE__, \
29 (psa_status_t) actual, (psa_status_t) expected); \
itayzafrir10366702018-07-11 13:44:41 +030030 goto exit; \
31 } \
Gilles Peskine449bd832023-01-11 14:50:10 +010032 } while (0)
itayzafrir10366702018-07-11 13:44:41 +030033
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) || \
Ronald Cronadc2ff22020-09-16 16:49:27 +020036 !defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) || \
37 defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
Gilles Peskine449bd832023-01-11 14:50:10 +010038int main(void)
itayzafrir18ac3312018-07-17 09:28:11 +030039{
Gilles Peskine449bd832023-01-11 14:50:10 +010040 printf("MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or "
41 "MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR "
42 "and/or MBEDTLS_CIPHER_MODE_WITH_PADDING "
43 "not defined and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER"
44 " defined.\r\n");
45 return 0;
itayzafrir18ac3312018-07-17 09:28:11 +030046}
47#else
48
Gilles Peskine449bd832023-01-11 14:50:10 +010049static psa_status_t cipher_operation(psa_cipher_operation_t *operation,
50 const uint8_t *input,
51 size_t input_size,
52 size_t part_size,
53 uint8_t *output,
54 size_t output_size,
55 size_t *output_len)
itayzafrir10366702018-07-11 13:44:41 +030056{
57 psa_status_t status;
58 size_t bytes_to_write = 0, bytes_written = 0, len = 0;
59
60 *output_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +010061 while (bytes_written != input_size) {
62 bytes_to_write = (input_size - bytes_written > part_size ?
63 part_size :
64 input_size - bytes_written);
itayzafrir10366702018-07-11 13:44:41 +030065
Gilles Peskine449bd832023-01-11 14:50:10 +010066 status = psa_cipher_update(operation, input + bytes_written,
67 bytes_to_write, output + *output_len,
68 output_size - *output_len, &len);
69 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +030070
71 bytes_written += bytes_to_write;
72 *output_len += len;
73 }
74
Gilles Peskine449bd832023-01-11 14:50:10 +010075 status = psa_cipher_finish(operation, output + *output_len,
76 output_size - *output_len, &len);
77 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +030078 *output_len += len;
79
80exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010081 return status;
itayzafrir10366702018-07-11 13:44:41 +030082}
83
Gilles Peskine449bd832023-01-11 14:50:10 +010084static psa_status_t cipher_encrypt(psa_key_id_t key,
85 psa_algorithm_t alg,
86 uint8_t *iv,
87 size_t iv_size,
88 const uint8_t *input,
89 size_t input_size,
90 size_t part_size,
91 uint8_t *output,
92 size_t output_size,
93 size_t *output_len)
itayzafrir10366702018-07-11 13:44:41 +030094{
95 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +000096 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +030097 size_t iv_len = 0;
98
Gilles Peskine449bd832023-01-11 14:50:10 +010099 memset(&operation, 0, sizeof(operation));
100 status = psa_cipher_encrypt_setup(&operation, key, alg);
101 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 status = psa_cipher_generate_iv(&operation, iv, iv_size, &iv_len);
104 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300105
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 status = cipher_operation(&operation, input, input_size, part_size,
107 output, output_size, output_len);
108 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300109
110exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 psa_cipher_abort(&operation);
112 return status;
itayzafrir10366702018-07-11 13:44:41 +0300113}
114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115static psa_status_t cipher_decrypt(psa_key_id_t key,
116 psa_algorithm_t alg,
117 const uint8_t *iv,
118 size_t iv_size,
119 const uint8_t *input,
120 size_t input_size,
121 size_t part_size,
122 uint8_t *output,
123 size_t output_size,
124 size_t *output_len)
itayzafrir10366702018-07-11 13:44:41 +0300125{
126 psa_status_t status;
Jaeden Amerob281f742019-02-20 10:40:20 +0000127 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
itayzafrir10366702018-07-11 13:44:41 +0300128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 memset(&operation, 0, sizeof(operation));
130 status = psa_cipher_decrypt_setup(&operation, key, alg);
131 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300132
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 status = psa_cipher_set_iv(&operation, iv, iv_size);
134 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 status = cipher_operation(&operation, input, input_size, part_size,
137 output, output_size, output_len);
138 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300139
140exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 psa_cipher_abort(&operation);
142 return status;
itayzafrir10366702018-07-11 13:44:41 +0300143}
144
145static psa_status_t
Gilles Peskine449bd832023-01-11 14:50:10 +0100146cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block(void)
itayzafrir10366702018-07-11 13:44:41 +0300147{
148 enum {
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
itayzafrir10366702018-07-11 13:44:41 +0300150 key_bits = 256,
151 part_size = block_size,
152 };
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200153 const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
itayzafrir10366702018-07-11 13:44:41 +0300154
155 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200156 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronadc2ff22020-09-16 16:49:27 +0200157 psa_key_id_t key = 0;
itayzafrir10366702018-07-11 13:44:41 +0300158 size_t output_len = 0;
159 uint8_t iv[block_size];
160 uint8_t input[block_size];
161 uint8_t encrypt[block_size];
162 uint8_t decrypt[block_size];
163
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 status = psa_generate_random(input, sizeof(input));
165 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300166
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 psa_set_key_usage_flags(&attributes,
168 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
169 psa_set_key_algorithm(&attributes, alg);
170 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
171 psa_set_key_bits(&attributes, key_bits);
Gilles Peskineb0edfb52018-12-03 16:24:51 +0100172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 status = psa_generate_key(&attributes, &key);
174 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 status = cipher_encrypt(key, alg, iv, sizeof(iv),
177 input, sizeof(input), part_size,
178 encrypt, sizeof(encrypt), &output_len);
179 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 status = cipher_decrypt(key, alg, iv, sizeof(iv),
182 encrypt, output_len, part_size,
183 decrypt, sizeof(decrypt), &output_len);
184 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 status = memcmp(input, decrypt, sizeof(input));
187 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir10366702018-07-11 13:44:41 +0300188
189exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 psa_destroy_key(key);
191 return status;
itayzafrir10366702018-07-11 13:44:41 +0300192}
193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi(void)
itayzafrira2d08042018-07-12 10:27:58 +0300195{
196 enum {
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
itayzafrira2d08042018-07-12 10:27:58 +0300198 key_bits = 256,
199 input_size = 100,
200 part_size = 10,
201 };
202
Gilles Peskinedaea26f2018-08-21 14:02:45 +0200203 const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
itayzafrira2d08042018-07-12 10:27:58 +0300204
205 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200206 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronadc2ff22020-09-16 16:49:27 +0200207 psa_key_id_t key = 0;
itayzafrira2d08042018-07-12 10:27:58 +0300208 size_t output_len = 0;
209 uint8_t iv[block_size], input[input_size],
210 encrypt[input_size + block_size], decrypt[input_size + block_size];
211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 status = psa_generate_random(input, sizeof(input));
213 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrira2d08042018-07-12 10:27:58 +0300214
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 psa_set_key_usage_flags(&attributes,
216 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
217 psa_set_key_algorithm(&attributes, alg);
218 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
219 psa_set_key_bits(&attributes, key_bits);
itayzafrira2d08042018-07-12 10:27:58 +0300220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 status = psa_generate_key(&attributes, &key);
222 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrira2d08042018-07-12 10:27:58 +0300223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 status = cipher_encrypt(key, alg, iv, sizeof(iv),
225 input, sizeof(input), part_size,
226 encrypt, sizeof(encrypt), &output_len);
227 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrira2d08042018-07-12 10:27:58 +0300228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 status = cipher_decrypt(key, alg, iv, sizeof(iv),
230 encrypt, output_len, part_size,
231 decrypt, sizeof(decrypt), &output_len);
232 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrira2d08042018-07-12 10:27:58 +0300233
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 status = memcmp(input, decrypt, sizeof(input));
235 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrira2d08042018-07-12 10:27:58 +0300236
237exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 psa_destroy_key(key);
239 return status;
itayzafrira2d08042018-07-12 10:27:58 +0300240}
241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi(void)
itayzafrir44b09d22018-07-12 13:06:41 +0300243{
244 enum {
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
itayzafrir44b09d22018-07-12 13:06:41 +0300246 key_bits = 256,
247 input_size = 100,
248 part_size = 10,
249 };
250 const psa_algorithm_t alg = PSA_ALG_CTR;
251
252 psa_status_t status;
Gilles Peskinedfea0a252019-04-18 13:39:40 +0200253 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Cronadc2ff22020-09-16 16:49:27 +0200254 psa_key_id_t key = 0;
itayzafrir44b09d22018-07-12 13:06:41 +0300255 size_t output_len = 0;
256 uint8_t iv[block_size], input[input_size], encrypt[input_size],
257 decrypt[input_size];
258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 status = psa_generate_random(input, sizeof(input));
260 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir44b09d22018-07-12 13:06:41 +0300261
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 psa_set_key_usage_flags(&attributes,
263 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
264 psa_set_key_algorithm(&attributes, alg);
265 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
266 psa_set_key_bits(&attributes, key_bits);
itayzafrir44b09d22018-07-12 13:06:41 +0300267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 status = psa_generate_key(&attributes, &key);
269 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir44b09d22018-07-12 13:06:41 +0300270
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 status = cipher_encrypt(key, alg, iv, sizeof(iv),
272 input, sizeof(input), part_size,
273 encrypt, sizeof(encrypt), &output_len);
274 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir44b09d22018-07-12 13:06:41 +0300275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 status = cipher_decrypt(key, alg, iv, sizeof(iv),
277 encrypt, output_len, part_size,
278 decrypt, sizeof(decrypt), &output_len);
279 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir44b09d22018-07-12 13:06:41 +0300280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 status = memcmp(input, decrypt, sizeof(input));
282 ASSERT_STATUS(status, PSA_SUCCESS);
itayzafrir44b09d22018-07-12 13:06:41 +0300283
284exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 psa_destroy_key(key);
286 return status;
itayzafrir44b09d22018-07-12 13:06:41 +0300287}
288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289static void cipher_examples(void)
itayzafrir10366702018-07-11 13:44:41 +0300290{
291 psa_status_t status;
292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 printf("cipher encrypt/decrypt AES CBC no padding:\r\n");
294 status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block();
295 if (status == PSA_SUCCESS) {
296 printf("\tsuccess!\r\n");
297 }
itayzafrira2d08042018-07-12 10:27:58 +0300298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 printf("cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n");
300 status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi();
301 if (status == PSA_SUCCESS) {
302 printf("\tsuccess!\r\n");
303 }
itayzafrir44b09d22018-07-12 13:06:41 +0300304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 printf("cipher encrypt/decrypt AES CTR multipart:\r\n");
306 status = cipher_example_encrypt_decrypt_aes_ctr_multi();
307 if (status == PSA_SUCCESS) {
308 printf("\tsuccess!\r\n");
309 }
itayzafrir10366702018-07-11 13:44:41 +0300310}
311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312int main(void)
itayzafrira3ff8a62018-07-10 10:10:21 +0300313{
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 ASSERT(psa_crypto_init() == PSA_SUCCESS);
315 cipher_examples();
itayzafrir10366702018-07-11 13:44:41 +0300316exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 mbedtls_psa_crypto_free();
318 return 0;
itayzafrira3ff8a62018-07-10 10:10:21 +0300319}
itayzafrir18ac3312018-07-17 09:28:11 +0300320#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
321 MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */