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 17ba1e2dc4SMatthias Ringwald static void sys_put_be16(uint16_t value, uint8_t * buffer) { 18ba1e2dc4SMatthias Ringwald big_endian_store_16(buffer, 0, value); 19ba1e2dc4SMatthias Ringwald } 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 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 81ba1e2dc4SMatthias Ringwald printf("%16s: ", "X1"); 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 118*f88ad41fSMatthias Ringwald #ifdef LOG_XN 119*f88ad41fSMatthias Ringwald printf("%16s: ", "Xn XOR bn"); 120*f88ad41fSMatthias Ringwald printf_hexdump(pmsg, 16); 121*f88ad41fSMatthias Ringwald #endif 122*f88ad41fSMatthias 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 240ba1e2dc4SMatthias Ringwald if (memcmp(mic, enc_msg + msg_len, mic_size)) { 241ba1e2dc4SMatthias Ringwald return -EBADMSG; 242ba1e2dc4SMatthias Ringwald } 243ba1e2dc4SMatthias Ringwald 244ba1e2dc4SMatthias Ringwald return 0; 245ba1e2dc4SMatthias Ringwald } 246ba1e2dc4SMatthias Ringwald 247ba1e2dc4SMatthias Ringwald int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13], 248ba1e2dc4SMatthias Ringwald const u8_t *msg, size_t msg_len, 249ba1e2dc4SMatthias Ringwald const u8_t *aad, size_t aad_len, 250ba1e2dc4SMatthias Ringwald u8_t *out_msg, size_t mic_size) 251ba1e2dc4SMatthias Ringwald { 252ba1e2dc4SMatthias Ringwald u8_t pmsg[16], cmic[16], cmsg[16], mic[16], Xn[16]; 253ba1e2dc4SMatthias Ringwald u16_t blk_cnt, last_blk; 254ba1e2dc4SMatthias Ringwald size_t i, j; 255ba1e2dc4SMatthias Ringwald int err; 256ba1e2dc4SMatthias Ringwald 257ba1e2dc4SMatthias Ringwald // BT_DBG("key %s", bt_hex(key, 16)); 258ba1e2dc4SMatthias Ringwald // BT_DBG("nonce %s", bt_hex(nonce, 13)); 259ba1e2dc4SMatthias Ringwald // BT_DBG("msg (len %zu) %s", msg_len, bt_hex(msg, msg_len)); 260ba1e2dc4SMatthias Ringwald // BT_DBG("aad_len %zu mic_size %zu", aad_len, mic_size); 261ba1e2dc4SMatthias Ringwald 262ba1e2dc4SMatthias Ringwald /* Unsupported AAD size */ 263ba1e2dc4SMatthias Ringwald if (aad_len >= 0xff00) { 264ba1e2dc4SMatthias Ringwald return -EINVAL; 265ba1e2dc4SMatthias Ringwald } 266ba1e2dc4SMatthias Ringwald 267ba1e2dc4SMatthias Ringwald /* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */ 268ba1e2dc4SMatthias Ringwald pmsg[0] = 0x01; 269ba1e2dc4SMatthias Ringwald memcpy(pmsg + 1, nonce, 13); 270ba1e2dc4SMatthias Ringwald sys_put_be16(0x0000, pmsg + 14); 271ba1e2dc4SMatthias Ringwald 272ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 273ba1e2dc4SMatthias Ringwald printf("%16s: ", "A0"); 274ba1e2dc4SMatthias Ringwald printf_hexdump(pmsg, 16); 275ba1e2dc4SMatthias Ringwald #endif 276ba1e2dc4SMatthias Ringwald 277ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, cmic); 278ba1e2dc4SMatthias Ringwald if (err) { 279ba1e2dc4SMatthias Ringwald return err; 280ba1e2dc4SMatthias Ringwald } 281ba1e2dc4SMatthias Ringwald 282ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 283ba1e2dc4SMatthias Ringwald printf("%16s: ", "S0"); 284ba1e2dc4SMatthias Ringwald printf_hexdump(cmic, 16); 285ba1e2dc4SMatthias Ringwald #endif 286ba1e2dc4SMatthias Ringwald 287ba1e2dc4SMatthias Ringwald /* X_0 = e(AppKey, 0x09 || nonce || length) */ 288ba1e2dc4SMatthias Ringwald if (mic_size == sizeof(u64_t)) { 289ba1e2dc4SMatthias Ringwald pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00); 290ba1e2dc4SMatthias Ringwald } else { 291ba1e2dc4SMatthias Ringwald pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00); 292ba1e2dc4SMatthias Ringwald } 293ba1e2dc4SMatthias Ringwald 294ba1e2dc4SMatthias Ringwald memcpy(pmsg + 1, nonce, 13); 295ba1e2dc4SMatthias Ringwald sys_put_be16(msg_len, pmsg + 14); 296ba1e2dc4SMatthias Ringwald 297ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 298ba1e2dc4SMatthias Ringwald printf("%16s: ", "B0"); 299ba1e2dc4SMatthias Ringwald printf_hexdump(pmsg, 16); 300ba1e2dc4SMatthias Ringwald #endif 301ba1e2dc4SMatthias Ringwald 302ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, Xn); 303ba1e2dc4SMatthias Ringwald if (err) { 304ba1e2dc4SMatthias Ringwald return err; 305ba1e2dc4SMatthias Ringwald } 306ba1e2dc4SMatthias Ringwald 307ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 308ba1e2dc4SMatthias Ringwald printf("%16s: ", "X1"); 309ba1e2dc4SMatthias Ringwald printf_hexdump(Xn, 16); 310ba1e2dc4SMatthias Ringwald #endif 311ba1e2dc4SMatthias Ringwald 312ba1e2dc4SMatthias Ringwald /* If AAD is being used to authenticate, include it here */ 313ba1e2dc4SMatthias Ringwald if (aad_len) { 314ba1e2dc4SMatthias Ringwald sys_put_be16(aad_len, pmsg); 315ba1e2dc4SMatthias Ringwald 316ba1e2dc4SMatthias Ringwald for (i = 0; i < sizeof(u16_t); i++) { 317ba1e2dc4SMatthias Ringwald pmsg[i] = Xn[i] ^ pmsg[i]; 318ba1e2dc4SMatthias Ringwald } 319ba1e2dc4SMatthias Ringwald 320ba1e2dc4SMatthias Ringwald j = 0; 321ba1e2dc4SMatthias Ringwald aad_len += sizeof(u16_t); 322ba1e2dc4SMatthias Ringwald while (aad_len > 16) { 323ba1e2dc4SMatthias Ringwald do { 324ba1e2dc4SMatthias Ringwald pmsg[i] = Xn[i] ^ aad[j]; 325ba1e2dc4SMatthias Ringwald i++, j++; 326ba1e2dc4SMatthias Ringwald } while (i < 16); 327ba1e2dc4SMatthias Ringwald 328ba1e2dc4SMatthias Ringwald aad_len -= 16; 329ba1e2dc4SMatthias Ringwald i = 0; 330ba1e2dc4SMatthias Ringwald 331*f88ad41fSMatthias Ringwald #ifdef LOG_XN 332*f88ad41fSMatthias Ringwald printf("%16s: ", "Xn XOR bn (aad)"); 333*f88ad41fSMatthias Ringwald printf_hexdump(pmsg, 16); 334*f88ad41fSMatthias Ringwald #endif 335*f88ad41fSMatthias Ringwald 336ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, Xn); 337ba1e2dc4SMatthias Ringwald if (err) { 338ba1e2dc4SMatthias Ringwald return err; 339ba1e2dc4SMatthias Ringwald } 340*f88ad41fSMatthias Ringwald 341*f88ad41fSMatthias Ringwald #ifdef LOG_XN 342*f88ad41fSMatthias Ringwald printf("%16s: ", "Xn+1 AAD"); 343*f88ad41fSMatthias Ringwald printf_hexdump(Xn, 16); 344*f88ad41fSMatthias Ringwald #endif 345*f88ad41fSMatthias Ringwald 346ba1e2dc4SMatthias Ringwald } 347ba1e2dc4SMatthias Ringwald 348ba1e2dc4SMatthias Ringwald for (i = 0; i < aad_len; i++, j++) { 349ba1e2dc4SMatthias Ringwald pmsg[i] = Xn[i] ^ aad[j]; 350ba1e2dc4SMatthias Ringwald } 351ba1e2dc4SMatthias Ringwald 352ba1e2dc4SMatthias Ringwald for (i = aad_len; i < 16; i++) { 353ba1e2dc4SMatthias Ringwald pmsg[i] = Xn[i]; 354ba1e2dc4SMatthias Ringwald } 355ba1e2dc4SMatthias Ringwald 356*f88ad41fSMatthias Ringwald #ifdef LOG_XN 357*f88ad41fSMatthias Ringwald printf("%16s: ", "Xn XOR bn (aad)"); 358*f88ad41fSMatthias Ringwald printf_hexdump(pmsg, 16); 359*f88ad41fSMatthias Ringwald #endif 360*f88ad41fSMatthias Ringwald 361ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, Xn); 362ba1e2dc4SMatthias Ringwald if (err) { 363ba1e2dc4SMatthias Ringwald return err; 364ba1e2dc4SMatthias Ringwald } 365*f88ad41fSMatthias Ringwald #ifdef LOG_XN 366*f88ad41fSMatthias Ringwald printf("%16s: ", "Xn+1 AAD"); 367*f88ad41fSMatthias Ringwald printf_hexdump(Xn, 16); 368*f88ad41fSMatthias Ringwald #endif 369*f88ad41fSMatthias Ringwald 370ba1e2dc4SMatthias Ringwald } 371ba1e2dc4SMatthias Ringwald 372ba1e2dc4SMatthias Ringwald last_blk = msg_len % 16; 373ba1e2dc4SMatthias Ringwald blk_cnt = (msg_len + 15) / 16; 374ba1e2dc4SMatthias Ringwald if (!last_blk) { 375ba1e2dc4SMatthias Ringwald last_blk = 16; 376ba1e2dc4SMatthias Ringwald } 377ba1e2dc4SMatthias Ringwald 378ba1e2dc4SMatthias Ringwald for (j = 0; j < blk_cnt; j++) { 379ba1e2dc4SMatthias Ringwald if (j + 1 == blk_cnt) { 380ba1e2dc4SMatthias Ringwald /* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */ 381ba1e2dc4SMatthias Ringwald for (i = 0; i < last_blk; i++) { 382ba1e2dc4SMatthias Ringwald pmsg[i] = Xn[i] ^ msg[(j * 16) + i]; 383ba1e2dc4SMatthias Ringwald } 384ba1e2dc4SMatthias Ringwald for (i = last_blk; i < 16; i++) { 385ba1e2dc4SMatthias Ringwald pmsg[i] = Xn[i] ^ 0x00; 386ba1e2dc4SMatthias Ringwald } 387ba1e2dc4SMatthias Ringwald 388ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 389ba1e2dc4SMatthias Ringwald printf("%16s: ", "Xn XOR Bn"); 390ba1e2dc4SMatthias Ringwald printf_hexdump(pmsg, 16); 391ba1e2dc4SMatthias Ringwald #endif 392ba1e2dc4SMatthias Ringwald 393ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, Xn); 394ba1e2dc4SMatthias Ringwald if (err) { 395ba1e2dc4SMatthias Ringwald return err; 396ba1e2dc4SMatthias Ringwald } 397ba1e2dc4SMatthias Ringwald 398ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 399ba1e2dc4SMatthias Ringwald printf("%16s: ", "Xn+1"); 400ba1e2dc4SMatthias Ringwald printf_hexdump(Xn, 16); 401ba1e2dc4SMatthias Ringwald #endif 402ba1e2dc4SMatthias Ringwald 403ba1e2dc4SMatthias Ringwald /* MIC = C_mic ^ X_1 */ 404ba1e2dc4SMatthias Ringwald for (i = 0; i < sizeof(mic); i++) { 405ba1e2dc4SMatthias Ringwald mic[i] = cmic[i] ^ Xn[i]; 406ba1e2dc4SMatthias Ringwald } 407ba1e2dc4SMatthias Ringwald 408ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 409ba1e2dc4SMatthias Ringwald printf("%16s: ", "mic"); 410ba1e2dc4SMatthias Ringwald printf_hexdump(mic, 16); 411ba1e2dc4SMatthias Ringwald #endif 412ba1e2dc4SMatthias Ringwald 413ba1e2dc4SMatthias Ringwald /* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */ 414ba1e2dc4SMatthias Ringwald pmsg[0] = 0x01; 415ba1e2dc4SMatthias Ringwald memcpy(pmsg + 1, nonce, 13); 416ba1e2dc4SMatthias Ringwald sys_put_be16(j + 1, pmsg + 14); 417ba1e2dc4SMatthias Ringwald 418ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, cmsg); 419ba1e2dc4SMatthias Ringwald if (err) { 420ba1e2dc4SMatthias Ringwald return err; 421ba1e2dc4SMatthias Ringwald } 422ba1e2dc4SMatthias Ringwald 423ba1e2dc4SMatthias Ringwald /* Encrypted = Payload[0-15] ^ C_1 */ 424ba1e2dc4SMatthias Ringwald for (i = 0; i < last_blk; i++) { 425ba1e2dc4SMatthias Ringwald out_msg[(j * 16) + i] = 426ba1e2dc4SMatthias Ringwald msg[(j * 16) + i] ^ cmsg[i]; 427ba1e2dc4SMatthias Ringwald } 428ba1e2dc4SMatthias Ringwald } else { 429ba1e2dc4SMatthias Ringwald 430ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 431ba1e2dc4SMatthias Ringwald printf("%16s: ", "bn"); 432ba1e2dc4SMatthias Ringwald printf_hexdump(msg, 16); 433ba1e2dc4SMatthias Ringwald #endif 434ba1e2dc4SMatthias Ringwald 435ba1e2dc4SMatthias Ringwald /* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */ 436ba1e2dc4SMatthias Ringwald for (i = 0; i < 16; i++) { 437ba1e2dc4SMatthias Ringwald pmsg[i] = Xn[i] ^ msg[(j * 16) + i]; 438ba1e2dc4SMatthias Ringwald } 439ba1e2dc4SMatthias Ringwald 440ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 441ba1e2dc4SMatthias Ringwald printf("%16s: ", "Xn XOR Bn"); 442ba1e2dc4SMatthias Ringwald printf_hexdump(pmsg, 16); 443ba1e2dc4SMatthias Ringwald #endif 444ba1e2dc4SMatthias Ringwald 445ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, Xn); 446ba1e2dc4SMatthias Ringwald if (err) { 447ba1e2dc4SMatthias Ringwald return err; 448ba1e2dc4SMatthias Ringwald } 449ba1e2dc4SMatthias Ringwald 450ba1e2dc4SMatthias Ringwald #ifdef LOG_XN 451ba1e2dc4SMatthias Ringwald printf("%16s: ", "Xn+1"); 452ba1e2dc4SMatthias Ringwald printf_hexdump(Xn, 16); 453ba1e2dc4SMatthias Ringwald #endif 454ba1e2dc4SMatthias Ringwald 455ba1e2dc4SMatthias Ringwald /* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */ 456ba1e2dc4SMatthias Ringwald pmsg[0] = 0x01; 457ba1e2dc4SMatthias Ringwald memcpy(pmsg + 1, nonce, 13); 458ba1e2dc4SMatthias Ringwald sys_put_be16(j + 1, pmsg + 14); 459ba1e2dc4SMatthias Ringwald 460ba1e2dc4SMatthias Ringwald err = bt_encrypt_be(key, pmsg, cmsg); 461ba1e2dc4SMatthias Ringwald if (err) { 462ba1e2dc4SMatthias Ringwald return err; 463ba1e2dc4SMatthias Ringwald } 464ba1e2dc4SMatthias Ringwald 465ba1e2dc4SMatthias Ringwald /* Encrypted = Payload[0-15] ^ C_N */ 466ba1e2dc4SMatthias Ringwald for (i = 0; i < 16; i++) { 467ba1e2dc4SMatthias Ringwald out_msg[(j * 16) + i] = 468ba1e2dc4SMatthias Ringwald msg[(j * 16) + i] ^ cmsg[i]; 469ba1e2dc4SMatthias Ringwald } 470ba1e2dc4SMatthias Ringwald 471ba1e2dc4SMatthias Ringwald } 472ba1e2dc4SMatthias Ringwald } 473ba1e2dc4SMatthias Ringwald 474ba1e2dc4SMatthias Ringwald memcpy(out_msg + msg_len, mic, mic_size); 475ba1e2dc4SMatthias Ringwald 476ba1e2dc4SMatthias Ringwald return 0; 477ba1e2dc4SMatthias Ringwald } 478