Embedded SDK
Embedded SDK
cx_aes.c
Go to the documentation of this file.
1 /* @BANNER@ */
2 
3 #include "app_config.h"
4 
5 #ifdef HAVE_AES
6 
7 #include "cx_cipher.h"
8 #include "cx_ram.h"
9 
10 #include <stddef.h>
11 #include <string.h>
12 
13 cx_err_t cx_aes_init_key_no_throw(const uint8_t *raw_key, size_t key_len, cx_aes_key_t *key)
14 {
15  memset(key, 0, sizeof(cx_aes_key_t));
16  switch (key_len) {
17  case 16:
18  case 24:
19  case 32:
20  key->size = key_len;
21  memmove(key->keys, raw_key, key_len);
22  return CX_OK;
23  default:
24  return CX_INVALID_PARAMETER;
25  }
26 }
27 
28 cx_err_t cx_aes_enc_block(const cx_aes_key_t *key, const uint8_t *inblock, uint8_t *outblock)
29 {
30  cx_err_t error;
31  cx_err_t err_reset = CX_INTERNAL_ERROR;
32  CX_CHECK(cx_aes_set_key_hw(key, CX_ENCRYPT));
33  CX_CHECK(cx_aes_block_hw(inblock, outblock));
34 end:
35  err_reset = cx_aes_reset_hw();
36  return error == CX_OK ? err_reset : error;
37 }
38 
39 cx_err_t cx_aes_dec_block(const cx_aes_key_t *key, const uint8_t *inblock, uint8_t *outblock)
40 {
41  cx_err_t error;
42  cx_err_t err_reset = CX_INTERNAL_ERROR;
43  CX_CHECK(cx_aes_set_key_hw(key, CX_ENCRYPT));
44  CX_CHECK(cx_aes_set_key_hw(key, CX_DECRYPT));
45  CX_CHECK(cx_aes_block_hw(inblock, outblock));
46 end:
47  err_reset = cx_aes_reset_hw();
48  return error == CX_OK ? err_reset : error;
49 }
50 
51 cx_err_t cx_aes_iv_no_throw(const cx_aes_key_t *key,
52  uint32_t mode,
53  const uint8_t *iv,
54  size_t iv_len,
55  const uint8_t *in,
56  size_t in_len,
57  uint8_t *out,
58  size_t *out_len)
59 {
61  cx_cipher_id_t type;
62  cx_err_t error;
63  uint32_t operation;
64 
65  switch (key->size) {
66  case 16:
67  type = CX_CIPHER_AES_128;
68  break;
69  case 24:
70  type = CX_CIPHER_AES_192;
71  break;
72  case 32:
73  type = CX_CIPHER_AES_256;
74  break;
75  default:
76  return CX_INVALID_PARAMETER;
77  }
78 
79  ctx = &G_cx.cipher;
80  operation = mode & CX_MASK_SIGCRYPT;
81  if ((operation != CX_ENCRYPT) && (operation != CX_DECRYPT) && (operation != CX_SIGN)
82  && (operation != CX_VERIFY)) {
83  return CX_INVALID_PARAMETER_VALUE;
84  }
85  CX_CHECK(cx_cipher_init(ctx));
86  // Set key
87  ctx->key_bitlen = key->size * 8;
88  ctx->operation = operation;
89  ctx->cipher_key = (const cipher_key_t *) key;
90  operation |= mode & CX_MASK_CHAIN;
91  CX_CHECK(cx_cipher_setup(ctx, type, mode & CX_MASK_CHAIN));
92  CX_CHECK(cx_aes_set_key_hw(key, operation));
93  CX_CHECK(cx_cipher_set_padding(ctx, mode & CX_MASK_PAD));
94  CX_CHECK(cx_cipher_enc_dec(ctx, iv, iv_len, in, in_len, out, out_len));
95 
96 end:
97  explicit_bzero(ctx, sizeof(cx_cipher_context_t));
98  return error;
99 }
100 
101 cx_err_t cx_aes_no_throw(const cx_aes_key_t *key,
102  uint32_t mode,
103  const uint8_t *in,
104  size_t in_len,
105  uint8_t *out,
106  size_t *out_len)
107 {
108  return cx_aes_iv_no_throw(key, mode, NULL, 0, in, in_len, out, out_len);
109 }
110 
111 cx_err_t aes_ctr(cx_aes_key_t *ctx_key,
112  size_t len,
113  size_t *nc_off,
114  uint8_t *nonce_counter,
115  uint8_t *stream_block,
116  const uint8_t *input,
117  uint8_t *output)
118 {
119  uint8_t c;
120  size_t n = *nc_off;
121  cx_err_t error = CX_INVALID_PARAMETER;
122  UNUSED(ctx_key);
123 
124  while (len--) {
125  if (n == 0) {
126  CX_CHECK(cx_aes_block_hw(nonce_counter, stream_block));
127  for (int i = CX_AES_BLOCK_SIZE; i > 0; i--) {
128  if (++nonce_counter[i - 1] != 0) {
129  break;
130  }
131  }
132  }
133  c = *input++;
134  *output++ = c ^ stream_block[n];
135  n = (n + 1) & 0x0F;
136  }
137  *nc_off = n;
138  error = CX_OK;
139 
140 end:
141  return error;
142 }
143 
144 cx_err_t aes_setkey(cx_aes_key_t *ctx_key,
145  uint32_t operation,
146  const uint8_t *key,
147  uint32_t key_bitlen)
148 {
149  cx_err_t error;
150  CX_CHECK(cx_aes_init_key_no_throw(key, key_bitlen / 8, ctx_key));
151  CX_CHECK(cx_aes_set_key_hw(ctx_key, operation));
152 end:
153  return error;
154 }
155 
156 static const cx_cipher_base_t aes_base = {
157  (cx_err_t(*)(const uint8_t *inblock, uint8_t *outblock)) cx_aes_block_hw,
158  (cx_err_t(*)(const uint8_t *inblock, uint8_t *outblock)) cx_aes_block_hw,
159  (cx_err_t(*)(const cipher_key_t *ctx_key,
160  size_t len,
161  size_t *nc_off,
162  uint8_t *nonce_counter,
163  uint8_t *stream_block,
164  const uint8_t *input,
165  uint8_t *output)) aes_ctr,
166  (cx_err_t(*)(const cipher_key_t *ctx_key,
167  uint32_t operation,
168  const uint8_t *key,
169  uint32_t key_bitlen)) aes_setkey,
170  (cx_err_t(*)(void)) cx_aes_reset_hw,
171 };
172 
173 const cx_cipher_info_t cx_aes_128_info = {128,
174  16,
175  CX_AES_BLOCK_SIZE,
176 #ifdef BOLOS_OS_UPGRADER_APP
177  (cx_cipher_base_t *)
178 #endif
179  &aes_base};
180 
181 const cx_cipher_info_t cx_aes_192_info = {192,
182  16,
183  CX_AES_BLOCK_SIZE,
184 #ifdef BOLOS_OS_UPGRADER_APP
185  (cx_cipher_base_t *)
186 #endif
187  &aes_base};
188 
189 const cx_cipher_info_t cx_aes_256_info = {256,
190  16,
191  CX_AES_BLOCK_SIZE,
192 #ifdef BOLOS_OS_UPGRADER_APP
193  (cx_cipher_base_t *)
194 #endif
195  &aes_base};
196 
197 #endif // HAVE_AES
union cx_u G_cx
Definition: cx_ram.c:21
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
WARN_UNUSED_RESULT cx_err_t cx_cipher_init(cx_cipher_context_t *ctx)
Initialize a cipher context as NONE.
Definition: cx_cipher.c:209
WARN_UNUSED_RESULT 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
WARN_UNUSED_RESULT 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
WARN_UNUSED_RESULT cx_err_t cx_cipher_set_padding(cx_cipher_context_t *ctx, uint32_t padding)
Set the padding type.
Definition: cx_cipher.c:301
#define CX_MASK_SIGCRYPT
Definition: lcx_common.h:125
#define CX_ENCRYPT
Definition: lcx_common.h:126
#define CX_DECRYPT
Definition: lcx_common.h:127
#define CX_MASK_CHAIN
Definition: lcx_common.h:145
#define CX_MASK_PAD
Definition: lcx_common.h:134
#define CX_SIGN
Definition: lcx_common.h:128
#define CX_VERIFY
Definition: lcx_common.h:129
uint32_t operation
Operation: encryption or decryption.
Definition: lcx_cipher.h:84
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
cx_cipher_context_t cipher
Definition: cx_ram.h:109
unsigned char uint8_t
Definition: usbd_conf.h:53