40 #include <sys/socket.h>
45 #ifndef HAVE_LINUX_IF_ALG_H
46 #ifndef HAVE_LINUX_TYPES_H
51 #include <linux/types.h>
71 #define ALG_OP_DECRYPT 0
72 #define ALG_OP_ENCRYPT 1
77 #include <linux/if_alg.h>
85 #define CMAC_MSG_MAX 80
103 fd = open(
"/dev/urandom", O_RDONLY);
119 fd = socket(
PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
123 memset(&salg, 0,
sizeof(salg));
125 strcpy((
char *) salg.
salg_type,
"skcipher");
126 strcpy((
char *) salg.
salg_name,
"ecb(aes)");
128 if (bind(fd, (
struct sockaddr *) &salg,
sizeof(salg)) < 0) {
141 fd = socket(
PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
145 memset(&salg, 0,
sizeof(salg));
148 strcpy((
char *) salg.
salg_name,
"cmac(aes)");
150 if (bind(fd, (
struct sockaddr *) &salg,
sizeof(salg)) < 0) {
195 __sync_fetch_and_add(&crypto->
ref_count, 1);
205 if (__sync_sub_and_fetch(&crypto->
ref_count, 1))
216 uint8_t *buf, uint8_t num_bytes)
223 len = read(crypto->
urandom, buf, num_bytes);
230 static int alg_new(
int fd,
const void *keyval, socklen_t keylen)
236 return accept(fd, NULL, 0);
240 void *outbuf,
size_t outlen)
243 char cbuf[CMSG_SPACE(
sizeof(alg_op))];
244 struct cmsghdr *cmsg;
249 memset(cbuf, 0,
sizeof(cbuf));
250 memset(&msg, 0,
sizeof(msg));
252 msg.msg_control = cbuf;
253 msg.msg_controllen =
sizeof(cbuf);
255 cmsg = CMSG_FIRSTHDR(&msg);
258 cmsg->cmsg_len = CMSG_LEN(
sizeof(alg_op));
259 memcpy(CMSG_DATA(cmsg), &alg_op,
sizeof(alg_op));
261 iov.iov_base = (
void *) inbuf;
267 len = sendmsg(fd, &msg, 0);
271 len = read(fd, outbuf, outlen);
278 static inline void swap_buf(
const uint8_t *src, uint8_t *dst, uint16_t len)
282 for (i = 0; i < len; i++)
283 dst[len - 1 - i] = src[i];
287 const uint8_t *m, uint16_t m_len,
288 uint32_t sign_cnt, uint8_t signature[12])
292 uint8_t tmp[16], out[16];
293 uint16_t msg_len = m_len +
sizeof(uint32_t);
294 uint8_t msg[msg_len];
295 uint8_t msg_s[msg_len];
300 memset(msg, 0, msg_len);
301 memcpy(msg, m, m_len);
316 len = send(fd, msg_s, msg_len, 0);
322 len = read(fd, out, 16);
342 memcpy(signature, tmp + 4, 12);
360 const uint8_t plaintext[16], uint8_t encrypted[16])
362 uint8_t tmp[16], in[16], out[16];
425 const uint8_t r[3], uint8_t hash[3])
428 uint8_t encrypted[16];
435 memset(rp + 3, 0, 13);
442 memcpy(hash, encrypted, 3);
451 static inline void u128_xor(
const uint8_t p[16],
const uint8_t q[16],
518 const uint8_t r[16],
const uint8_t pres[7],
519 const uint8_t preq[7], uint8_t iat,
520 const uint8_t ia[6], uint8_t rat,
521 const uint8_t ra[6], uint8_t res[16])
523 uint8_t p1[16], p2[16];
528 memcpy(p1 + 2, preq, 7);
529 memcpy(p1 + 9, pres, 7);
533 memcpy(p2 + 6, ia, 6);
534 memset(p2 + 12, 0, 4);
582 const uint8_t r1[16],
const uint8_t r2[16],
586 memcpy(res + 8, r1, 8);
592 size_t msg_len, uint8_t res[16])
607 len = send(fd, msg_msb, msg_len, 0);
613 len = read(fd, out, 16);
627 uint8_t x[16], uint8_t z, uint8_t res[16])
635 memcpy(&m[1], v, 32);
636 memcpy(&m[33], u, 32);
638 return aes_cmac(crypto, x, m,
sizeof(m), res);
642 uint8_t n2[16], uint8_t a1[7], uint8_t a2[7],
643 uint8_t mackey[16], uint8_t ltk[16])
645 uint8_t btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
646 uint8_t salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
647 0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
648 uint8_t length[2] = { 0x00, 0x01 };
649 uint8_t m[53], t[16];
651 if (!
aes_cmac(crypto, salt, w, 32, t))
654 memcpy(&m[0], length, 2);
655 memcpy(&m[2], a2, 7);
656 memcpy(&m[9], a1, 7);
657 memcpy(&m[16], n2, 16);
658 memcpy(&m[32], n1, 16);
659 memcpy(&m[48], btle, 4);
662 if (!
aes_cmac(crypto, t, m,
sizeof(m), mackey))
666 return aes_cmac(crypto, t, m,
sizeof(m), ltk);
670 uint8_t n2[16], uint8_t r[16], uint8_t io_cap[3],
671 uint8_t a1[7], uint8_t a2[7], uint8_t res[16])
675 memcpy(&m[0], a2, 7);
676 memcpy(&m[7], a1, 7);
677 memcpy(&m[14], io_cap, 3);
678 memcpy(&m[17], r, 16);
679 memcpy(&m[33], n2, 16);
680 memcpy(&m[49], n1, 16);
682 return aes_cmac(crypto, w, m,
sizeof(m), res);
686 uint8_t x[16], uint8_t y[16], uint32_t *val)
688 uint8_t m[80], tmp[16];
690 memcpy(&m[0], y, 16);
691 memcpy(&m[16], v, 32);
692 memcpy(&m[48], u, 32);
694 if (!
aes_cmac(crypto, x, m,
sizeof(m), tmp))
bool bt_crypto_c1(struct bt_crypto *crypto, const uint8_t k[16], const uint8_t r[16], const uint8_t pres[7], const uint8_t preq[7], uint8_t iat, const uint8_t ia[6], uint8_t rat, const uint8_t ra[6], uint8_t res[16])
static bool aes_cmac(struct bt_crypto *crypto, uint8_t key[16], uint8_t *msg, size_t msg_len, uint8_t res[16])
bool bt_crypto_s1(struct bt_crypto *crypto, const uint8_t k[16], const uint8_t r1[16], const uint8_t r2[16], uint8_t res[16])
static int alg_new(int fd, const void *keyval, socklen_t keylen)
static void u128_xor(const uint8_t p[16], const uint8_t q[16], uint8_t r[16])
static void put_be32(uint32_t val, void *dst)
static bool alg_encrypt(int fd, const void *inbuf, size_t inlen, void *outbuf, size_t outlen)
bool bt_crypto_f4(struct bt_crypto *crypto, uint8_t u[32], uint8_t v[32], uint8_t x[16], uint8_t z, uint8_t res[16])
struct bt_crypto * bt_crypto_new(void)
static uint32_t get_le32(const void *ptr)
static int ecb_aes_setup(void)
bool bt_crypto_g2(struct bt_crypto *crypto, uint8_t u[32], uint8_t v[32], uint8_t x[16], uint8_t y[16], uint32_t *val)
static void put_le32(uint32_t val, void *dst)
bool bt_crypto_f5(struct bt_crypto *crypto, uint8_t w[32], uint8_t n1[16], uint8_t n2[16], uint8_t a1[7], uint8_t a2[7], uint8_t mackey[16], uint8_t ltk[16])
struct bt_crypto * bt_crypto_ref(struct bt_crypto *crypto)
bool bt_crypto_sign_att(struct bt_crypto *crypto, const uint8_t key[16], const uint8_t *m, uint16_t m_len, uint32_t sign_cnt, uint8_t signature[12])
bool bt_crypto_random_bytes(struct bt_crypto *crypto, uint8_t *buf, uint8_t num_bytes)
bool bt_crypto_e(struct bt_crypto *crypto, const uint8_t key[16], const uint8_t plaintext[16], uint8_t encrypted[16])
static void swap_buf(const uint8_t *src, uint8_t *dst, uint16_t len)
void bt_crypto_unref(struct bt_crypto *crypto)
bool bt_crypto_f6(struct bt_crypto *crypto, uint8_t w[16], uint8_t n1[16], uint8_t n2[16], uint8_t r[16], uint8_t io_cap[3], uint8_t a1[7], uint8_t a2[7], uint8_t res[16])
static int cmac_aes_setup(void)
static int urandom_setup(void)
bool bt_crypto_ah(struct bt_crypto *crypto, const uint8_t k[16], const uint8_t r[3], uint8_t hash[3])