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