Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
cx_cipher.c
Go to the documentation of this file.
1/* @BANNER@ */
2
3#include "cx_cipher.h"
4#include "os_math.h"
5#include "os_utils.h"
6
7#include <stddef.h>
8#include <string.h>
9
10#define CX_MAX_BLOCK_SIZE 16
11
12static cx_err_t cx_cipher_check_out_len(cx_cipher_context_t *ctx, size_t in_len, size_t out_len)
13{
14 if (CX_CHAIN_CTR == ctx->mode) {
15 if (out_len < in_len) {
16 return CX_INVALID_PARAMETER;
17 }
18 return CX_OK;
19 }
20 if ((CX_SIGN == ctx->operation) || (CX_VERIFY == ctx->operation)) {
21 if (out_len < 8) {
22 return CX_INVALID_PARAMETER;
23 }
24 }
25 else if (CX_DECRYPT == ctx->operation) {
26 if (out_len < in_len) {
27 return CX_INVALID_PARAMETER;
28 }
29 }
30 else if (CX_ENCRYPT == ctx->operation) {
31 if (NULL == ctx->add_padding) {
32 if (out_len < UPPER_ALIGN(in_len, 8, size_t)) {
33 return CX_INVALID_PARAMETER;
34 }
35 }
36 else {
37 if (out_len < UPPER_ALIGN(in_len + 7, 8, size_t)) {
38 return CX_INVALID_PARAMETER;
39 }
40 }
41 }
42 return CX_OK;
43}
44
45static const cx_cipher_info_t *cx_cipher_get_info(const cx_cipher_id_t type)
46{
47 switch (type) {
48#ifdef HAVE_AES
50 return &cx_aes_128_info;
52 return &cx_aes_192_info;
54 return &cx_aes_256_info;
55#endif // HAVE_AES
56 default:
57 return NULL;
58 }
59}
60
61static cx_err_t get_no_padding(uint8_t *input, size_t in_len, size_t *data_len)
62{
63 if ((NULL == input) || (NULL == data_len)) {
64 return CX_INVALID_PARAMETER;
65 }
66 *data_len = in_len;
67 return CX_OK;
68}
69
70static void add_zeros_padding(uint8_t *output, size_t out_len, size_t data_len)
71{
72 size_t i;
73
74 for (i = data_len; i < out_len; i++) {
75 output[i] = 0x00;
76 }
77}
78
79void add_one_and_zeros_padding(uint8_t *output, size_t out_len, size_t data_len)
80{
81 size_t padding_len = out_len - data_len;
82 size_t i = 0;
83
84 output[data_len] = 0x80;
85 for (i = 1; i < padding_len; i++) {
86 output[data_len + i] = 0x00;
87 }
88}
89
90static cx_err_t get_zeros_padding(uint8_t *input, size_t in_len, size_t *data_len)
91{
92 if ((NULL == input) || (NULL == data_len)) {
93 return CX_INVALID_PARAMETER;
94 }
95 *data_len = in_len;
96 return CX_OK;
97}
98
99static inline uint32_t neq_zero(uint32_t x)
100{
101 return (x | -x) >> 31;
102}
103
104static inline uint32_t conditional_choice(uint32_t a, uint32_t b, uint32_t cond)
105{
106 // Return a if cond is non zero, otherwise return b
107 return (a ^ b) ^ (b & (-cond));
108}
109
110static cx_err_t get_one_and_zeros_padding(uint8_t *input, size_t in_len, size_t *data_len)
111{
112 if ((NULL == input) || (NULL == data_len)) {
113 return CX_INVALID_PARAMETER;
114 }
115 int i;
116 // keeps track of consecutive zeroes
117 uint32_t acc = 0;
118 // result[0] is 1 if the padding is correct
119 // result[1] serves as a dummy value for constant time purposes
120 uint8_t result[2] = {0};
121 // padsize[0] will contain the padding length
122 // padsize[1] is a dummy value
123 uint8_t padsize[2] = {0};
124
125 for (i = in_len - 1; i >= 0; i--) {
126 uint32_t is_0x80 = neq_zero(input[i] ^ 0x80); // 0 if current byte == 0x80
127 uint32_t is_zero = neq_zero(acc);
128 result[is_0x80 | is_zero] = 1; // result[0] == 1 if t==0 and is_zero==0
129 padsize[is_0x80 | is_zero] = i; // update padded_size the same wa
130 acc |= input[i];
131 }
132 *data_len = padsize[0]; // this is 0 if padding is invalid
133 uint32_t is_correct = neq_zero((uint32_t) result[0]);
134 return conditional_choice(CX_OK, CX_INVALID_PARAMETER, is_correct);
135}
136
137static cx_err_t ecb_func(cx_cipher_context_t *ctx,
138 uint32_t operation,
139 size_t len,
140 const uint8_t *input,
141 uint8_t *output)
142{
143 uint32_t block_size = ctx->cipher_info->block_size;
144 cx_err_t error = CX_INTERNAL_ERROR;
145
146 if (len % block_size) {
147 return CX_INVALID_PARAMETER_VALUE;
148 }
149 while (len > 0) {
150 if (CX_ENCRYPT == operation) {
151 CX_CHECK(ctx->cipher_info->base->enc_func(input, output));
152 }
153 else if (CX_DECRYPT == operation) {
154 CX_CHECK(ctx->cipher_info->base->dec_func(input, output));
155 }
156 else {
157 return CX_INVALID_PARAMETER_VALUE;
158 }
159 input += block_size;
160 output += block_size;
161 len -= block_size;
162 }
163 error = CX_OK;
164
165end:
166 return error;
167}
168
169static cx_err_t cbc_func(cx_cipher_context_t *ctx,
170 uint32_t operation,
171 size_t len,
172 const uint8_t *input,
173 uint8_t *output)
174{
176 uint32_t block_size = ctx->cipher_info->block_size;
177 cx_err_t error = CX_INTERNAL_ERROR;
178
179 if (len % block_size) {
180 return CX_INVALID_PARAMETER_VALUE;
181 }
182 while (len > 0) {
183 if (CX_DECRYPT == operation) {
184 CX_CHECK(ctx->cipher_info->base->dec_func(input, output));
185 output += block_size;
186 }
187 else {
188 CX_CHECK(ctx->cipher_info->base->enc_func(input, block));
189 if (CX_ENCRYPT == operation) {
190 memcpy(output, block, block_size);
191 output += block_size;
192 }
193 }
194 input += block_size;
195 len -= block_size;
196 }
197 memcpy(ctx->sig, block, block_size);
198 error = CX_OK;
199
200end:
201 return error;
202}
203
204static size_t cx_cipher_verify_block(uint8_t *block, uint8_t *block_ref, size_t block_size)
205{
206 return (memcmp(block, block_ref, block_size) == 0) ? block_size : 0;
207}
208
210{
211 if (NULL == ctx) {
212 return CX_INVALID_PARAMETER;
213 }
214 memset(ctx, 0, sizeof(cx_cipher_context_t));
215 return CX_OK;
216}
217
218cx_err_t cx_cipher_setup(cx_cipher_context_t *ctx, const cx_cipher_id_t type, uint32_t mode)
219{
220 if (NULL == ctx) {
221 return CX_INVALID_PARAMETER;
222 }
223 const cx_cipher_info_t *info = cx_cipher_get_info(type);
224 if (NULL == info) {
225 return CX_INVALID_PARAMETER;
226 }
227 if (NULL == ctx->cipher_key) {
228 return CX_INVALID_PARAMETER;
229 }
230 switch (mode) {
231 case CX_CHAIN_CTR:
232 switch (type) {
236 ctx->mode = mode;
237 break;
238 default:
239 return CX_INVALID_PARAMETER_VALUE;
240 }
241 break;
242 case CX_CHAIN_ECB:
243 case CX_CHAIN_CBC:
244 ctx->mode = mode;
245 break;
246 default:
247 return CX_INVALID_PARAMETER_VALUE;
248 }
249 ctx->cipher_info = info;
250 return CX_OK;
251}
252
254 const uint8_t *key,
255 uint32_t key_bitlen,
256 uint32_t operation)
257{
258 uint32_t op_mode;
259
260 if ((NULL == ctx) || (NULL == key) || (NULL == ctx->cipher_info)) {
261 return CX_INVALID_PARAMETER;
262 }
263 if (ctx->cipher_info->key_bitlen != key_bitlen) {
264 return CX_INVALID_PARAMETER_SIZE;
265 }
266 if ((operation != CX_ENCRYPT) && (operation != CX_DECRYPT) && (operation != CX_SIGN)
267 && (operation != CX_VERIFY)) {
268 return CX_INVALID_PARAMETER_VALUE;
269 }
270 ctx->key_bitlen = key_bitlen;
271 ctx->operation = operation;
272 op_mode = operation | ctx->mode;
273 return ctx->cipher_info->base->setkey_func(ctx->cipher_key, op_mode, key, key_bitlen);
274}
275
276cx_err_t cx_cipher_setiv(cx_cipher_context_t *ctx, const uint8_t *iv, size_t iv_len)
277{
278 if ((NULL == ctx) || (NULL == ctx->cipher_info)) {
279 return CX_INVALID_PARAMETER;
280 }
281 if (CX_CHAIN_ECB == ctx->mode) {
282 return CX_OK;
283 }
284 if ((NULL == iv) && (0 != iv_len)) {
285 return CX_INVALID_PARAMETER_VALUE;
286 }
287
288 if ((0 != iv_len) && (ctx->cipher_info->iv_size != iv_len)) {
289 return CX_INVALID_PARAMETER_VALUE;
290 }
291
292 memcpy(ctx->iv, iv, iv_len);
293 ctx->iv_size = iv_len;
294
295 if (CX_CHAIN_CBC == ctx->mode) {
296 ctx->cipher_info->base->enc_func(ctx->iv, ctx->iv);
297 }
298 return CX_OK;
299}
300
301cx_err_t cx_cipher_set_padding(cx_cipher_context_t *ctx, uint32_t padding)
302{
303 if ((NULL == ctx) || (NULL == ctx->cipher_info)) {
304 return CX_INVALID_PARAMETER;
305 }
306 switch (padding) {
307 case CX_PAD_NONE:
308 ctx->add_padding = NULL;
309 ctx->get_padding = get_no_padding;
310 return CX_OK;
311 case CX_PAD_ISO9797M1:
312 ctx->add_padding = add_zeros_padding;
313 ctx->get_padding = get_zeros_padding;
314 return CX_OK;
315 case CX_PAD_ISO9797M2:
317 ctx->get_padding = get_one_and_zeros_padding;
318 return CX_OK;
319 default:
320 return CX_INVALID_PARAMETER_VALUE;
321 }
322}
323
325 const uint8_t *input,
326 size_t in_len,
327 uint8_t *output,
328 size_t *out_len)
329{
330 size_t remain_len;
331 size_t block_size;
332 cx_err_t error = CX_INTERNAL_ERROR;
333
334 if ((NULL == ctx) || (NULL == ctx->cipher_info) || (NULL == out_len)) {
335 return CX_INVALID_PARAMETER;
336 }
337
338 if (NULL == input) {
339 return CX_INVALID_PARAMETER_VALUE;
340 }
341
342 CX_CHECK(cx_cipher_check_out_len(ctx, in_len, *out_len));
343
344 *out_len = 0;
345 block_size = ctx->cipher_info->block_size;
346
347 switch (ctx->mode) {
348 case CX_CHAIN_ECB:
349 case CX_CHAIN_CBC:
350 if (in_len + ctx->unprocessed_len < block_size) {
351 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, in_len);
352 ctx->unprocessed_len += in_len;
353 return CX_OK;
354 }
355 if (ctx->unprocessed_len != 0) {
356 remain_len = block_size - ctx->unprocessed_len;
357 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, remain_len);
358 if (CX_CHAIN_ECB == ctx->mode) {
359 CX_CHECK(
360 ecb_func(ctx, ctx->operation, block_size, ctx->unprocessed_data, output));
361 }
362 else {
363 CX_CHECK(
364 cbc_func(ctx, ctx->operation, block_size, ctx->unprocessed_data, output));
365 }
366 if (ctx->operation != CX_SIGN) {
367 output += block_size;
368 }
369 *out_len += block_size;
370 ctx->unprocessed_len = 0;
371 input += remain_len;
372 in_len -= remain_len;
373 }
374 if (in_len != 0) {
375 remain_len = in_len % block_size;
376 if ((remain_len == 0) && (ctx->operation == CX_DECRYPT)
377 && (ctx->add_padding != NULL)) {
378 remain_len = block_size;
379 }
380 memcpy(ctx->unprocessed_data, &(input[in_len - remain_len]), remain_len);
381 ctx->unprocessed_len += remain_len;
382 in_len -= remain_len;
383 }
384 if (in_len) {
385 if (CX_CHAIN_ECB == ctx->mode) {
386 CX_CHECK(ecb_func(ctx, ctx->operation, in_len, input, output));
387 }
388 else {
389 CX_CHECK(cbc_func(ctx, ctx->operation, in_len, input, output));
390 }
391 }
392 *out_len = in_len;
393 return CX_OK;
394 case CX_CHAIN_CTR:
395 CX_CHECK(ctx->cipher_info->base->ctr_func(ctx->cipher_key,
396 in_len,
397 &ctx->unprocessed_len,
398 ctx->iv,
399 ctx->unprocessed_data,
400 input,
401 output));
402 *out_len = in_len;
403 return CX_OK;
404 default:
405 return CX_INVALID_PARAMETER_VALUE;
406 }
407end:
408 return error;
409}
410
411cx_err_t cx_cipher_finish(cx_cipher_context_t *ctx, uint8_t *output, size_t *out_len)
412{
413 cx_err_t error = CX_INTERNAL_ERROR;
414 if ((NULL == ctx) || (NULL == ctx->cipher_info) || (NULL == out_len)) {
415 return CX_INVALID_PARAMETER;
416 }
417
418 *out_len = 0;
419 switch (ctx->mode) {
420 case CX_CHAIN_CTR:
421 error = CX_OK;
422 break;
423 case CX_CHAIN_ECB:
424 case CX_CHAIN_CBC:
425 if ((CX_ENCRYPT == ctx->operation) || (CX_SIGN == ctx->operation)
426 || (CX_VERIFY == ctx->operation)) {
427 if (NULL == ctx->add_padding) {
428 if (ctx->unprocessed_len != 0) {
429 goto end;
430 }
431 error = CX_OK;
432 goto end;
433 }
434 if ((add_zeros_padding == ctx->add_padding) && (ctx->unprocessed_len == 0)) {
435 *out_len = 0;
436 error = CX_OK;
437 goto end;
438 }
439 ctx->add_padding(
441 }
442 if (get_no_padding != ctx->get_padding) {
444 }
445 if (CX_CHAIN_ECB == ctx->mode) {
446 CX_CHECK(ecb_func(
447 ctx, ctx->operation, ctx->unprocessed_len, ctx->unprocessed_data, output));
448 }
449 else {
450 CX_CHECK(cbc_func(
451 ctx, ctx->operation, ctx->unprocessed_len, ctx->unprocessed_data, output));
452 }
453
454 if ((CX_DECRYPT == ctx->operation) && (NULL != ctx->get_padding)) {
455 error = ctx->get_padding(output, ctx->unprocessed_len, out_len);
456 goto end;
457 }
458
459 *out_len = ctx->unprocessed_len;
460 error = CX_OK;
461 break;
462 default:
463 error = CX_INVALID_PARAMETER_VALUE;
464 break;
465 }
466end:
467 ctx->cipher_info->base->ctx_reset();
468 return error;
469}
470
472 uint8_t *output,
473 size_t *out_len,
474 size_t *finish_len)
475{
476 // Only in CBC
477 if (CX_VERIFY == ctx->operation) {
478 *finish_len = cx_cipher_verify_block(ctx->sig, output, ctx->cipher_info->block_size);
479 *out_len = 0;
480 }
481 else if (CX_SIGN == ctx->operation) {
482 memcpy(output, ctx->sig, ctx->cipher_info->block_size);
483 *finish_len = ctx->cipher_info->block_size;
484 *out_len = 0;
485 }
486 else {
487 return CX_OK;
488 }
489 return CX_OK;
490}
491
493 const uint8_t *iv,
494 size_t iv_len,
495 const uint8_t *input,
496 size_t in_len,
497 uint8_t *output,
498 size_t *out_len)
499{
500 cx_err_t error = CX_INTERNAL_ERROR;
501 size_t finish_len = 0;
502
503 CX_CHECK(cx_cipher_setiv(ctx, iv, iv_len));
504 CX_CHECK(cx_cipher_update(ctx, input, in_len, output, out_len));
505 if (ctx->add_padding != NULL) {
506 finish_len = *out_len;
507 }
508 CX_CHECK(cx_cipher_finish(ctx, output + finish_len, &finish_len));
509 CX_CHECK(cx_cipher_mac(ctx, output, out_len, &finish_len));
510 *out_len += finish_len;
511
512end:
513 return error;
514}
515
517{
518 memset(ctx->iv, 0, MAX_IV_LENGTH);
519 memset(ctx->unprocessed_data, 0, MAX_BLOCK_LENGTH);
520 ctx->unprocessed_len = 0;
521 ctx->iv_size = 0;
522}
523
524#ifdef UNITTEST
525#include <stdarg.h>
526#include <stddef.h>
527#include <setjmp.h>
528#include <stdint.h>
529#include <cmocka.h>
530static void test_iso9797_method2_unpad(void **state)
531{
532 uint8_t buf1[8] = {0, 1, 2, 3, 4, 5, 6, 0x80};
533 size_t unpadded_size = 0;
534
535 assert_int_equal(get_one_and_zeros_padding(buf1, 8, &unpadded_size), CX_OK);
536 assert_int_equal(unpadded_size, 7);
537
538 uint8_t buf2[8] = {0, 1, 2, 3, 0x80, 0, 0, 0};
539 unpadded_size = 0;
540
541 assert_int_equal(get_one_and_zeros_padding(buf2, 8, &unpadded_size), CX_OK);
542 assert_int_equal(unpadded_size, 4);
543
544 unpadded_size = 0;
545 uint8_t buf3[8] = {0, 1, 2, 3, 4, 5, 6, 7};
546
547 assert_int_equal(get_one_and_zeros_padding(buf3, 8, &unpadded_size), CX_INVALID_PARAMETER);
548
549 uint8_t buf4[8] = {0, 1, 2, 3, 4, 5, 0x80, 7};
550 unpadded_size = 0;
551
552 assert_int_equal(get_one_and_zeros_padding(buf4, 8, &unpadded_size), CX_INVALID_PARAMETER);
553
554 uint8_t buf5[8] = {0x80, 0, 0, 0, 0, 0, 0, 0};
555 unpadded_size = 0;
556
557 assert_int_equal(get_one_and_zeros_padding(buf5, 8, &unpadded_size), CX_OK);
558 assert_int_equal(unpadded_size, 0);
559}
560
561static void test_iso9797_method2_pad(void **state)
562{
563 uint8_t buf1[8] = {0};
564 const uint8_t buf1_padded[8] = {0x80, 0, 0, 0, 0, 0, 0, 0};
565
566 add_one_and_zeros_padding(buf1, 8, 0);
567 assert_memory_equal(buf1, buf1_padded, sizeof(buf1_padded));
568
569 uint8_t buf2[8] = {0xaa, 0xbb, 0xcc};
570 const uint8_t buf2_padded[8] = {0xaa, 0xbb, 0xcc, 0x80, 0, 0, 0, 0};
571
572 add_one_and_zeros_padding(buf2, 8, 3);
573 assert_memory_equal(buf2, buf2_padded, sizeof(buf2_padded));
574
575 uint8_t buf3[16] = {0, 1, 2, 3, 4, 5, 6, 7};
576 const uint8_t buf3_padded[16] = {0, 1, 2, 3, 4, 5, 6, 7, 0x80, 0, 0, 0, 0, 0, 0, 0};
577
578 add_one_and_zeros_padding(buf3, 16, 8);
579 assert_memory_equal(buf3, buf3_padded, sizeof(buf3_padded));
580}
581
582int main()
583{
584 const struct CMUnitTest tests[] = {
585 cmocka_unit_test(test_iso9797_method2_pad),
586 cmocka_unit_test(test_iso9797_method2_unpad),
587 };
588
589 return cmocka_run_group_tests(tests, NULL, NULL);
590}
591#endif // UNITTEST
void cx_cipher_reset(cx_cipher_context_t *ctx)
Definition cx_cipher.c:516
#define CX_MAX_BLOCK_SIZE
Definition cx_cipher.c:10
cx_err_t cx_cipher_setiv(cx_cipher_context_t *ctx, const uint8_t *iv, size_t iv_len)
Set the initialization vector.
Definition cx_cipher.c:276
void add_one_and_zeros_padding(uint8_t *output, size_t out_len, size_t data_len)
Definition cx_cipher.c:79
cx_err_t cx_cipher_mac(cx_cipher_context_t *ctx, uint8_t *output, size_t *out_len, size_t *finish_len)
Definition cx_cipher.c:471
cx_err_t cx_cipher_setup(cx_cipher_context_t *ctx, const cx_cipher_id_t type, uint32_t mode)
Initialize and fill the context structure given the cipher info.
Definition cx_cipher.c:218
cx_err_t cx_cipher_init(cx_cipher_context_t *ctx)
Initialize a cipher context as NONE.
Definition cx_cipher.c:209
cx_err_t cx_cipher_enc_dec(cx_cipher_context_t *ctx, const uint8_t *iv, size_t iv_len, const uint8_t *input, size_t in_len, uint8_t *output, size_t *out_len)
All-in-one encryption or decryption.
Definition cx_cipher.c:492
cx_err_t cx_cipher_update(cx_cipher_context_t *ctx, const uint8_t *input, size_t in_len, uint8_t *output, size_t *out_len)
Encrypt or decrypt with the given context.
Definition cx_cipher.c:324
cx_err_t cx_cipher_setkey(cx_cipher_context_t *ctx, const uint8_t *key, uint32_t key_bitlen, uint32_t operation)
Set the key to use.
Definition cx_cipher.c:253
cx_err_t cx_cipher_finish(cx_cipher_context_t *ctx, uint8_t *output, size_t *out_len)
Finalize the operation.
Definition cx_cipher.c:411
cx_err_t cx_cipher_set_padding(cx_cipher_context_t *ctx, uint32_t padding)
Set the padding type.
Definition cx_cipher.c:301
cx_cipher_id_t
Definition lcx_cipher.h:36
@ CX_CIPHER_AES_192
AES with a 192-bit key.
Definition lcx_cipher.h:39
@ CX_CIPHER_AES_256
AES with a 256-bit key.
Definition lcx_cipher.h:40
@ CX_CIPHER_AES_128
AES with a 128-bit key.
Definition lcx_cipher.h:38
#define MAX_IV_LENGTH
Definition lcx_cipher.h:19
#define MAX_BLOCK_LENGTH
Definition lcx_cipher.h:21
#define CX_PAD_NONE
Definition lcx_common.h:135
#define CX_PAD_ISO9797M2
Definition lcx_common.h:137
#define CX_CHAIN_CBC
Definition lcx_common.h:147
#define CX_CHAIN_CTR
Definition lcx_common.h:148
#define CX_ENCRYPT
Definition lcx_common.h:126
#define CX_DECRYPT
Definition lcx_common.h:127
#define CX_SIGN
Definition lcx_common.h:128
#define CX_PAD_ISO9797M1
Definition lcx_common.h:136
#define CX_CHAIN_ECB
Definition lcx_common.h:146
#define CX_VERIFY
Definition lcx_common.h:129
cx_err_t(* enc_func)(const uint8_t *in_block, uint8_t *out_block)
Encryption function.
Definition lcx_cipher.h:51
cx_err_t(* dec_func)(const uint8_t *in_block, uint8_t *out_block)
Decryption function.
Definition lcx_cipher.h:52
cx_err_t(* ctx_reset)(void)
Reset.
Definition lcx_cipher.h:64
cx_err_t(* setkey_func)(const cipher_key_t *ctx_key, uint32_t operation, const uint8_t *key, uint32_t key_bitlen)
Set key for encryption or decryption.
Definition lcx_cipher.h:60
cx_err_t(* ctr_func)(const cipher_key_t *ctx_key, size_t len, size_t *nc_off, uint8_t *nonce_counter, uint8_t *stream_block, const uint8_t *input, uint8_t *output)
Encryption in CTR mode.
Definition lcx_cipher.h:53
uint32_t mode
Mode of operation: ECB, CBC, CTR.
Definition lcx_cipher.h:93
size_t iv_size
Length of the initialization vector.
Definition lcx_cipher.h:92
uint32_t operation
Operation: encryption or decryption.
Definition lcx_cipher.h:84
uint8_t unprocessed_data[MAX_BLOCK_LENGTH]
Data to process.
Definition lcx_cipher.h:89
void(* add_padding)(uint8_t *output, size_t out_len, size_t data_len)
Padding function.
Definition lcx_cipher.h:85
uint32_t key_bitlen
Key size in bits.
Definition lcx_cipher.h:83
const cipher_key_t * cipher_key
Cipher-specific context.
Definition lcx_cipher.h:95
uint8_t iv[MAX_IV_LENGTH]
Initiaization vector.
Definition lcx_cipher.h:91
cx_err_t(* get_padding)(uint8_t *input, size_t in_len, size_t *data_len)
Check the padding.
Definition lcx_cipher.h:86
const cx_cipher_info_t * cipher_info
Cipher information.
Definition lcx_cipher.h:82
size_t unprocessed_len
Length of data to process.
Definition lcx_cipher.h:90
uint8_t sig[MAX_BLOCK_LENGTH]
Last block to be verified.
Definition lcx_cipher.h:94
const cx_cipher_base_t * base
Definition lcx_cipher.h:73
uint32_t iv_size
Initialization vector size.
Definition lcx_cipher.h:70
uint32_t key_bitlen
Key size.
Definition lcx_cipher.h:69
uint32_t block_size
Block size.
Definition lcx_cipher.h:71
unsigned char uint8_t
Definition usbd_conf.h:53