Contiki-NG
Loading...
Searching...
No Matches
ccm-star.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013, Hasso-Plattner-Institut.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 */
32
33/**
34 * \addtogroup crypto
35 * @{
36 * \file
37 * AES_128-based CCM* implementation.
38 * \author
39 * Konrad Krentz <konrad.krentz@gmail.com>
40 * Justin King-Lacroix <justin.kinglacroix@gmail.com>
41 */
42
43#include "ccm-star.h"
44#include "lib/aes-128.h"
45#include <string.h>
46
47/* As per RFC 3610. L == 2 (m_len is two bytes long). */
48#define CCM_STAR_AUTH_FLAGS(a_len, mic_len) (((a_len) ? 1u << 6 : 0) \
49 | ((((mic_len) - 2u) >> 1) << 3) \
50 | 1u)
51#define CCM_STAR_ENCRYPTION_FLAGS 1
52/* Valid values are 4, 6, 8, 10, 12, 14, and 16 octets */
53#define MIC_LEN_VALID(x) ((x) >= 4 && (x) <= 16 && (x) % 2 == 0)
54
55/*---------------------------------------------------------------------------*/
56static void
57set_iv(uint8_t *iv,
58 uint8_t flags,
59 const uint8_t *nonce,
60 uint16_t counter)
61{
62 iv[0] = flags;
63 memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH);
64 iv[14] = counter >> 8;
65 iv[15] = counter;
66}
67/*---------------------------------------------------------------------------*/
68/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */
69static void
70ctr_step(const uint8_t *nonce,
71 uint16_t pos,
72 uint8_t *m_and_result, uint16_t m_len,
73 uint16_t counter)
74{
75 uint8_t a[AES_128_BLOCK_SIZE];
76
77 set_iv(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter);
78 AES_128.encrypt(a);
79
80 for(uint_fast8_t i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
81 m_and_result[pos + i] ^= a[i];
82 }
83}
84/*---------------------------------------------------------------------------*/
85static void
86mic(const uint8_t *nonce,
87 const uint8_t *m, uint16_t m_len,
88 const uint8_t *a, uint16_t a_len,
89 uint8_t *result, uint8_t mic_len)
90{
91 uint8_t x[AES_128_BLOCK_SIZE];
92
93 set_iv(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len);
94 AES_128.encrypt(x);
95
96 if(a_len) {
97 x[0] ^= (a_len >> 8);
98 x[1] ^= a_len;
99 uint32_t pos;
100 for(pos = 0; (pos < a_len) && (pos < AES_128_BLOCK_SIZE - 2); pos++) {
101 x[2 + pos] ^= a[pos];
102 }
103
104 AES_128.encrypt(x);
105
106 /* 32-bit pos to reach the end of the loop if a_len is large */
107 for(; pos < a_len; pos += AES_128_BLOCK_SIZE) {
108 for(uint_fast8_t i = 0;
109 (pos + i < a_len) && (i < AES_128_BLOCK_SIZE);
110 i++) {
111 x[i] ^= a[pos + i];
112 }
113 AES_128.encrypt(x);
114 }
115 }
116
117 if(m_len) {
118 /* 32-bit pos to reach the end of the loop if m_len is large */
119 for(uint32_t pos = 0; pos < m_len; pos += AES_128_BLOCK_SIZE) {
120 for(uint_fast8_t i = 0;
121 (pos + i < m_len) && (i < AES_128_BLOCK_SIZE);
122 i++) {
123 x[i] ^= m[pos + i];
124 }
125 AES_128.encrypt(x);
126 }
127 }
128
129 ctr_step(nonce, 0, x, AES_128_BLOCK_SIZE, 0);
130
131 memcpy(result, x, mic_len);
132}
133/*---------------------------------------------------------------------------*/
134static void
135ctr(const uint8_t *nonce, uint8_t *m, uint16_t m_len)
136{
137 uint16_t counter = 1;
138 /* 32-bit pos to reach the end of the loop if m_len is large */
139 for(uint32_t pos = 0; pos < m_len; pos += AES_128_BLOCK_SIZE) {
140 ctr_step(nonce, pos, m, m_len, counter++);
141 }
142}
143/*---------------------------------------------------------------------------*/
144static void
145set_key(const uint8_t *key)
146{
147 AES_128.set_key(key);
148}
149/*---------------------------------------------------------------------------*/
150static void
151aead(const uint8_t *nonce,
152 uint8_t *m, uint16_t m_len,
153 const uint8_t *a, uint16_t a_len,
154 uint8_t *result, uint8_t mic_len,
155 int forward)
156{
157 if(!MIC_LEN_VALID(mic_len)) {
158 return;
159 }
160
161 if(!forward) {
162 /* decrypt */
163 ctr(nonce, m, m_len);
164 }
165
166 mic(nonce,
167 m, m_len,
168 a, a_len,
169 result,
170 mic_len);
171
172 if(forward) {
173 /* encrypt */
174 ctr(nonce, m, m_len);
175 }
176}
177/*---------------------------------------------------------------------------*/
178const struct ccm_star_driver ccm_star_driver = {
179 set_key,
180 aead
181};
182/*---------------------------------------------------------------------------*/
183
184/** @} */
AES-128.
static volatile at86rf215_flags_t flags
The radio driver uses the following flags to keep track of the current state of the radio and IRQ eve...
Definition at86rf215.c:144
CCM* header file.
Structure of CCM* drivers.
Definition ccm-star.h:58
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.
Definition ccm-star.h:77
void(* set_key)(const uint8_t *key)
Sets the key in use.
Definition ccm-star.h:66