Embedded SDK
Embedded SDK
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 
12 static 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 
45 static const cx_cipher_info_t *cx_cipher_get_info(const cx_cipher_id_t type)
46 {
47  switch (type) {
48 #ifdef HAVE_AES
49  case CX_CIPHER_AES_128:
50  return &cx_aes_128_info;
51  case CX_CIPHER_AES_192:
52  return &cx_aes_192_info;
53  case CX_CIPHER_AES_256:
54  return &cx_aes_256_info;
55 #endif // HAVE_AES
56  default:
57  return NULL;
58  }
59 }
60 
61 static 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 
70 static 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 
79 void 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 
90 static 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 
99 static inline uint32_t neq_zero(uint32_t x)
100 {
101  return (x | -x) >> 31;
102 }
103 
104 static 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 
110 static 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 
137 static 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 
165 end:
166  return error;
167 }
168 
169 static 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 {
175  uint8_t block[CX_MAX_BLOCK_SIZE];
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 
200 end:
201  return error;
202 }
203 
204 static 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 
218 cx_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) {
233  case CX_CIPHER_AES_128:
234  case CX_CIPHER_AES_192:
235  case CX_CIPHER_AES_256:
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 
276 cx_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 
301 cx_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  }
407 end:
408  return error;
409 }
410 
411 cx_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  }
466 end:
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 
512 end:
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>
530 static 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 
561 static 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 
582 int 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