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