Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_aes.c
1 #include <bc_aes.h>
2 #include <bc_system.h>
3 #include <bc_tick.h>
4 #include <stm32l0xx.h>
5 
6 #define _BC_AES_DATATYPE AES_CR_DATATYPE_1
7 
8 static void _bc_aes_set_key(const bc_aes_key_t key);
9 static void _bc_aes_set_iv(const bc_aes_iv_t iv);
10 static bool _bc_aes_process(void *buffer_out, const void *buffer_in, size_t length);
11 
12 void bc_aes_init(void)
13 {
14  RCC->AHBENR |= RCC_AHBENR_CRYPEN_Msk;
15  // Errata workaround
16  RCC->AHBENR;
17 }
18 
19 bool bc_aes_key_derivation(bc_aes_key_t decryption_key, const bc_aes_key_t key)
20 {
21  bc_system_pll_enable();
22 
23  AES->CR = AES_CR_MODE_0;
24 
25  _bc_aes_set_key(key);
26 
27  AES->CR |= AES_CR_EN;
28 
29  bc_tick_t timeout = bc_tick_get() + 100;
30 
31  while ((AES->SR & AES_SR_CCF) == 0)
32  {
33  if (timeout < bc_tick_get())
34  {
35  bc_system_pll_disable();
36  return false;
37  }
38  }
39 
40  decryption_key[0] = AES->KEYR0;
41  decryption_key[1] = AES->KEYR1;
42  decryption_key[2] = AES->KEYR2;
43  decryption_key[3] = AES->KEYR3;
44 
45  AES->CR |= AES_CR_CCFC;
46 
47  bc_system_pll_disable();
48 
49  return true;
50 }
51 
52 bool bc_aes_ecb_encrypt(void *buffer_out, const void *buffer_in, const size_t length, const bc_aes_key_t key)
53 {
54  if ((length % 16) != 0)
55  {
56  return false;
57  }
58 
59  AES->CR = _BC_AES_DATATYPE;
60 
61  _bc_aes_set_key(key);
62 
63  return _bc_aes_process(buffer_out, buffer_in, length);
64 }
65 
66 bool bc_aes_ecb_decrypt(void *buffer_out, const void *buffer_in, size_t length, bc_aes_key_t key)
67 {
68  if ((length % 16) != 0)
69  {
70  return false;
71  }
72 
73  AES->CR = _BC_AES_DATATYPE | AES_CR_MODE_1;
74 
75  _bc_aes_set_key(key);
76 
77  return _bc_aes_process(buffer_out, buffer_in, length);
78 }
79 
80 bool bc_aes_cbc_encrypt(void *buffer_out, const void *buffer_in, size_t length, bc_aes_key_t key, bc_aes_iv_t iv)
81 {
82  if ((length % 16) != 0)
83  {
84  return false;
85  }
86 
87  AES->CR = AES_CR_CHMOD_0 | _BC_AES_DATATYPE;
88 
89  _bc_aes_set_key(key);
90 
91  _bc_aes_set_iv(iv);
92 
93  return _bc_aes_process(buffer_out, buffer_in, length);
94 }
95 
96 bool bc_aes_cbc_decrypt(void *buffer_out, const void *buffer_in, size_t length, bc_aes_key_t key, bc_aes_iv_t iv)
97 {
98  if ((length % 16) != 0)
99  {
100  return false;
101  }
102 
103  AES->CR = AES_CR_CHMOD_0 | _BC_AES_DATATYPE | AES_CR_MODE_1;
104 
105  _bc_aes_set_key(key);
106 
107  _bc_aes_set_iv(iv);
108 
109  return _bc_aes_process(buffer_out, buffer_in, length);
110 }
111 
112 void bc_aes_key_from_uint8(bc_aes_key_t key, const uint8_t *buffer)
113 {
114  uint8_t *tmp = (uint8_t *) key;
115 
116  for (int i = 0; i < 16; i++)
117  {
118  tmp[15 - i] = buffer[i];
119  }
120 }
121 
122 void bc_aes_iv_from_uint8(bc_aes_iv_t iv, const uint8_t *buffer)
123 {
124  uint8_t *tmp = (uint8_t *) iv;
125 
126  for (int i = 0; i < 16; i++)
127  {
128  tmp[15 - i] = buffer[i];
129  }
130 }
131 
132 static void _bc_aes_set_key(const bc_aes_key_t key)
133 {
134  AES->KEYR0 = key[0];
135  AES->KEYR1 = key[1];
136  AES->KEYR2 = key[2];
137  AES->KEYR3 = key[3];
138 }
139 
140 static void _bc_aes_set_iv(const bc_aes_iv_t iv)
141 {
142  AES->IVR0 = iv[0];
143  AES->IVR1 = iv[1];
144  AES->IVR2 = iv[2];
145  AES->IVR3 = iv[3];
146 }
147 
148 static bool _bc_aes_process(void *buffer_out, const void *buffer_in, size_t length)
149 {
150  uint8_t buffer[16];
151 
152  uint32_t *inputaddr = (uint32_t *) buffer_in;
153  uint32_t *outputaddr = (uint32_t *) buffer_out;
154 
155  bc_system_pll_enable();
156 
157  bool inputaddr_aligned = ((uint32_t) inputaddr & (uint32_t) 0x00000003U) == 0U;
158  bool outputaddr_aligned = ((uint32_t) outputaddr & (uint32_t) 0x00000003U) == 0U;
159 
160  if (!outputaddr_aligned)
161  {
162  outputaddr = (uint32_t *) buffer;
163  }
164 
165  AES->CR |= AES_CR_EN;
166 
167  for (size_t i = 0; i < length; i += 16)
168  {
169  if (!inputaddr_aligned)
170  {
171  memcpy(buffer, (uint8_t *) buffer_in + i, 16);
172 
173  inputaddr = (uint32_t *) buffer;
174  }
175 
176  AES->DINR = *(inputaddr++);
177  AES->DINR = *(inputaddr++);
178  AES->DINR = *(inputaddr++);
179  AES->DINR = *(inputaddr++);
180 
181  bc_tick_t timeout = bc_tick_get() + 100;
182 
183  while ((AES->SR & AES_SR_CCF) == 0)
184  {
185  if (timeout < bc_tick_get())
186  {
187  bc_system_pll_disable();
188  return false;
189  }
190  }
191 
192  AES->CR |= AES_CR_CCFC;
193 
194  *(outputaddr++) = AES->DOUTR;
195  *(outputaddr++) = AES->DOUTR;
196  *(outputaddr++) = AES->DOUTR;
197  *(outputaddr++) = AES->DOUTR;
198 
199  if (!outputaddr_aligned)
200  {
201  memcpy((uint8_t *) buffer_out + i, buffer, 16);
202  outputaddr = (uint32_t *) buffer;
203  }
204  }
205 
206  AES->CR &= ~AES_CR_EN;
207 
208  bc_system_pll_disable();
209 
210  return true;
211 }
uint64_t bc_tick_t
Timestamp data type.
Definition: bc_tick.h:16
uint32_t bc_aes_key_t[BC_AES_KEYLEN/8/4]
AES 128-bit Key.
Definition: bc_aes.h:15
bool bc_aes_key_derivation(bc_aes_key_t decryption_key, const bc_aes_key_t key)
AES derivation decryption key from encryption key.
Definition: bc_aes.c:19
bool bc_aes_ecb_decrypt(void *buffer_out, const void *buffer_in, size_t length, bc_aes_key_t key)
AES decryption Electronic CodeBook (ECB)
Definition: bc_aes.c:66
void bc_aes_init(void)
Initialize AES.
Definition: bc_aes.c:12
uint32_t bc_aes_iv_t[BC_AES_IVLEN/8/4]
AES 128-bit Initialization vector.
Definition: bc_aes.h:19
bc_tick_t bc_tick_get(void)
Get absolute timestamp since start of program.
Definition: bc_tick.c:7
bool bc_aes_cbc_decrypt(void *buffer_out, const void *buffer_in, size_t length, bc_aes_key_t key, bc_aes_iv_t iv)
AES Cipher block chaining (CBC)
Definition: bc_aes.c:96
void bc_aes_iv_from_uint8(bc_aes_iv_t iv, const uint8_t *buffer)
Create Initialization vector from uint8 array.
Definition: bc_aes.c:122
bool bc_aes_cbc_encrypt(void *buffer_out, const void *buffer_in, size_t length, bc_aes_key_t key, bc_aes_iv_t iv)
AES Cipher block chaining (CBC)
Definition: bc_aes.c:80
bool bc_aes_ecb_encrypt(void *buffer_out, const void *buffer_in, const size_t length, const bc_aes_key_t key)
AES encryption Electronic CodeBook (ECB)
Definition: bc_aes.c:52
void bc_aes_key_from_uint8(bc_aes_key_t key, const uint8_t *buffer)
Create key from uint8 array.
Definition: bc_aes.c:112