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_CHECK(cx_aes_set_key_hw(key, CX_ENCRYPT));
32  CX_CHECK(cx_aes_block_hw(inblock, outblock));
33  cx_aes_reset_hw();
34 end:
35  return error;
36 }
37 
38 cx_err_t cx_aes_dec_block(const cx_aes_key_t *key, const uint8_t *inblock, uint8_t *outblock)
39 {
40  cx_err_t error;
41  CX_CHECK(cx_aes_set_key_hw(key, CX_DECRYPT));
42  CX_CHECK(cx_aes_block_hw(inblock, outblock));
43  cx_aes_reset_hw();
44 end:
45  return error;
46 }
47 
48 cx_err_t cx_aes_iv_no_throw(const cx_aes_key_t *key,
49  uint32_t mode,
50  const uint8_t *iv,
51  size_t iv_len,
52  const uint8_t *in,
53  size_t in_len,
54  uint8_t *out,
55  size_t *out_len)
56 {
58  cx_cipher_id_t type;
59  cx_err_t error;
60  uint32_t operation;
61 
62  switch (key->size) {
63  case 16:
64  type = CX_CIPHER_AES_128;
65  break;
66  case 24:
67  type = CX_CIPHER_AES_192;
68  break;
69  case 32:
70  type = CX_CIPHER_AES_256;
71  break;
72  default:
73  return CX_INVALID_PARAMETER;
74  }
75 
76  ctx = &G_cx.cipher;
77  operation = mode & CX_MASK_SIGCRYPT;
78  if ((operation != CX_ENCRYPT) && (operation != CX_DECRYPT) && (operation != CX_SIGN)
79  && (operation != CX_VERIFY)) {
80  return CX_INVALID_PARAMETER_VALUE;
81  }
82  CX_CHECK(cx_cipher_init(ctx));
83  // Set key
84  ctx->key_bitlen = key->size * 8;
85  ctx->operation = operation;
86  ctx->cipher_key = (const cipher_key_t *) key;
87  operation |= mode & CX_MASK_CHAIN;
88  CX_CHECK(cx_cipher_setup(ctx, type, mode & CX_MASK_CHAIN));
89  CX_CHECK(cx_aes_set_key_hw(key, operation));
90  CX_CHECK(cx_cipher_set_padding(ctx, mode & CX_MASK_PAD));
91  CX_CHECK(cx_cipher_enc_dec(ctx, iv, iv_len, in, in_len, out, out_len));
92 
93 end:
94  explicit_bzero(ctx, sizeof(cx_cipher_context_t));
95  return error;
96 }
97 
98 cx_err_t cx_aes_no_throw(const cx_aes_key_t *key,
99  uint32_t mode,
100  const uint8_t *in,
101  size_t in_len,
102  uint8_t *out,
103  size_t *out_len)
104 {
105  return cx_aes_iv_no_throw(key, mode, NULL, 0, in, in_len, out, out_len);
106 }
107 
108 cx_err_t aes_ctr(cx_aes_key_t *ctx_key,
109  size_t len,
110  size_t *nc_off,
111  uint8_t *nonce_counter,
112  uint8_t *stream_block,
113  const uint8_t *input,
114  uint8_t *output)
115 {
116  uint8_t c;
117  size_t n = *nc_off;
118  cx_err_t error = CX_INVALID_PARAMETER;
119  UNUSED(ctx_key);
120 
121  while (len--) {
122  if (n == 0) {
123  CX_CHECK(cx_aes_block_hw(nonce_counter, stream_block));
124  for (int i = CX_AES_BLOCK_SIZE; i > 0; i--) {
125  if (++nonce_counter[i - 1] != 0) {
126  break;
127  }
128  }
129  }
130  c = *input++;
131  *output++ = c ^ stream_block[n];
132  n = (n + 1) & 0x0F;
133  }
134  *nc_off = n;
135  error = CX_OK;
136 
137 end:
138  return error;
139 }
140 
141 cx_err_t aes_setkey(cx_aes_key_t *ctx_key,
142  uint32_t operation,
143  const uint8_t *key,
144  uint32_t key_bitlen)
145 {
146  cx_err_t error;
147  CX_CHECK(cx_aes_init_key_no_throw(key, key_bitlen / 8, ctx_key));
148  CX_CHECK(cx_aes_set_key_hw(ctx_key, operation));
149 end:
150  return error;
151 }
152 
153 static const cx_cipher_base_t aes_base = {
154  (cx_err_t(*)(const uint8_t *inblock, uint8_t *outblock)) cx_aes_block_hw,
155  (cx_err_t(*)(const uint8_t *inblock, uint8_t *outblock)) cx_aes_block_hw,
156  (cx_err_t(*)(const cipher_key_t *ctx_key,
157  size_t len,
158  size_t *nc_off,
159  uint8_t *nonce_counter,
160  uint8_t *stream_block,
161  const uint8_t *input,
162  uint8_t *output)) aes_ctr,
163  (cx_err_t(*)(const cipher_key_t *ctx_key,
164  uint32_t operation,
165  const uint8_t *key,
166  uint32_t key_bitlen)) aes_setkey,
167  (cx_err_t(*)(void)) cx_aes_reset_hw,
168 };
169 
170 const cx_cipher_info_t cx_aes_128_info = {128,
171  16,
172  CX_AES_BLOCK_SIZE,
173 #ifdef BOLOS_OS_UPGRADER_APP
174  (cx_cipher_base_t *)
175 #endif
176  &aes_base};
177 
178 const cx_cipher_info_t cx_aes_192_info = {192,
179  16,
180  CX_AES_BLOCK_SIZE,
181 #ifdef BOLOS_OS_UPGRADER_APP
182  (cx_cipher_base_t *)
183 #endif
184  &aes_base};
185 
186 const cx_cipher_info_t cx_aes_256_info = {256,
187  16,
188  CX_AES_BLOCK_SIZE,
189 #ifdef BOLOS_OS_UPGRADER_APP
190  (cx_cipher_base_t *)
191 #endif
192  &aes_base};
193 
194 #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