xref: /btstack/test/crypto/aes_ccm_test.c (revision 75ba91cf9c57cf2e084f5652aaeef7907e852232)
181132a39SMatthias Ringwald #include <stdio.h>
281132a39SMatthias Ringwald #include <stdint.h>
381132a39SMatthias Ringwald #include "btstack_util.h"
481132a39SMatthias Ringwald #include "aes_cmac.h"
581132a39SMatthias Ringwald #include <errno.h>
681132a39SMatthias Ringwald 
7*75ba91cfSMatthias Ringwald // degbugging
8*75ba91cfSMatthias Ringwald // #define LOG_XN
9*75ba91cfSMatthias Ringwald 
1081132a39SMatthias Ringwald typedef uint8_t key_t[16];
1181132a39SMatthias Ringwald 
1281132a39SMatthias Ringwald #define LOG_KEY(NAME) { printf("%16s: ", #NAME); printf_hexdump(NAME, 16); }
1381132a39SMatthias Ringwald #define PARSE_KEY(NAME) { parse_hex(NAME, NAME##_string); LOG_KEY(NAME); }
1481132a39SMatthias Ringwald #define DEFINE_KEY(NAME, VALUE) key_t NAME; parse_hex(NAME, VALUE); LOG_KEY(NAME);
1581132a39SMatthias Ringwald 
1681132a39SMatthias Ringwald static int parse_hex(uint8_t * buffer, const char * hex_string){
1781132a39SMatthias Ringwald 	int len = 0;
1881132a39SMatthias Ringwald 	while (*hex_string){
1981132a39SMatthias Ringwald 		if (*hex_string == ' '){
2081132a39SMatthias Ringwald 			hex_string++;
2181132a39SMatthias Ringwald 			continue;
2281132a39SMatthias Ringwald 		}
2381132a39SMatthias Ringwald 		int high_nibble = nibble_for_char(*hex_string++);
2481132a39SMatthias Ringwald 		int low_nibble = nibble_for_char(*hex_string++);
2581132a39SMatthias Ringwald 		*buffer++ = (high_nibble << 4) | low_nibble;
2681132a39SMatthias Ringwald 		len++;
2781132a39SMatthias Ringwald 	}
2881132a39SMatthias Ringwald 	return len;
2981132a39SMatthias Ringwald }
3081132a39SMatthias Ringwald 
3181132a39SMatthias Ringwald // CCM Encrypt & Decrypt from Zephyr Project
3281132a39SMatthias Ringwald 
3381132a39SMatthias Ringwald typedef uint8_t  u8_t;
3481132a39SMatthias Ringwald typedef uint16_t u16_t;
3581132a39SMatthias Ringwald typedef uint64_t u64_t;
3681132a39SMatthias Ringwald 
3781132a39SMatthias Ringwald static void sys_put_be16(uint16_t value, uint8_t * buffer) {
3881132a39SMatthias Ringwald 	big_endian_store_16(buffer, 0, value);
3981132a39SMatthias Ringwald }
4081132a39SMatthias Ringwald static int bt_encrypt_be(const uint8_t * key, const uint8_t * plain, uint8_t * cipher) {
4181132a39SMatthias Ringwald 	aes128_calc_cyphertext(key, plain, cipher);
4281132a39SMatthias Ringwald 	return 0;
4381132a39SMatthias Ringwald }
4481132a39SMatthias Ringwald 
4581132a39SMatthias Ringwald static int bt_mesh_ccm_decrypt(const u8_t key[16], u8_t nonce[13],
4681132a39SMatthias Ringwald 			       const u8_t *enc_msg, size_t msg_len,
4781132a39SMatthias Ringwald 			       const u8_t *aad, size_t aad_len,
4881132a39SMatthias Ringwald 			       u8_t *out_msg, size_t mic_size)
4981132a39SMatthias Ringwald {
5081132a39SMatthias Ringwald 	u8_t msg[16], pmsg[16], cmic[16], cmsg[16], Xn[16], mic[16];
5181132a39SMatthias Ringwald 	u16_t last_blk, blk_cnt;
5281132a39SMatthias Ringwald 	size_t i, j;
5381132a39SMatthias Ringwald 	int err;
5481132a39SMatthias Ringwald 
5581132a39SMatthias Ringwald 	if (msg_len < 1 || aad_len >= 0xff00) {
5681132a39SMatthias Ringwald 		return -EINVAL;
5781132a39SMatthias Ringwald 	}
5881132a39SMatthias Ringwald 
5981132a39SMatthias Ringwald 	/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
6081132a39SMatthias Ringwald 	pmsg[0] = 0x01;
6181132a39SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
6281132a39SMatthias Ringwald 	sys_put_be16(0x0000, pmsg + 14);
6381132a39SMatthias Ringwald 
64*75ba91cfSMatthias Ringwald #ifdef LOG_XN
65*75ba91cfSMatthias Ringwald 	printf("%16s: ", "A0");
66*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
67*75ba91cfSMatthias Ringwald #endif
68*75ba91cfSMatthias Ringwald 
6981132a39SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, cmic);
7081132a39SMatthias Ringwald 	if (err) {
7181132a39SMatthias Ringwald 		return err;
7281132a39SMatthias Ringwald 	}
7381132a39SMatthias Ringwald 
74*75ba91cfSMatthias Ringwald #ifdef LOG_XN
75*75ba91cfSMatthias Ringwald 	printf("%16s: ", "S0");
76*75ba91cfSMatthias Ringwald 	printf_hexdump(cmic, 16);
77*75ba91cfSMatthias Ringwald #endif
78*75ba91cfSMatthias Ringwald 
79*75ba91cfSMatthias Ringwald 
8081132a39SMatthias Ringwald 	/* X_0 = e(AppKey, 0x09 || nonce || length) */
8181132a39SMatthias Ringwald 	if (mic_size == sizeof(u64_t)) {
8281132a39SMatthias Ringwald 		pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
8381132a39SMatthias Ringwald 	} else {
8481132a39SMatthias Ringwald 		pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
8581132a39SMatthias Ringwald 	}
8681132a39SMatthias Ringwald 
8781132a39SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
8881132a39SMatthias Ringwald 	sys_put_be16(msg_len, pmsg + 14);
8981132a39SMatthias Ringwald 
90*75ba91cfSMatthias Ringwald #ifdef LOG_XN
91*75ba91cfSMatthias Ringwald 	printf("%16s: ", "B0");
92*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
93*75ba91cfSMatthias Ringwald #endif
94*75ba91cfSMatthias Ringwald 
9581132a39SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, Xn);
9681132a39SMatthias Ringwald 	if (err) {
9781132a39SMatthias Ringwald 		return err;
9881132a39SMatthias Ringwald 	}
9981132a39SMatthias Ringwald 
100*75ba91cfSMatthias Ringwald #ifdef LOG_XN
101*75ba91cfSMatthias Ringwald 	printf("%16s: ", "X1");
102*75ba91cfSMatthias Ringwald 	printf_hexdump(Xn, 16);
103*75ba91cfSMatthias Ringwald #endif
104*75ba91cfSMatthias Ringwald 
10581132a39SMatthias Ringwald 	/* If AAD is being used to authenticate, include it here */
10681132a39SMatthias Ringwald 	if (aad_len) {
10781132a39SMatthias Ringwald 		sys_put_be16(aad_len, pmsg);
10881132a39SMatthias Ringwald 
10981132a39SMatthias Ringwald 		for (i = 0; i < sizeof(u16_t); i++) {
11081132a39SMatthias Ringwald 			pmsg[i] = Xn[i] ^ pmsg[i];
11181132a39SMatthias Ringwald 		}
11281132a39SMatthias Ringwald 
11381132a39SMatthias Ringwald 		j = 0;
11481132a39SMatthias Ringwald 		aad_len += sizeof(u16_t);
11581132a39SMatthias Ringwald 		while (aad_len > 16) {
11681132a39SMatthias Ringwald 			do {
11781132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ aad[j];
11881132a39SMatthias Ringwald 				i++, j++;
11981132a39SMatthias Ringwald 			} while (i < 16);
12081132a39SMatthias Ringwald 
12181132a39SMatthias Ringwald 			aad_len -= 16;
12281132a39SMatthias Ringwald 			i = 0;
12381132a39SMatthias Ringwald 
12481132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
12581132a39SMatthias Ringwald 			if (err) {
12681132a39SMatthias Ringwald 				return err;
12781132a39SMatthias Ringwald 			}
12881132a39SMatthias Ringwald 		}
12981132a39SMatthias Ringwald 
13081132a39SMatthias Ringwald 		for (i = 0; i < aad_len; i++, j++) {
13181132a39SMatthias Ringwald 			pmsg[i] = Xn[i] ^ aad[j];
13281132a39SMatthias Ringwald 		}
13381132a39SMatthias Ringwald 
13481132a39SMatthias Ringwald 		for (i = aad_len; i < 16; i++) {
13581132a39SMatthias Ringwald 			pmsg[i] = Xn[i];
13681132a39SMatthias Ringwald 		}
13781132a39SMatthias Ringwald 
13881132a39SMatthias Ringwald 		err = bt_encrypt_be(key, pmsg, Xn);
13981132a39SMatthias Ringwald 		if (err) {
14081132a39SMatthias Ringwald 			return err;
14181132a39SMatthias Ringwald 		}
14281132a39SMatthias Ringwald 	}
14381132a39SMatthias Ringwald 
14481132a39SMatthias Ringwald 	last_blk = msg_len % 16;
14581132a39SMatthias Ringwald 	blk_cnt = (msg_len + 15) / 16;
14681132a39SMatthias Ringwald 	if (!last_blk) {
14781132a39SMatthias Ringwald 		last_blk = 16;
14881132a39SMatthias Ringwald 	}
14981132a39SMatthias Ringwald 
15081132a39SMatthias Ringwald 	for (j = 0; j < blk_cnt; j++) {
15181132a39SMatthias Ringwald 		if (j + 1 == blk_cnt) {
15281132a39SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
15381132a39SMatthias Ringwald 			pmsg[0] = 0x01;
15481132a39SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
15581132a39SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
15681132a39SMatthias Ringwald 
15781132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
15881132a39SMatthias Ringwald 			if (err) {
15981132a39SMatthias Ringwald 				return err;
16081132a39SMatthias Ringwald 			}
16181132a39SMatthias Ringwald 
16281132a39SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_1 */
16381132a39SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
16481132a39SMatthias Ringwald 				msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
16581132a39SMatthias Ringwald 			}
16681132a39SMatthias Ringwald 
16781132a39SMatthias Ringwald 			memcpy(out_msg + (j * 16), msg, last_blk);
16881132a39SMatthias Ringwald 
16981132a39SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
17081132a39SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
17181132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[i];
17281132a39SMatthias Ringwald 			}
17381132a39SMatthias Ringwald 
17481132a39SMatthias Ringwald 			for (i = last_blk; i < 16; i++) {
17581132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ 0x00;
17681132a39SMatthias Ringwald 			}
17781132a39SMatthias Ringwald 
178*75ba91cfSMatthias Ringwald #ifdef LOG_XN
179*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Xn XOR bn");
180*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
181*75ba91cfSMatthias Ringwald #endif
182*75ba91cfSMatthias Ringwald 
18381132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
18481132a39SMatthias Ringwald 			if (err) {
18581132a39SMatthias Ringwald 				return err;
18681132a39SMatthias Ringwald 			}
18781132a39SMatthias Ringwald 
188*75ba91cfSMatthias Ringwald #ifdef LOG_XN
189*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Xn XOR bn");
190*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
191*75ba91cfSMatthias Ringwald #endif
192*75ba91cfSMatthias Ringwald 
19381132a39SMatthias Ringwald 			/* MIC = C_mic ^ X_1 */
19481132a39SMatthias Ringwald 			for (i = 0; i < sizeof(mic); i++) {
19581132a39SMatthias Ringwald 				mic[i] = cmic[i] ^ Xn[i];
19681132a39SMatthias Ringwald 			}
197*75ba91cfSMatthias Ringwald 
198*75ba91cfSMatthias Ringwald #ifdef LOG_XN
199*75ba91cfSMatthias Ringwald 	printf("%16s: ", "mic");
200*75ba91cfSMatthias Ringwald 	printf_hexdump(mic, 16);
201*75ba91cfSMatthias Ringwald #endif
202*75ba91cfSMatthias Ringwald 
20381132a39SMatthias Ringwald 		} else {
20481132a39SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
20581132a39SMatthias Ringwald 			pmsg[0] = 0x01;
20681132a39SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
20781132a39SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
20881132a39SMatthias Ringwald 
209*75ba91cfSMatthias Ringwald #ifdef LOG_XN
210*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Ai");
211*75ba91cfSMatthias Ringwald 	printf_hexdump(mic, 16);
212*75ba91cfSMatthias Ringwald #endif
213*75ba91cfSMatthias Ringwald 
21481132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
21581132a39SMatthias Ringwald 			if (err) {
21681132a39SMatthias Ringwald 				return err;
21781132a39SMatthias Ringwald 			}
21881132a39SMatthias Ringwald 
219*75ba91cfSMatthias Ringwald #ifdef LOG_XN
220*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Si");
221*75ba91cfSMatthias Ringwald 	printf_hexdump(mic, 16);
222*75ba91cfSMatthias Ringwald #endif
223*75ba91cfSMatthias Ringwald 
22481132a39SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_1 */
22581132a39SMatthias Ringwald 			for (i = 0; i < 16; i++) {
22681132a39SMatthias Ringwald 				msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
22781132a39SMatthias Ringwald 			}
22881132a39SMatthias Ringwald 
22981132a39SMatthias Ringwald 			memcpy(out_msg + (j * 16), msg, 16);
23081132a39SMatthias Ringwald 
231*75ba91cfSMatthias Ringwald #ifdef LOG_XN
232*75ba91cfSMatthias Ringwald 	printf("%16s: ", "bn");
233*75ba91cfSMatthias Ringwald 	printf_hexdump(msg, 16);
234*75ba91cfSMatthias Ringwald #endif
235*75ba91cfSMatthias Ringwald 
23681132a39SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
23781132a39SMatthias Ringwald 			for (i = 0; i < 16; i++) {
23881132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[i];
23981132a39SMatthias Ringwald 			}
24081132a39SMatthias Ringwald 
24181132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
24281132a39SMatthias Ringwald 			if (err) {
24381132a39SMatthias Ringwald 				return err;
24481132a39SMatthias Ringwald 			}
245*75ba91cfSMatthias Ringwald 
246*75ba91cfSMatthias Ringwald #ifdef LOG_XN
247*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Xn");
248*75ba91cfSMatthias Ringwald 	printf_hexdump(mic, 16);
249*75ba91cfSMatthias Ringwald #endif
250*75ba91cfSMatthias Ringwald 
251*75ba91cfSMatthias Ringwald 
25281132a39SMatthias Ringwald 		}
25381132a39SMatthias Ringwald 	}
25481132a39SMatthias Ringwald 
25581132a39SMatthias Ringwald 	if (memcmp(mic, enc_msg + msg_len, mic_size)) {
25681132a39SMatthias Ringwald 		return -EBADMSG;
25781132a39SMatthias Ringwald 	}
25881132a39SMatthias Ringwald 
25981132a39SMatthias Ringwald 	return 0;
26081132a39SMatthias Ringwald }
26181132a39SMatthias Ringwald static int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13],
26281132a39SMatthias Ringwald 			       const u8_t *msg, size_t msg_len,
26381132a39SMatthias Ringwald 			       const u8_t *aad, size_t aad_len,
26481132a39SMatthias Ringwald 			       u8_t *out_msg, size_t mic_size)
26581132a39SMatthias Ringwald {
26681132a39SMatthias Ringwald 	u8_t pmsg[16], cmic[16], cmsg[16], mic[16], Xn[16];
26781132a39SMatthias Ringwald 	u16_t blk_cnt, last_blk;
26881132a39SMatthias Ringwald 	size_t i, j;
26981132a39SMatthias Ringwald 	int err;
27081132a39SMatthias Ringwald 
27181132a39SMatthias Ringwald 	// BT_DBG("key %s", bt_hex(key, 16));
27281132a39SMatthias Ringwald 	// BT_DBG("nonce %s", bt_hex(nonce, 13));
27381132a39SMatthias Ringwald 	// BT_DBG("msg (len %zu) %s", msg_len, bt_hex(msg, msg_len));
27481132a39SMatthias Ringwald 	// BT_DBG("aad_len %zu mic_size %zu", aad_len, mic_size);
27581132a39SMatthias Ringwald 
27681132a39SMatthias Ringwald 	/* Unsupported AAD size */
27781132a39SMatthias Ringwald 	if (aad_len >= 0xff00) {
27881132a39SMatthias Ringwald 		return -EINVAL;
27981132a39SMatthias Ringwald 	}
28081132a39SMatthias Ringwald 
28181132a39SMatthias Ringwald 	/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
28281132a39SMatthias Ringwald 	pmsg[0] = 0x01;
28381132a39SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
28481132a39SMatthias Ringwald 	sys_put_be16(0x0000, pmsg + 14);
28581132a39SMatthias Ringwald 
286*75ba91cfSMatthias Ringwald #ifdef LOG_XN
287*75ba91cfSMatthias Ringwald 	printf("%16s: ", "A0");
288*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
289*75ba91cfSMatthias Ringwald #endif
290*75ba91cfSMatthias Ringwald 
29181132a39SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, cmic);
29281132a39SMatthias Ringwald 	if (err) {
29381132a39SMatthias Ringwald 		return err;
29481132a39SMatthias Ringwald 	}
29581132a39SMatthias Ringwald 
296*75ba91cfSMatthias Ringwald #ifdef LOG_XN
297*75ba91cfSMatthias Ringwald 	printf("%16s: ", "S0");
298*75ba91cfSMatthias Ringwald 	printf_hexdump(cmic, 16);
299*75ba91cfSMatthias Ringwald #endif
300*75ba91cfSMatthias Ringwald 
30181132a39SMatthias Ringwald 	/* X_0 = e(AppKey, 0x09 || nonce || length) */
30281132a39SMatthias Ringwald 	if (mic_size == sizeof(u64_t)) {
30381132a39SMatthias Ringwald 		pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
30481132a39SMatthias Ringwald 	} else {
30581132a39SMatthias Ringwald 		pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
30681132a39SMatthias Ringwald 	}
30781132a39SMatthias Ringwald 
30881132a39SMatthias Ringwald 	memcpy(pmsg + 1, nonce, 13);
30981132a39SMatthias Ringwald 	sys_put_be16(msg_len, pmsg + 14);
31081132a39SMatthias Ringwald 
311*75ba91cfSMatthias Ringwald #ifdef LOG_XN
312*75ba91cfSMatthias Ringwald 	printf("%16s: ", "B0");
313*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
314*75ba91cfSMatthias Ringwald #endif
315*75ba91cfSMatthias Ringwald 
31681132a39SMatthias Ringwald 	err = bt_encrypt_be(key, pmsg, Xn);
31781132a39SMatthias Ringwald 	if (err) {
31881132a39SMatthias Ringwald 		return err;
31981132a39SMatthias Ringwald 	}
32081132a39SMatthias Ringwald 
321*75ba91cfSMatthias Ringwald #ifdef LOG_XN
322*75ba91cfSMatthias Ringwald 	printf("%16s: ", "X1");
323*75ba91cfSMatthias Ringwald 	printf_hexdump(Xn, 16);
324*75ba91cfSMatthias Ringwald #endif
325*75ba91cfSMatthias Ringwald 
32681132a39SMatthias Ringwald 	/* If AAD is being used to authenticate, include it here */
32781132a39SMatthias Ringwald 	if (aad_len) {
32881132a39SMatthias Ringwald 		sys_put_be16(aad_len, pmsg);
32981132a39SMatthias Ringwald 
33081132a39SMatthias Ringwald 		for (i = 0; i < sizeof(u16_t); i++) {
33181132a39SMatthias Ringwald 			pmsg[i] = Xn[i] ^ pmsg[i];
33281132a39SMatthias Ringwald 		}
33381132a39SMatthias Ringwald 
33481132a39SMatthias Ringwald 		j = 0;
33581132a39SMatthias Ringwald 		aad_len += sizeof(u16_t);
33681132a39SMatthias Ringwald 		while (aad_len > 16) {
33781132a39SMatthias Ringwald 			do {
33881132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ aad[j];
33981132a39SMatthias Ringwald 				i++, j++;
34081132a39SMatthias Ringwald 			} while (i < 16);
34181132a39SMatthias Ringwald 
34281132a39SMatthias Ringwald 			aad_len -= 16;
34381132a39SMatthias Ringwald 			i = 0;
34481132a39SMatthias Ringwald 
34581132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
34681132a39SMatthias Ringwald 			if (err) {
34781132a39SMatthias Ringwald 				return err;
34881132a39SMatthias Ringwald 			}
34981132a39SMatthias Ringwald 		}
35081132a39SMatthias Ringwald 
35181132a39SMatthias Ringwald 		for (i = 0; i < aad_len; i++, j++) {
35281132a39SMatthias Ringwald 			pmsg[i] = Xn[i] ^ aad[j];
35381132a39SMatthias Ringwald 		}
35481132a39SMatthias Ringwald 
35581132a39SMatthias Ringwald 		for (i = aad_len; i < 16; i++) {
35681132a39SMatthias Ringwald 			pmsg[i] = Xn[i];
35781132a39SMatthias Ringwald 		}
35881132a39SMatthias Ringwald 
35981132a39SMatthias Ringwald 		err = bt_encrypt_be(key, pmsg, Xn);
36081132a39SMatthias Ringwald 		if (err) {
36181132a39SMatthias Ringwald 			return err;
36281132a39SMatthias Ringwald 		}
36381132a39SMatthias Ringwald 	}
36481132a39SMatthias Ringwald 
36581132a39SMatthias Ringwald 	last_blk = msg_len % 16;
36681132a39SMatthias Ringwald 	blk_cnt = (msg_len + 15) / 16;
36781132a39SMatthias Ringwald 	if (!last_blk) {
36881132a39SMatthias Ringwald 		last_blk = 16;
36981132a39SMatthias Ringwald 	}
37081132a39SMatthias Ringwald 
37181132a39SMatthias Ringwald 	for (j = 0; j < blk_cnt; j++) {
37281132a39SMatthias Ringwald 		if (j + 1 == blk_cnt) {
37381132a39SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
37481132a39SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
37581132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
37681132a39SMatthias Ringwald 			}
37781132a39SMatthias Ringwald 			for (i = last_blk; i < 16; i++) {
37881132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ 0x00;
37981132a39SMatthias Ringwald 			}
38081132a39SMatthias Ringwald 
381*75ba91cfSMatthias Ringwald #ifdef LOG_XN
382*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Xn XOR Bn");
383*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
384*75ba91cfSMatthias Ringwald #endif
385*75ba91cfSMatthias Ringwald 
38681132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
38781132a39SMatthias Ringwald 			if (err) {
38881132a39SMatthias Ringwald 				return err;
38981132a39SMatthias Ringwald 			}
39081132a39SMatthias Ringwald 
391*75ba91cfSMatthias Ringwald #ifdef LOG_XN
392*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Xn+1");
393*75ba91cfSMatthias Ringwald 	printf_hexdump(Xn, 16);
394*75ba91cfSMatthias Ringwald #endif
395*75ba91cfSMatthias Ringwald 
39681132a39SMatthias Ringwald 			/* MIC = C_mic ^ X_1 */
39781132a39SMatthias Ringwald 			for (i = 0; i < sizeof(mic); i++) {
39881132a39SMatthias Ringwald 				mic[i] = cmic[i] ^ Xn[i];
39981132a39SMatthias Ringwald 			}
40081132a39SMatthias Ringwald 
401*75ba91cfSMatthias Ringwald #ifdef LOG_XN
402*75ba91cfSMatthias Ringwald 	printf("%16s: ", "mic");
403*75ba91cfSMatthias Ringwald 	printf_hexdump(mic, 16);
404*75ba91cfSMatthias Ringwald #endif
405*75ba91cfSMatthias Ringwald 
40681132a39SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
40781132a39SMatthias Ringwald 			pmsg[0] = 0x01;
40881132a39SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
40981132a39SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
41081132a39SMatthias Ringwald 
41181132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
41281132a39SMatthias Ringwald 			if (err) {
41381132a39SMatthias Ringwald 				return err;
41481132a39SMatthias Ringwald 			}
41581132a39SMatthias Ringwald 
41681132a39SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_1 */
41781132a39SMatthias Ringwald 			for (i = 0; i < last_blk; i++) {
41881132a39SMatthias Ringwald 				out_msg[(j * 16) + i] =
41981132a39SMatthias Ringwald 					msg[(j * 16) + i] ^ cmsg[i];
42081132a39SMatthias Ringwald 			}
42181132a39SMatthias Ringwald 		} else {
422*75ba91cfSMatthias Ringwald 
423*75ba91cfSMatthias Ringwald #ifdef LOG_XN
424*75ba91cfSMatthias Ringwald 	printf("%16s: ", "bn");
425*75ba91cfSMatthias Ringwald 	printf_hexdump(msg, 16);
426*75ba91cfSMatthias Ringwald #endif
427*75ba91cfSMatthias Ringwald 
42881132a39SMatthias Ringwald 			/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
42981132a39SMatthias Ringwald 			for (i = 0; i < 16; i++) {
43081132a39SMatthias Ringwald 				pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
43181132a39SMatthias Ringwald 			}
43281132a39SMatthias Ringwald 
433*75ba91cfSMatthias Ringwald #ifdef LOG_XN
434*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Xn XOR Bn");
435*75ba91cfSMatthias Ringwald 	printf_hexdump(pmsg, 16);
436*75ba91cfSMatthias Ringwald #endif
437*75ba91cfSMatthias Ringwald 
43881132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, Xn);
43981132a39SMatthias Ringwald 			if (err) {
44081132a39SMatthias Ringwald 				return err;
44181132a39SMatthias Ringwald 			}
44281132a39SMatthias Ringwald 
443*75ba91cfSMatthias Ringwald #ifdef LOG_XN
444*75ba91cfSMatthias Ringwald 	printf("%16s: ", "Xn+1");
445*75ba91cfSMatthias Ringwald 	printf_hexdump(Xn, 16);
446*75ba91cfSMatthias Ringwald #endif
447*75ba91cfSMatthias Ringwald 
44881132a39SMatthias Ringwald 			/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
44981132a39SMatthias Ringwald 			pmsg[0] = 0x01;
45081132a39SMatthias Ringwald 			memcpy(pmsg + 1, nonce, 13);
45181132a39SMatthias Ringwald 			sys_put_be16(j + 1, pmsg + 14);
45281132a39SMatthias Ringwald 
45381132a39SMatthias Ringwald 			err = bt_encrypt_be(key, pmsg, cmsg);
45481132a39SMatthias Ringwald 			if (err) {
45581132a39SMatthias Ringwald 				return err;
45681132a39SMatthias Ringwald 			}
45781132a39SMatthias Ringwald 
45881132a39SMatthias Ringwald 			/* Encrypted = Payload[0-15] ^ C_N */
45981132a39SMatthias Ringwald 			for (i = 0; i < 16; i++) {
46081132a39SMatthias Ringwald 				out_msg[(j * 16) + i] =
46181132a39SMatthias Ringwald 					msg[(j * 16) + i] ^ cmsg[i];
46281132a39SMatthias Ringwald 			}
46381132a39SMatthias Ringwald 
46481132a39SMatthias Ringwald 		}
46581132a39SMatthias Ringwald 	}
46681132a39SMatthias Ringwald 
46781132a39SMatthias Ringwald 	memcpy(out_msg + msg_len, mic, mic_size);
46881132a39SMatthias Ringwald 
46981132a39SMatthias Ringwald 	return 0;
47081132a39SMatthias Ringwald }
47181132a39SMatthias Ringwald 
47281132a39SMatthias Ringwald static void message_24(void){
47381132a39SMatthias Ringwald 	DEFINE_KEY(encryption_key, "0953fa93e7caac9638f58820220a398e");
47481132a39SMatthias Ringwald 
47581132a39SMatthias Ringwald 	uint8_t network_nonce[13];
47681132a39SMatthias Ringwald 	parse_hex(network_nonce, "000307080d1234000012345677");
47781132a39SMatthias Ringwald 	printf("%16s: ", "network_nonce"); printf_hexdump(network_nonce, 13);
47881132a39SMatthias Ringwald 
47981132a39SMatthias Ringwald 	uint8_t plaintext[18];
48081132a39SMatthias Ringwald 	parse_hex(plaintext, "9736e6a03401de1547118463123e5f6a17b9");
48181132a39SMatthias Ringwald 	printf("%16s: ", "plaintext"); printf_hexdump(plaintext, sizeof(plaintext));
48281132a39SMatthias Ringwald 
48381132a39SMatthias Ringwald 	uint8_t ciphertext[18+4];
48481132a39SMatthias Ringwald 	bt_mesh_ccm_encrypt(encryption_key, network_nonce, plaintext, sizeof(plaintext), NULL, 0, ciphertext, 4);
48581132a39SMatthias Ringwald 	printf("%16s: ", "ciphertext"); printf_hexdump(ciphertext, 18);
48681132a39SMatthias Ringwald 	printf("%16s: ", "NetMIC");     printf_hexdump(&ciphertext[18], 4);
48781132a39SMatthias Ringwald }
48881132a39SMatthias Ringwald 
48981132a39SMatthias Ringwald int main(void){
49081132a39SMatthias Ringwald 	message_24();
49181132a39SMatthias Ringwald 	return 0;
49281132a39SMatthias Ringwald }
493