Skip to content

Commit c099695

Browse files
author
itayzafrir
committed
Add mbed-crypto examples
1 parent e61a708 commit c099695

File tree

1 file changed

+349
-0
lines changed

1 file changed

+349
-0
lines changed

main.cpp

Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
/*
2+
* Copyright (c) 2018, Arm Limited and affiliates
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may 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,
13+
* WITHOUT 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.
16+
*/
17+
18+
#include "psa/crypto.h"
19+
#include <string.h>
20+
#include <inttypes.h>
21+
22+
#if defined(MBEDTLS_PLATFORM_C)
23+
#include "mbedtls/platform.h"
24+
#else
25+
#include <stdio.h>
26+
#define mbedtls_printf printf
27+
#endif
28+
29+
#define ASSERT(predicate) \
30+
do \
31+
{ \
32+
if(!(predicate)) \
33+
{ \
34+
mbedtls_printf( "\tassertion failed at %s:%d - '%s'\r\n", \
35+
__FILE__, __LINE__, #predicate); \
36+
goto exit; \
37+
} \
38+
} while (0)
39+
40+
#define ASSERT_STATUS(actual, expected) \
41+
do \
42+
{ \
43+
if((actual) != (expected)) \
44+
{ \
45+
mbedtls_printf( "\tassertion failed at %s:%d - " \
46+
"actual:%" PRId32 "expected:%" PRId32 "\r\n", \
47+
__FILE__, __LINE__, \
48+
(psa_status_t) actual, (psa_status_t) expected ); \
49+
goto exit; \
50+
} \
51+
} while (0)
52+
53+
#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_AES_C) || \
54+
!defined(MBEDTLS_CIPHER_MODE_CBC) || !defined(MBEDTLS_CIPHER_MODE_CTR) || \
55+
!defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
56+
int main(void)
57+
{
58+
mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or "
59+
"MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR "
60+
"and/or MBEDTLS_CIPHER_MODE_WITH_PADDING "
61+
"not defined.\r\n");
62+
return 0;
63+
}
64+
#else
65+
66+
/* Use key slot 1 for our cipher key. Key slot 0 is reserved as unused. */
67+
static const psa_key_slot_t key_slot_cipher = 1;
68+
69+
static psa_status_t set_key_policy(psa_key_slot_t key_slot,
70+
psa_key_usage_t key_usage,
71+
psa_algorithm_t alg)
72+
{
73+
psa_status_t status;
74+
psa_key_policy_t policy;
75+
76+
psa_key_policy_init(&policy);
77+
psa_key_policy_set_usage(&policy, key_usage, alg);
78+
status = psa_set_key_policy(key_slot, &policy);
79+
ASSERT_STATUS(status, PSA_SUCCESS);
80+
exit:
81+
return status;
82+
}
83+
84+
static psa_status_t cipher_operation(psa_cipher_operation_t *operation,
85+
const uint8_t *input,
86+
size_t input_size,
87+
size_t part_size,
88+
uint8_t *output,
89+
size_t output_size,
90+
size_t *output_len)
91+
{
92+
psa_status_t status;
93+
size_t bytes_to_write = 0, bytes_written = 0, len = 0;
94+
95+
*output_len = 0;
96+
while (bytes_written != input_size) {
97+
bytes_to_write = (input_size - bytes_written > part_size ?
98+
part_size :
99+
input_size - bytes_written);
100+
101+
status = psa_cipher_update(operation, input + bytes_written,
102+
bytes_to_write, output + *output_len,
103+
output_size - *output_len, &len);
104+
ASSERT_STATUS(status, PSA_SUCCESS);
105+
106+
bytes_written += bytes_to_write;
107+
*output_len += len;
108+
}
109+
110+
status = psa_cipher_finish(operation, output + *output_len,
111+
output_size - *output_len, &len);
112+
ASSERT_STATUS(status, PSA_SUCCESS);
113+
*output_len += len;
114+
115+
exit:
116+
return status;
117+
}
118+
119+
static psa_status_t cipher_encrypt(psa_key_slot_t key_slot,
120+
psa_algorithm_t alg,
121+
uint8_t *iv,
122+
size_t iv_size,
123+
const uint8_t *input,
124+
size_t input_size,
125+
size_t part_size,
126+
uint8_t *output,
127+
size_t output_size,
128+
size_t *output_len)
129+
{
130+
psa_status_t status;
131+
psa_cipher_operation_t operation;
132+
size_t iv_len = 0;
133+
134+
memset(&operation, 0, sizeof(operation));
135+
status = psa_cipher_encrypt_setup(&operation, key_slot, alg);
136+
ASSERT_STATUS(status, PSA_SUCCESS);
137+
138+
status = psa_cipher_generate_iv(&operation, iv, iv_size, &iv_len);
139+
ASSERT_STATUS(status, PSA_SUCCESS);
140+
141+
status = cipher_operation(&operation, input, input_size, part_size,
142+
output, output_size, output_len);
143+
ASSERT_STATUS(status, PSA_SUCCESS);
144+
145+
exit:
146+
psa_cipher_abort(&operation);
147+
return status;
148+
}
149+
150+
static psa_status_t cipher_decrypt(psa_key_slot_t key_slot,
151+
psa_algorithm_t alg,
152+
const uint8_t *iv,
153+
size_t iv_size,
154+
const uint8_t *input,
155+
size_t input_size,
156+
size_t part_size,
157+
uint8_t *output,
158+
size_t output_size,
159+
size_t *output_len)
160+
{
161+
psa_status_t status;
162+
psa_cipher_operation_t operation;
163+
164+
memset(&operation, 0, sizeof(operation));
165+
status = psa_cipher_decrypt_setup(&operation, key_slot, alg);
166+
ASSERT_STATUS(status, PSA_SUCCESS);
167+
168+
status = psa_cipher_set_iv(&operation, iv, iv_size);
169+
ASSERT_STATUS(status, PSA_SUCCESS);
170+
171+
status = cipher_operation(&operation, input, input_size, part_size,
172+
output, output_size, output_len);
173+
ASSERT_STATUS(status, PSA_SUCCESS);
174+
175+
exit:
176+
psa_cipher_abort(&operation);
177+
return status;
178+
}
179+
180+
static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block(void)
181+
{
182+
enum {
183+
block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES),
184+
key_bits = 256,
185+
part_size = block_size,
186+
};
187+
const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
188+
189+
psa_status_t status;
190+
size_t output_len = 0;
191+
uint8_t iv[block_size];
192+
uint8_t input[block_size];
193+
uint8_t encrypt[block_size];
194+
uint8_t decrypt[block_size];
195+
196+
status = psa_generate_random(input, sizeof(input));
197+
ASSERT_STATUS(status, PSA_SUCCESS);
198+
199+
status = set_key_policy(key_slot_cipher,
200+
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
201+
alg);
202+
ASSERT_STATUS(status, PSA_SUCCESS);
203+
204+
status = psa_generate_key(key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
205+
NULL, 0);
206+
ASSERT_STATUS(status, PSA_SUCCESS);
207+
208+
status = cipher_encrypt(key_slot_cipher, alg, iv, sizeof(iv),
209+
input, sizeof(input), part_size,
210+
encrypt, sizeof(encrypt), &output_len);
211+
ASSERT_STATUS(status, PSA_SUCCESS);
212+
213+
status = cipher_decrypt(key_slot_cipher, alg, iv, sizeof(iv),
214+
encrypt, output_len, part_size,
215+
decrypt, sizeof(decrypt), &output_len);
216+
ASSERT_STATUS(status, PSA_SUCCESS);
217+
218+
status = memcmp(input, decrypt, sizeof(input));
219+
ASSERT_STATUS(status, PSA_SUCCESS);
220+
221+
exit:
222+
psa_destroy_key(key_slot_cipher);
223+
return status;
224+
}
225+
226+
static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi(void)
227+
{
228+
enum {
229+
block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES),
230+
key_bits = 256,
231+
input_size = 100,
232+
part_size = 10,
233+
};
234+
235+
const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
236+
237+
psa_status_t status;
238+
size_t output_len = 0;
239+
uint8_t iv[block_size], input[input_size],
240+
encrypt[input_size + block_size], decrypt[input_size + block_size];
241+
242+
status = psa_generate_random(input, sizeof(input));
243+
ASSERT_STATUS(status, PSA_SUCCESS);
244+
245+
status = set_key_policy(key_slot_cipher,
246+
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
247+
alg);
248+
ASSERT_STATUS(status, PSA_SUCCESS);
249+
250+
status = psa_generate_key(key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
251+
NULL, 0);
252+
ASSERT_STATUS(status, PSA_SUCCESS);
253+
254+
status = cipher_encrypt(key_slot_cipher, alg, iv, sizeof(iv),
255+
input, sizeof(input), part_size,
256+
encrypt, sizeof(encrypt), &output_len);
257+
ASSERT_STATUS(status, PSA_SUCCESS);
258+
259+
status = cipher_decrypt(key_slot_cipher, alg, iv, sizeof(iv),
260+
encrypt, output_len, part_size,
261+
decrypt, sizeof(decrypt), &output_len);
262+
ASSERT_STATUS(status, PSA_SUCCESS);
263+
264+
status = memcmp(input, decrypt, sizeof(input));
265+
ASSERT_STATUS(status, PSA_SUCCESS);
266+
267+
exit:
268+
psa_destroy_key(key_slot_cipher);
269+
return status;
270+
}
271+
272+
static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi(void)
273+
{
274+
enum {
275+
block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES),
276+
key_bits = 256,
277+
input_size = 100,
278+
part_size = 10,
279+
};
280+
const psa_algorithm_t alg = PSA_ALG_CTR;
281+
282+
psa_status_t status;
283+
size_t output_len = 0;
284+
uint8_t iv[block_size], input[input_size], encrypt[input_size],
285+
decrypt[input_size];
286+
287+
status = psa_generate_random(input, sizeof(input));
288+
ASSERT_STATUS(status, PSA_SUCCESS);
289+
290+
status = set_key_policy(key_slot_cipher,
291+
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
292+
alg);
293+
ASSERT_STATUS(status, PSA_SUCCESS);
294+
295+
status = psa_generate_key(key_slot_cipher, PSA_KEY_TYPE_AES, key_bits,
296+
NULL, 0);
297+
ASSERT_STATUS(status, PSA_SUCCESS);
298+
299+
status = cipher_encrypt(key_slot_cipher, alg, iv, sizeof(iv),
300+
input, sizeof(input), part_size,
301+
encrypt, sizeof(encrypt), &output_len);
302+
ASSERT_STATUS(status, PSA_SUCCESS);
303+
304+
status = cipher_decrypt(key_slot_cipher, alg, iv, sizeof(iv),
305+
encrypt, output_len, part_size,
306+
decrypt, sizeof(decrypt), &output_len);
307+
ASSERT_STATUS(status, PSA_SUCCESS);
308+
309+
status = memcmp(input, decrypt, sizeof(input));
310+
ASSERT_STATUS(status, PSA_SUCCESS);
311+
312+
exit:
313+
psa_destroy_key(key_slot_cipher);
314+
return status;
315+
}
316+
317+
static void cipher_examples(void)
318+
{
319+
psa_status_t status;
320+
321+
mbedtls_printf("cipher encrypt/decrypt AES CBC no padding:\r\n");
322+
status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block();
323+
if (status == PSA_SUCCESS) {
324+
mbedtls_printf("\tsuccess!\r\n");
325+
}
326+
327+
mbedtls_printf("cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n");
328+
status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi();
329+
if (status == PSA_SUCCESS) {
330+
mbedtls_printf("\tsuccess!\r\n");
331+
}
332+
333+
mbedtls_printf("cipher encrypt/decrypt AES CTR multipart:\r\n");
334+
status = cipher_example_encrypt_decrypt_aes_ctr_multi();
335+
if (status == PSA_SUCCESS) {
336+
mbedtls_printf("\tsuccess!\r\n");
337+
}
338+
}
339+
340+
int main(void)
341+
{
342+
ASSERT(psa_crypto_init() == PSA_SUCCESS);
343+
cipher_examples();
344+
exit:
345+
mbedtls_psa_crypto_free();
346+
return 0;
347+
}
348+
#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC &&
349+
MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */

0 commit comments

Comments
 (0)