xref: /btstack/test/crypto/aes_ccm.c (revision ba1e2dc4c93743e601d6cffa4e6a44beac37622a)
1*ba1e2dc4SMatthias Ringwald #include <stdio.h>
2*ba1e2dc4SMatthias Ringwald #include <stdint.h>
3*ba1e2dc4SMatthias Ringwald #include "btstack_util.h"
4*ba1e2dc4SMatthias Ringwald #include "aes_cmac.h"
5*ba1e2dc4SMatthias Ringwald #include <errno.h>
6*ba1e2dc4SMatthias Ringwald #include "aes_ccm.h"
7*ba1e2dc4SMatthias Ringwald 
8*ba1e2dc4SMatthias Ringwald // degbugging
9*ba1e2dc4SMatthias Ringwald // #define LOG_XN
10*ba1e2dc4SMatthias Ringwald 
11*ba1e2dc4SMatthias Ringwald // CCM Encrypt & Decrypt from Zephyr Project
12*ba1e2dc4SMatthias Ringwald 
13*ba1e2dc4SMatthias Ringwald typedef uint8_t  u8_t;
14*ba1e2dc4SMatthias Ringwald typedef uint16_t u16_t;
15*ba1e2dc4SMatthias Ringwald typedef uint64_t u64_t;
16*ba1e2dc4SMatthias Ringwald 
17*ba1e2dc4SMatthias Ringwald static void sys_put_be16(uint16_t value, uint8_t * buffer) {
18*ba1e2dc4SMatthias Ringwald 	big_endian_store_16(buffer, 0, value);
19*ba1e2dc4SMatthias Ringwald }
20*ba1e2dc4SMatthias Ringwald static int bt_encrypt_be(const uint8_t * key, const uint8_t * plain, uint8_t * cipher) {
21*ba1e2dc4SMatthias Ringwald 	aes128_calc_cyphertext(key, plain, cipher);
22*ba1e2dc4SMatthias Ringwald 	return 0;
23*ba1e2dc4SMatthias Ringwald }
24*ba1e2dc4SMatthias Ringwald 
25*ba1e2dc4SMatthias Ringwald int bt_mesh_ccm_decrypt(const u8_t key[16], u8_t nonce[13],
26*ba1e2dc4SMatthias Ringwald 			       const u8_t *enc_msg, size_t msg_len,
27*ba1e2dc4SMatthias Ringwald 			       const u8_t *aad, size_t aad_len,
28*ba1e2dc4SMatthias Ringwald 			       u8_t *out_msg, size_t mic_size)
29*ba1e2dc4SMatthias Ringwald {
30*ba1e2dc4SMatthias Ringwald 	u8_t msg[16], pmsg[16], cmic[16], cmsg[16], Xn[16], mic[16];
31*ba1e2dc4SMatthias Ringwald 	u16_t last_blk, blk_cnt;
32*ba1e2dc4SMatthias Ringwald 	size_t i, j;
33*ba1e2dc4SMatthias Ringwald 	int err;
34*ba1e2dc4SMatthias Ringwald 
35*ba1e2dc4SMatthias Ringwald 	if (msg_len < 1 || aad_len >= 0xff00) {
36*ba1e2dc4SMatthias Ringwald 		return -EINVAL;
37*ba1e2dc4SMatthias Ringwald 	}
38*ba1e2dc4SMatthias Ringwald 
39*ba1e2dc4SMatthias Ringwald 	/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
40*ba1e2dc4SMatthias Ringwald 	pmsg[0] = 0x01;
41*ba1e2dc4SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
42*ba1e2dc4SMatthias Ringwald 	sys_put_be16(0x0000, pmsg + 14);
43*ba1e2dc4SMatthias Ringwald 
44*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
45*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "A0");
46*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
47*ba1e2dc4SMatthias Ringwald #endif
48*ba1e2dc4SMatthias Ringwald 
49*ba1e2dc4SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, cmic);
50*ba1e2dc4SMatthias Ringwald 	if (err) {
51*ba1e2dc4SMatthias Ringwald 		return err;
52*ba1e2dc4SMatthias Ringwald 	}
53*ba1e2dc4SMatthias Ringwald 
54*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
55*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "S0");
56*ba1e2dc4SMatthias Ringwald 	printf_hexdump(cmic, 16);
57*ba1e2dc4SMatthias Ringwald #endif
58*ba1e2dc4SMatthias Ringwald 
59*ba1e2dc4SMatthias Ringwald 
60*ba1e2dc4SMatthias Ringwald 	/* X_0 = e(AppKey, 0x09 || nonce || length) */
61*ba1e2dc4SMatthias Ringwald 	if (mic_size == sizeof(u64_t)) {
62*ba1e2dc4SMatthias Ringwald 		pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
63*ba1e2dc4SMatthias Ringwald 	} else {
64*ba1e2dc4SMatthias Ringwald 		pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
65*ba1e2dc4SMatthias Ringwald 	}
66*ba1e2dc4SMatthias Ringwald 
67*ba1e2dc4SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
68*ba1e2dc4SMatthias Ringwald 	sys_put_be16(msg_len, pmsg + 14);
69*ba1e2dc4SMatthias Ringwald 
70*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
71*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "B0");
72*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
73*ba1e2dc4SMatthias Ringwald #endif
74*ba1e2dc4SMatthias Ringwald 
75*ba1e2dc4SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, Xn);
76*ba1e2dc4SMatthias Ringwald 	if (err) {
77*ba1e2dc4SMatthias Ringwald 		return err;
78*ba1e2dc4SMatthias Ringwald 	}
79*ba1e2dc4SMatthias Ringwald 
80*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
81*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "X1");
82*ba1e2dc4SMatthias Ringwald 	printf_hexdump(Xn, 16);
83*ba1e2dc4SMatthias Ringwald #endif
84*ba1e2dc4SMatthias Ringwald 
85*ba1e2dc4SMatthias Ringwald 	/* If AAD is being used to authenticate, include it here */
86*ba1e2dc4SMatthias Ringwald 	if (aad_len) {
87*ba1e2dc4SMatthias Ringwald 		sys_put_be16(aad_len, pmsg);
88*ba1e2dc4SMatthias Ringwald 
89*ba1e2dc4SMatthias Ringwald 		for (i = 0; i < sizeof(u16_t); i++) {
90*ba1e2dc4SMatthias Ringwald 			pmsg[i] = Xn[i] ^ pmsg[i];
91*ba1e2dc4SMatthias Ringwald 		}
92*ba1e2dc4SMatthias Ringwald 
93*ba1e2dc4SMatthias Ringwald 		j = 0;
94*ba1e2dc4SMatthias Ringwald 		aad_len += sizeof(u16_t);
95*ba1e2dc4SMatthias Ringwald 		while (aad_len > 16) {
96*ba1e2dc4SMatthias Ringwald 			do {
97*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ aad[j];
98*ba1e2dc4SMatthias Ringwald 				i++, j++;
99*ba1e2dc4SMatthias Ringwald 			} while (i < 16);
100*ba1e2dc4SMatthias Ringwald 
101*ba1e2dc4SMatthias Ringwald 			aad_len -= 16;
102*ba1e2dc4SMatthias Ringwald 			i = 0;
103*ba1e2dc4SMatthias Ringwald 
104*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
105*ba1e2dc4SMatthias Ringwald 			if (err) {
106*ba1e2dc4SMatthias Ringwald 				return err;
107*ba1e2dc4SMatthias Ringwald 			}
108*ba1e2dc4SMatthias Ringwald 		}
109*ba1e2dc4SMatthias Ringwald 
110*ba1e2dc4SMatthias Ringwald 		for (i = 0; i < aad_len; i++, j++) {
111*ba1e2dc4SMatthias Ringwald 			pmsg[i] = Xn[i] ^ aad[j];
112*ba1e2dc4SMatthias Ringwald 		}
113*ba1e2dc4SMatthias Ringwald 
114*ba1e2dc4SMatthias Ringwald 		for (i = aad_len; i < 16; i++) {
115*ba1e2dc4SMatthias Ringwald 			pmsg[i] = Xn[i];
116*ba1e2dc4SMatthias Ringwald 		}
117*ba1e2dc4SMatthias Ringwald 
118*ba1e2dc4SMatthias Ringwald 		err = bt_encrypt_be(key, pmsg, Xn);
119*ba1e2dc4SMatthias Ringwald 		if (err) {
120*ba1e2dc4SMatthias Ringwald 			return err;
121*ba1e2dc4SMatthias Ringwald 		}
122*ba1e2dc4SMatthias Ringwald 	}
123*ba1e2dc4SMatthias Ringwald 
124*ba1e2dc4SMatthias Ringwald 	last_blk = msg_len % 16;
125*ba1e2dc4SMatthias Ringwald 	blk_cnt = (msg_len + 15) / 16;
126*ba1e2dc4SMatthias Ringwald 	if (!last_blk) {
127*ba1e2dc4SMatthias Ringwald 		last_blk = 16;
128*ba1e2dc4SMatthias Ringwald 	}
129*ba1e2dc4SMatthias Ringwald 
130*ba1e2dc4SMatthias Ringwald 	for (j = 0; j < blk_cnt; j++) {
131*ba1e2dc4SMatthias Ringwald 		if (j + 1 == blk_cnt) {
132*ba1e2dc4SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
133*ba1e2dc4SMatthias Ringwald 			pmsg[0] = 0x01;
134*ba1e2dc4SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
135*ba1e2dc4SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
136*ba1e2dc4SMatthias Ringwald 
137*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
138*ba1e2dc4SMatthias Ringwald 			if (err) {
139*ba1e2dc4SMatthias Ringwald 				return err;
140*ba1e2dc4SMatthias Ringwald 			}
141*ba1e2dc4SMatthias Ringwald 
142*ba1e2dc4SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_1 */
143*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
144*ba1e2dc4SMatthias Ringwald 				msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
145*ba1e2dc4SMatthias Ringwald 			}
146*ba1e2dc4SMatthias Ringwald 
147*ba1e2dc4SMatthias Ringwald 			memcpy(out_msg + (j * 16), msg, last_blk);
148*ba1e2dc4SMatthias Ringwald 
149*ba1e2dc4SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
150*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
151*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[i];
152*ba1e2dc4SMatthias Ringwald 			}
153*ba1e2dc4SMatthias Ringwald 
154*ba1e2dc4SMatthias Ringwald 			for (i = last_blk; i < 16; i++) {
155*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ 0x00;
156*ba1e2dc4SMatthias Ringwald 			}
157*ba1e2dc4SMatthias Ringwald 
158*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
159*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Xn XOR bn");
160*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
161*ba1e2dc4SMatthias Ringwald #endif
162*ba1e2dc4SMatthias Ringwald 
163*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
164*ba1e2dc4SMatthias Ringwald 			if (err) {
165*ba1e2dc4SMatthias Ringwald 				return err;
166*ba1e2dc4SMatthias Ringwald 			}
167*ba1e2dc4SMatthias Ringwald 
168*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
169*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Xn XOR bn");
170*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
171*ba1e2dc4SMatthias Ringwald #endif
172*ba1e2dc4SMatthias Ringwald 
173*ba1e2dc4SMatthias Ringwald 			/* MIC = C_mic ^ X_1 */
174*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < sizeof(mic); i++) {
175*ba1e2dc4SMatthias Ringwald 				mic[i] = cmic[i] ^ Xn[i];
176*ba1e2dc4SMatthias Ringwald 			}
177*ba1e2dc4SMatthias Ringwald 
178*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
179*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "mic");
180*ba1e2dc4SMatthias Ringwald 	printf_hexdump(mic, 16);
181*ba1e2dc4SMatthias Ringwald #endif
182*ba1e2dc4SMatthias Ringwald 
183*ba1e2dc4SMatthias Ringwald 		} else {
184*ba1e2dc4SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
185*ba1e2dc4SMatthias Ringwald 			pmsg[0] = 0x01;
186*ba1e2dc4SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
187*ba1e2dc4SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
188*ba1e2dc4SMatthias Ringwald 
189*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
190*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Ai");
191*ba1e2dc4SMatthias Ringwald 	printf_hexdump(mic, 16);
192*ba1e2dc4SMatthias Ringwald #endif
193*ba1e2dc4SMatthias Ringwald 
194*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
195*ba1e2dc4SMatthias Ringwald 			if (err) {
196*ba1e2dc4SMatthias Ringwald 				return err;
197*ba1e2dc4SMatthias Ringwald 			}
198*ba1e2dc4SMatthias Ringwald 
199*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
200*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Si");
201*ba1e2dc4SMatthias Ringwald 	printf_hexdump(mic, 16);
202*ba1e2dc4SMatthias Ringwald #endif
203*ba1e2dc4SMatthias Ringwald 
204*ba1e2dc4SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_1 */
205*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < 16; i++) {
206*ba1e2dc4SMatthias Ringwald 				msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
207*ba1e2dc4SMatthias Ringwald 			}
208*ba1e2dc4SMatthias Ringwald 
209*ba1e2dc4SMatthias Ringwald 			memcpy(out_msg + (j * 16), msg, 16);
210*ba1e2dc4SMatthias Ringwald 
211*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
212*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "bn");
213*ba1e2dc4SMatthias Ringwald 	printf_hexdump(msg, 16);
214*ba1e2dc4SMatthias Ringwald #endif
215*ba1e2dc4SMatthias Ringwald 
216*ba1e2dc4SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
217*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < 16; i++) {
218*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[i];
219*ba1e2dc4SMatthias Ringwald 			}
220*ba1e2dc4SMatthias Ringwald 
221*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
222*ba1e2dc4SMatthias Ringwald 			if (err) {
223*ba1e2dc4SMatthias Ringwald 				return err;
224*ba1e2dc4SMatthias Ringwald 			}
225*ba1e2dc4SMatthias Ringwald 
226*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
227*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Xn");
228*ba1e2dc4SMatthias Ringwald 	printf_hexdump(mic, 16);
229*ba1e2dc4SMatthias Ringwald #endif
230*ba1e2dc4SMatthias Ringwald 
231*ba1e2dc4SMatthias Ringwald 
232*ba1e2dc4SMatthias Ringwald 		}
233*ba1e2dc4SMatthias Ringwald 	}
234*ba1e2dc4SMatthias Ringwald 
235*ba1e2dc4SMatthias Ringwald 	if (memcmp(mic, enc_msg + msg_len, mic_size)) {
236*ba1e2dc4SMatthias Ringwald 		return -EBADMSG;
237*ba1e2dc4SMatthias Ringwald 	}
238*ba1e2dc4SMatthias Ringwald 
239*ba1e2dc4SMatthias Ringwald 	return 0;
240*ba1e2dc4SMatthias Ringwald }
241*ba1e2dc4SMatthias Ringwald 
242*ba1e2dc4SMatthias Ringwald int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13],
243*ba1e2dc4SMatthias Ringwald 			       const u8_t *msg, size_t msg_len,
244*ba1e2dc4SMatthias Ringwald 			       const u8_t *aad, size_t aad_len,
245*ba1e2dc4SMatthias Ringwald 			       u8_t *out_msg, size_t mic_size)
246*ba1e2dc4SMatthias Ringwald {
247*ba1e2dc4SMatthias Ringwald 	u8_t pmsg[16], cmic[16], cmsg[16], mic[16], Xn[16];
248*ba1e2dc4SMatthias Ringwald 	u16_t blk_cnt, last_blk;
249*ba1e2dc4SMatthias Ringwald 	size_t i, j;
250*ba1e2dc4SMatthias Ringwald 	int err;
251*ba1e2dc4SMatthias Ringwald 
252*ba1e2dc4SMatthias Ringwald 	// BT_DBG("key %s", bt_hex(key, 16));
253*ba1e2dc4SMatthias Ringwald 	// BT_DBG("nonce %s", bt_hex(nonce, 13));
254*ba1e2dc4SMatthias Ringwald 	// BT_DBG("msg (len %zu) %s", msg_len, bt_hex(msg, msg_len));
255*ba1e2dc4SMatthias Ringwald 	// BT_DBG("aad_len %zu mic_size %zu", aad_len, mic_size);
256*ba1e2dc4SMatthias Ringwald 
257*ba1e2dc4SMatthias Ringwald 	/* Unsupported AAD size */
258*ba1e2dc4SMatthias Ringwald 	if (aad_len >= 0xff00) {
259*ba1e2dc4SMatthias Ringwald 		return -EINVAL;
260*ba1e2dc4SMatthias Ringwald 	}
261*ba1e2dc4SMatthias Ringwald 
262*ba1e2dc4SMatthias Ringwald 	/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
263*ba1e2dc4SMatthias Ringwald 	pmsg[0] = 0x01;
264*ba1e2dc4SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
265*ba1e2dc4SMatthias Ringwald 	sys_put_be16(0x0000, pmsg + 14);
266*ba1e2dc4SMatthias Ringwald 
267*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
268*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "A0");
269*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
270*ba1e2dc4SMatthias Ringwald #endif
271*ba1e2dc4SMatthias Ringwald 
272*ba1e2dc4SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, cmic);
273*ba1e2dc4SMatthias Ringwald 	if (err) {
274*ba1e2dc4SMatthias Ringwald 		return err;
275*ba1e2dc4SMatthias Ringwald 	}
276*ba1e2dc4SMatthias Ringwald 
277*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
278*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "S0");
279*ba1e2dc4SMatthias Ringwald 	printf_hexdump(cmic, 16);
280*ba1e2dc4SMatthias Ringwald #endif
281*ba1e2dc4SMatthias Ringwald 
282*ba1e2dc4SMatthias Ringwald 	/* X_0 = e(AppKey, 0x09 || nonce || length) */
283*ba1e2dc4SMatthias Ringwald 	if (mic_size == sizeof(u64_t)) {
284*ba1e2dc4SMatthias Ringwald 		pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
285*ba1e2dc4SMatthias Ringwald 	} else {
286*ba1e2dc4SMatthias Ringwald 		pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
287*ba1e2dc4SMatthias Ringwald 	}
288*ba1e2dc4SMatthias Ringwald 
289*ba1e2dc4SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
290*ba1e2dc4SMatthias Ringwald 	sys_put_be16(msg_len, pmsg + 14);
291*ba1e2dc4SMatthias Ringwald 
292*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
293*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "B0");
294*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
295*ba1e2dc4SMatthias Ringwald #endif
296*ba1e2dc4SMatthias Ringwald 
297*ba1e2dc4SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, Xn);
298*ba1e2dc4SMatthias Ringwald 	if (err) {
299*ba1e2dc4SMatthias Ringwald 		return err;
300*ba1e2dc4SMatthias Ringwald 	}
301*ba1e2dc4SMatthias Ringwald 
302*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
303*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "X1");
304*ba1e2dc4SMatthias Ringwald 	printf_hexdump(Xn, 16);
305*ba1e2dc4SMatthias Ringwald #endif
306*ba1e2dc4SMatthias Ringwald 
307*ba1e2dc4SMatthias Ringwald 	/* If AAD is being used to authenticate, include it here */
308*ba1e2dc4SMatthias Ringwald 	if (aad_len) {
309*ba1e2dc4SMatthias Ringwald 		sys_put_be16(aad_len, pmsg);
310*ba1e2dc4SMatthias Ringwald 
311*ba1e2dc4SMatthias Ringwald 		for (i = 0; i < sizeof(u16_t); i++) {
312*ba1e2dc4SMatthias Ringwald 			pmsg[i] = Xn[i] ^ pmsg[i];
313*ba1e2dc4SMatthias Ringwald 		}
314*ba1e2dc4SMatthias Ringwald 
315*ba1e2dc4SMatthias Ringwald 		j = 0;
316*ba1e2dc4SMatthias Ringwald 		aad_len += sizeof(u16_t);
317*ba1e2dc4SMatthias Ringwald 		while (aad_len > 16) {
318*ba1e2dc4SMatthias Ringwald 			do {
319*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ aad[j];
320*ba1e2dc4SMatthias Ringwald 				i++, j++;
321*ba1e2dc4SMatthias Ringwald 			} while (i < 16);
322*ba1e2dc4SMatthias Ringwald 
323*ba1e2dc4SMatthias Ringwald 			aad_len -= 16;
324*ba1e2dc4SMatthias Ringwald 			i = 0;
325*ba1e2dc4SMatthias Ringwald 
326*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
327*ba1e2dc4SMatthias Ringwald 			if (err) {
328*ba1e2dc4SMatthias Ringwald 				return err;
329*ba1e2dc4SMatthias Ringwald 			}
330*ba1e2dc4SMatthias Ringwald 		}
331*ba1e2dc4SMatthias Ringwald 
332*ba1e2dc4SMatthias Ringwald 		for (i = 0; i < aad_len; i++, j++) {
333*ba1e2dc4SMatthias Ringwald 			pmsg[i] = Xn[i] ^ aad[j];
334*ba1e2dc4SMatthias Ringwald 		}
335*ba1e2dc4SMatthias Ringwald 
336*ba1e2dc4SMatthias Ringwald 		for (i = aad_len; i < 16; i++) {
337*ba1e2dc4SMatthias Ringwald 			pmsg[i] = Xn[i];
338*ba1e2dc4SMatthias Ringwald 		}
339*ba1e2dc4SMatthias Ringwald 
340*ba1e2dc4SMatthias Ringwald 		err = bt_encrypt_be(key, pmsg, Xn);
341*ba1e2dc4SMatthias Ringwald 		if (err) {
342*ba1e2dc4SMatthias Ringwald 			return err;
343*ba1e2dc4SMatthias Ringwald 		}
344*ba1e2dc4SMatthias Ringwald 	}
345*ba1e2dc4SMatthias Ringwald 
346*ba1e2dc4SMatthias Ringwald 	last_blk = msg_len % 16;
347*ba1e2dc4SMatthias Ringwald 	blk_cnt = (msg_len + 15) / 16;
348*ba1e2dc4SMatthias Ringwald 	if (!last_blk) {
349*ba1e2dc4SMatthias Ringwald 		last_blk = 16;
350*ba1e2dc4SMatthias Ringwald 	}
351*ba1e2dc4SMatthias Ringwald 
352*ba1e2dc4SMatthias Ringwald 	for (j = 0; j < blk_cnt; j++) {
353*ba1e2dc4SMatthias Ringwald 		if (j + 1 == blk_cnt) {
354*ba1e2dc4SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
355*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
356*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
357*ba1e2dc4SMatthias Ringwald 			}
358*ba1e2dc4SMatthias Ringwald 			for (i = last_blk; i < 16; i++) {
359*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ 0x00;
360*ba1e2dc4SMatthias Ringwald 			}
361*ba1e2dc4SMatthias Ringwald 
362*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
363*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Xn XOR Bn");
364*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
365*ba1e2dc4SMatthias Ringwald #endif
366*ba1e2dc4SMatthias Ringwald 
367*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
368*ba1e2dc4SMatthias Ringwald 			if (err) {
369*ba1e2dc4SMatthias Ringwald 				return err;
370*ba1e2dc4SMatthias Ringwald 			}
371*ba1e2dc4SMatthias Ringwald 
372*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
373*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Xn+1");
374*ba1e2dc4SMatthias Ringwald 	printf_hexdump(Xn, 16);
375*ba1e2dc4SMatthias Ringwald #endif
376*ba1e2dc4SMatthias Ringwald 
377*ba1e2dc4SMatthias Ringwald 			/* MIC = C_mic ^ X_1 */
378*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < sizeof(mic); i++) {
379*ba1e2dc4SMatthias Ringwald 				mic[i] = cmic[i] ^ Xn[i];
380*ba1e2dc4SMatthias Ringwald 			}
381*ba1e2dc4SMatthias Ringwald 
382*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
383*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "mic");
384*ba1e2dc4SMatthias Ringwald 	printf_hexdump(mic, 16);
385*ba1e2dc4SMatthias Ringwald #endif
386*ba1e2dc4SMatthias Ringwald 
387*ba1e2dc4SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
388*ba1e2dc4SMatthias Ringwald 			pmsg[0] = 0x01;
389*ba1e2dc4SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
390*ba1e2dc4SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
391*ba1e2dc4SMatthias Ringwald 
392*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
393*ba1e2dc4SMatthias Ringwald 			if (err) {
394*ba1e2dc4SMatthias Ringwald 				return err;
395*ba1e2dc4SMatthias Ringwald 			}
396*ba1e2dc4SMatthias Ringwald 
397*ba1e2dc4SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_1 */
398*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
399*ba1e2dc4SMatthias Ringwald 				out_msg[(j * 16) + i] =
400*ba1e2dc4SMatthias Ringwald 					msg[(j * 16) + i] ^ cmsg[i];
401*ba1e2dc4SMatthias Ringwald 			}
402*ba1e2dc4SMatthias Ringwald 		} else {
403*ba1e2dc4SMatthias Ringwald 
404*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
405*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "bn");
406*ba1e2dc4SMatthias Ringwald 	printf_hexdump(msg, 16);
407*ba1e2dc4SMatthias Ringwald #endif
408*ba1e2dc4SMatthias Ringwald 
409*ba1e2dc4SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
410*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < 16; i++) {
411*ba1e2dc4SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
412*ba1e2dc4SMatthias Ringwald 			}
413*ba1e2dc4SMatthias Ringwald 
414*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
415*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Xn XOR Bn");
416*ba1e2dc4SMatthias Ringwald 	printf_hexdump(pmsg, 16);
417*ba1e2dc4SMatthias Ringwald #endif
418*ba1e2dc4SMatthias Ringwald 
419*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
420*ba1e2dc4SMatthias Ringwald 			if (err) {
421*ba1e2dc4SMatthias Ringwald 				return err;
422*ba1e2dc4SMatthias Ringwald 			}
423*ba1e2dc4SMatthias Ringwald 
424*ba1e2dc4SMatthias Ringwald #ifdef LOG_XN
425*ba1e2dc4SMatthias Ringwald 	printf("%16s: ", "Xn+1");
426*ba1e2dc4SMatthias Ringwald 	printf_hexdump(Xn, 16);
427*ba1e2dc4SMatthias Ringwald #endif
428*ba1e2dc4SMatthias Ringwald 
429*ba1e2dc4SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
430*ba1e2dc4SMatthias Ringwald 			pmsg[0] = 0x01;
431*ba1e2dc4SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
432*ba1e2dc4SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
433*ba1e2dc4SMatthias Ringwald 
434*ba1e2dc4SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
435*ba1e2dc4SMatthias Ringwald 			if (err) {
436*ba1e2dc4SMatthias Ringwald 				return err;
437*ba1e2dc4SMatthias Ringwald 			}
438*ba1e2dc4SMatthias Ringwald 
439*ba1e2dc4SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_N */
440*ba1e2dc4SMatthias Ringwald 			for (i = 0; i < 16; i++) {
441*ba1e2dc4SMatthias Ringwald 				out_msg[(j * 16) + i] =
442*ba1e2dc4SMatthias Ringwald 					msg[(j * 16) + i] ^ cmsg[i];
443*ba1e2dc4SMatthias Ringwald 			}
444*ba1e2dc4SMatthias Ringwald 
445*ba1e2dc4SMatthias Ringwald 		}
446*ba1e2dc4SMatthias Ringwald 	}
447*ba1e2dc4SMatthias Ringwald 
448*ba1e2dc4SMatthias Ringwald 	memcpy(out_msg + msg_len, mic, mic_size);
449*ba1e2dc4SMatthias Ringwald 
450*ba1e2dc4SMatthias Ringwald 	return 0;
451*ba1e2dc4SMatthias Ringwald }
452