46#define CCM_STAR_AUTH_FLAGS(AUTH, MICLEN) (((AUTH) ? (1u << 6) : 0) | ((((MICLEN) - 2u) >> 1) << 3) | 1u)
47#define CCM_STAR_ENCRYPTION_FLAGS 1
50#define MAX_A_LEN 0xfeff
52#define MIC_LEN_VALID(x) ((x) >= 4 && (x) <= 16 && (x) % 2 == 0)
62 memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH);
63 iv[14] = counter >> 8;
69ctr_step(
const uint8_t *nonce,
71 uint8_t *m_and_result,
75 uint8_t a[AES_128_BLOCK_SIZE];
78 set_iv(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter);
81 for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
82 m_and_result[pos + i] ^= a[i];
87mic(
const uint8_t *nonce,
88 const uint8_t *m, uint16_t m_len,
89 const uint8_t *a, uint16_t a_len,
93 uint8_t x[AES_128_BLOCK_SIZE];
97 set_iv(x, CCM_STAR_AUTH_FLAGS(a_len > 0, mic_len), nonce, m_len);
101 x[0] = x[0] ^ (a_len >> 8);
103 for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
111 for(i = 0; (pos + i < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
114 pos += AES_128_BLOCK_SIZE;
122 for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
125 pos += AES_128_BLOCK_SIZE;
130 ctr_step(nonce, 0, x, AES_128_BLOCK_SIZE, 0);
132 memcpy(result, x, mic_len);
136ctr(
const uint8_t *nonce, uint8_t *m, uint16_t m_len)
144 ctr_step(nonce, pos, m, m_len, counter++);
145 pos += AES_128_BLOCK_SIZE;
150set_key(
const uint8_t *key)
152 AES_128.set_key(key);
156aead(
const uint8_t* nonce,
157 uint8_t* m, uint16_t m_len,
158 const uint8_t* a, uint16_t a_len,
159 uint8_t *result, uint8_t mic_len,
162 if(a_len > MAX_A_LEN || !MIC_LEN_VALID(mic_len)) {
168 ctr(nonce, m, m_len);
179 ctr(nonce, m, m_len);
Structure of CCM* drivers.
void(* aead)(const uint8_t *nonce, uint8_t *m, uint16_t m_len, const uint8_t *a, uint16_t a_len, uint8_t *result, uint8_t mic_len, int forward)
Combines authentication and encryption.
void(* set_key)(const uint8_t *key)
Sets the key in use.