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