mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-15 00:04:29 +08:00
mesh: Convert crypto to use ELL wrappers
Use ELL implementations of aead-ccm(aes), ecb(aes) and cmac(aes). These standard encryption and hashing routines are provided by ELL.
This commit is contained in:
parent
75cd5b382e
commit
dfed483946
@ -116,6 +116,8 @@ ell_headers = ell/util.h \
|
||||
ell/random.h \
|
||||
ell/signal.h \
|
||||
ell/timeout.h \
|
||||
ell/cipher.h \
|
||||
ell/checksum.h \
|
||||
ell/io.h \
|
||||
ell/idle.h \
|
||||
ell/main.h \
|
||||
@ -138,6 +140,8 @@ ell_sources = ell/private.h ell/missing.h \
|
||||
ell/main.c \
|
||||
ell/strv.c \
|
||||
ell/string.c \
|
||||
ell/cipher.c \
|
||||
ell/checksum.c \
|
||||
ell/dbus-private.h \
|
||||
ell/dbus.c \
|
||||
ell/dbus-message.c \
|
||||
|
518
mesh/crypto.c
518
mesh/crypto.c
@ -44,193 +44,52 @@
|
||||
/* Multiply used Zero array */
|
||||
static const uint8_t zero[16] = { 0, };
|
||||
|
||||
static int alg_new(int fd, const void *keyval, socklen_t keylen,
|
||||
size_t mic_size)
|
||||
static bool aes_ecb_one(const uint8_t key[16], const uint8_t in[16],
|
||||
uint8_t out[16])
|
||||
{
|
||||
if (setsockopt(fd, SOL_ALG, ALG_SET_KEY, keyval, keylen) < 0)
|
||||
return -1;
|
||||
void *cipher;
|
||||
bool result = false;
|
||||
|
||||
if (mic_size &&
|
||||
setsockopt(fd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE,
|
||||
NULL, mic_size) < 0)
|
||||
return -1;
|
||||
cipher = l_cipher_new(L_CIPHER_AES, key, 16);
|
||||
|
||||
/* FIXME: This should use accept4() with SOCK_CLOEXEC */
|
||||
return accept(fd, NULL, 0);
|
||||
}
|
||||
|
||||
static bool alg_encrypt(int fd, const void *inbuf, size_t inlen,
|
||||
void *outbuf, size_t outlen)
|
||||
{
|
||||
__u32 alg_op = ALG_OP_ENCRYPT;
|
||||
char cbuf[CMSG_SPACE(sizeof(alg_op))];
|
||||
struct cmsghdr *cmsg;
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
ssize_t len;
|
||||
|
||||
memset(cbuf, 0, sizeof(cbuf));
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
msg.msg_control = cbuf;
|
||||
msg.msg_controllen = sizeof(cbuf);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = SOL_ALG;
|
||||
cmsg->cmsg_type = ALG_SET_OP;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(alg_op));
|
||||
memcpy(CMSG_DATA(cmsg), &alg_op, sizeof(alg_op));
|
||||
|
||||
iov.iov_base = (void *) inbuf;
|
||||
iov.iov_len = inlen;
|
||||
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
len = sendmsg(fd, &msg, 0);
|
||||
if (len < 0)
|
||||
return false;
|
||||
|
||||
len = read(fd, outbuf, outlen);
|
||||
if (len < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int aes_ecb_setup(const uint8_t key[16])
|
||||
{
|
||||
struct sockaddr_alg salg;
|
||||
int fd, nfd;
|
||||
|
||||
fd = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
memset(&salg, 0, sizeof(salg));
|
||||
salg.salg_family = AF_ALG;
|
||||
strcpy((char *) salg.salg_type, "skcipher");
|
||||
strcpy((char *) salg.salg_name, "ecb(aes)");
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &salg, sizeof(salg)) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
if (cipher) {
|
||||
result = l_cipher_encrypt(cipher, in, out, 16);
|
||||
l_cipher_free(cipher);
|
||||
}
|
||||
|
||||
nfd = alg_new(fd, key, 16, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
return nfd;
|
||||
}
|
||||
|
||||
static bool aes_ecb(int fd, const uint8_t plaintext[16], uint8_t encrypted[16])
|
||||
{
|
||||
return alg_encrypt(fd, plaintext, 16, encrypted, 16);
|
||||
}
|
||||
|
||||
static void aes_ecb_destroy(int fd)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static bool aes_ecb_one(const uint8_t key[16],
|
||||
const uint8_t plaintext[16], uint8_t encrypted[16])
|
||||
{
|
||||
bool result;
|
||||
int fd;
|
||||
|
||||
fd = aes_ecb_setup(key);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
result = aes_ecb(fd, plaintext, encrypted);
|
||||
|
||||
aes_ecb_destroy(fd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool mesh_aes_ecb_one(const uint8_t key[16],
|
||||
const uint8_t plaintext[16], uint8_t encrypted[16])
|
||||
{
|
||||
return aes_ecb_one(key, plaintext, encrypted);
|
||||
}
|
||||
|
||||
/* Maximum message length that can be passed to aes_cmac */
|
||||
#define CMAC_MSG_MAX (64 + 64 + 17)
|
||||
|
||||
static int aes_cmac_setup(const uint8_t key[16])
|
||||
{
|
||||
struct sockaddr_alg salg;
|
||||
int fd, nfd;
|
||||
|
||||
fd = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
memset(&salg, 0, sizeof(salg));
|
||||
salg.salg_family = AF_ALG;
|
||||
strcpy((char *) salg.salg_type, "hash");
|
||||
strcpy((char *) salg.salg_name, "cmac(aes)");
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &salg, sizeof(salg)) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nfd = alg_new(fd, key, 16, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
return nfd;
|
||||
}
|
||||
|
||||
static bool aes_cmac(int fd, const uint8_t *msg,
|
||||
static bool aes_cmac(void *checksum, const uint8_t *msg,
|
||||
size_t msg_len, uint8_t res[16])
|
||||
{
|
||||
ssize_t len;
|
||||
|
||||
if (msg_len > CMAC_MSG_MAX)
|
||||
if (!l_checksum_update(checksum, msg, msg_len))
|
||||
return false;
|
||||
|
||||
len = send(fd, msg, msg_len, 0);
|
||||
if (len < 0)
|
||||
return false;
|
||||
if (16 == l_checksum_get_digest(checksum, res, 16))
|
||||
return true;
|
||||
|
||||
len = read(fd, res, 16);
|
||||
if (len < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void aes_cmac_destroy(int fd)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int aes_cmac_N_start(const uint8_t N[16])
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = aes_cmac_setup(N);
|
||||
return fd;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool aes_cmac_one(const uint8_t key[16], const void *msg,
|
||||
size_t msg_len, uint8_t res[16])
|
||||
{
|
||||
void *checksum;
|
||||
bool result;
|
||||
int fd;
|
||||
|
||||
fd = aes_cmac_setup(key);
|
||||
if (fd < 0)
|
||||
checksum = l_checksum_new_cmac_aes(key, 16);
|
||||
if (!checksum)
|
||||
return false;
|
||||
|
||||
result = aes_cmac(fd, msg, msg_len, res);
|
||||
result = l_checksum_update(checksum, msg, msg_len);
|
||||
|
||||
aes_cmac_destroy(fd);
|
||||
if (result) {
|
||||
ssize_t len = l_checksum_get_digest(checksum, res, 16);
|
||||
result = !!(len == 16);
|
||||
}
|
||||
|
||||
l_checksum_free(checksum);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -247,161 +106,22 @@ bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
|
||||
uint8_t *out_msg,
|
||||
void *out_mic, size_t mic_size)
|
||||
{
|
||||
uint8_t pmsg[16], cmic[16], cmsg[16];
|
||||
uint8_t mic[16], Xn[16];
|
||||
uint16_t blk_cnt, last_blk;
|
||||
void *cipher;
|
||||
bool result;
|
||||
size_t i, j;
|
||||
int fd;
|
||||
|
||||
/* Mesh limits AAD length to 16 */
|
||||
if (aad_len > 16)
|
||||
return false;
|
||||
cipher = l_aead_cipher_new(L_AEAD_CIPHER_AES_CCM, key, 16, mic_size);
|
||||
|
||||
fd = aes_ecb_setup(key);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
result = l_aead_cipher_encrypt(cipher, msg, msg_len, aad, aad_len,
|
||||
nonce, 13, out_msg, msg_len + mic_size);
|
||||
|
||||
/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
|
||||
pmsg[0] = 0x01;
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(0x0000, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, cmic);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* X_0 = e(AppKey, 0x09 || nonce || length) */
|
||||
if (mic_size == 8)
|
||||
pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
|
||||
else
|
||||
pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
|
||||
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(msg_len, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* If AAD is being used to authenticate, include it here */
|
||||
if (aad_len) {
|
||||
l_put_be16(aad_len, pmsg);
|
||||
|
||||
for (i = 0; i < sizeof(uint16_t); i++)
|
||||
pmsg[i] = Xn[i] ^ pmsg[i];
|
||||
|
||||
j = 0;
|
||||
aad_len += sizeof(uint16_t);
|
||||
while (aad_len > 16) {
|
||||
do {
|
||||
pmsg[i] = Xn[i] ^ aad[j];
|
||||
i++, j++;
|
||||
} while (i < 16);
|
||||
|
||||
aad_len -= 16;
|
||||
i = 0;
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < aad_len; i++, j++)
|
||||
pmsg[i] = Xn[i] ^ aad[j];
|
||||
|
||||
for (i = aad_len; i < 16; i++)
|
||||
pmsg[i] = Xn[i];
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
if (result && out_mic) {
|
||||
if (mic_size == 4)
|
||||
*(uint32_t *)out_mic = l_get_be32(out_msg + msg_len);
|
||||
else
|
||||
*(uint64_t *)out_mic = l_get_be64(out_msg + msg_len);
|
||||
}
|
||||
|
||||
last_blk = msg_len % 16;
|
||||
blk_cnt = (msg_len + 15) / 16;
|
||||
if (!last_blk)
|
||||
last_blk = 16;
|
||||
|
||||
for (j = 0; j < blk_cnt; j++) {
|
||||
if (j + 1 == blk_cnt) {
|
||||
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
|
||||
for (i = 0; i < last_blk; i++)
|
||||
pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
|
||||
for (i = last_blk; i < 16; i++)
|
||||
pmsg[i] = Xn[i] ^ 0x00;
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* MIC = C_mic ^ X_1 */
|
||||
for (i = 0; i < sizeof(mic); i++)
|
||||
mic[i] = cmic[i] ^ Xn[i];
|
||||
|
||||
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
|
||||
pmsg[0] = 0x01;
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(j + 1, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, cmsg);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
if (out_msg) {
|
||||
/* Encrypted = Payload[0-15] ^ C_1 */
|
||||
for (i = 0; i < last_blk; i++)
|
||||
out_msg[(j * 16) + i] =
|
||||
msg[(j * 16) + i] ^ cmsg[i];
|
||||
|
||||
}
|
||||
} else {
|
||||
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
|
||||
for (i = 0; i < 16; i++)
|
||||
pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
|
||||
pmsg[0] = 0x01;
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(j + 1, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, cmsg);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
if (out_msg) {
|
||||
/* Encrypted = Payload[0-15] ^ C_N */
|
||||
for (i = 0; i < 16; i++)
|
||||
out_msg[(j * 16) + i] =
|
||||
msg[(j * 16) + i] ^ cmsg[i];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (out_msg)
|
||||
memcpy(out_msg + msg_len, mic, mic_size);
|
||||
|
||||
if (out_mic) {
|
||||
switch (mic_size) {
|
||||
case 4:
|
||||
*(uint32_t *)out_mic = l_get_be32(mic);
|
||||
break;
|
||||
case 8:
|
||||
*(uint64_t *)out_mic = l_get_be64(mic);
|
||||
break;
|
||||
default:
|
||||
/* Unsupported MIC size */
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
aes_ecb_destroy(fd);
|
||||
l_aead_cipher_free(cipher);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -412,156 +132,26 @@ bool mesh_crypto_aes_ccm_decrypt(const uint8_t nonce[13], const uint8_t key[16],
|
||||
uint8_t *out_msg,
|
||||
void *out_mic, size_t mic_size)
|
||||
{
|
||||
uint8_t msg[16], pmsg[16], cmic[16], cmsg[16], Xn[16];
|
||||
uint8_t mic[16];
|
||||
uint16_t msg_len = enc_msg_len - mic_size;
|
||||
uint16_t last_blk, blk_cnt;
|
||||
void *cipher;
|
||||
bool result;
|
||||
size_t i, j;
|
||||
int fd;
|
||||
size_t out_msg_len = enc_msg_len - mic_size;
|
||||
|
||||
if (enc_msg_len < 5 || aad_len > 16)
|
||||
return false;
|
||||
cipher = l_aead_cipher_new(L_AEAD_CIPHER_AES_CCM, key, 16, mic_size);
|
||||
|
||||
fd = aes_ecb_setup(key);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
result = l_aead_cipher_decrypt(cipher, enc_msg, enc_msg_len,
|
||||
aad, aad_len, nonce, 13,
|
||||
out_msg, out_msg_len);
|
||||
|
||||
/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
|
||||
pmsg[0] = 0x01;
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(0x0000, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, cmic);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* X_0 = e(AppKey, 0x09 || nonce || length) */
|
||||
if (mic_size == 8)
|
||||
pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
|
||||
else
|
||||
pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
|
||||
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(msg_len, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* If AAD is being used to authenticate, include it here */
|
||||
if (aad_len) {
|
||||
l_put_be16(aad_len, pmsg);
|
||||
|
||||
for (i = 0; i < sizeof(uint16_t); i++)
|
||||
pmsg[i] = Xn[i] ^ pmsg[i];
|
||||
|
||||
j = 0;
|
||||
aad_len += sizeof(uint16_t);
|
||||
while (aad_len > 16) {
|
||||
do {
|
||||
pmsg[i] = Xn[i] ^ aad[j];
|
||||
i++, j++;
|
||||
} while (i < 16);
|
||||
|
||||
aad_len -= 16;
|
||||
i = 0;
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < aad_len; i++, j++)
|
||||
pmsg[i] = Xn[i] ^ aad[j];
|
||||
|
||||
for (i = aad_len; i < 16; i++)
|
||||
pmsg[i] = Xn[i];
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
if (result && out_mic) {
|
||||
if (mic_size == 4)
|
||||
*(uint32_t *)out_mic =
|
||||
l_get_be32(enc_msg + enc_msg_len - mic_size);
|
||||
else
|
||||
*(uint64_t *)out_mic =
|
||||
l_get_be64(enc_msg + enc_msg_len - mic_size);
|
||||
}
|
||||
|
||||
last_blk = msg_len % 16;
|
||||
blk_cnt = (msg_len + 15) / 16;
|
||||
if (!last_blk)
|
||||
last_blk = 16;
|
||||
|
||||
for (j = 0; j < blk_cnt; j++) {
|
||||
if (j + 1 == blk_cnt) {
|
||||
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
|
||||
pmsg[0] = 0x01;
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(j + 1, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, cmsg);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* Encrypted = Payload[0-15] ^ C_1 */
|
||||
for (i = 0; i < last_blk; i++)
|
||||
msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
|
||||
|
||||
if (out_msg)
|
||||
memcpy(out_msg + (j * 16), msg, last_blk);
|
||||
|
||||
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
|
||||
for (i = 0; i < last_blk; i++)
|
||||
pmsg[i] = Xn[i] ^ msg[i];
|
||||
for (i = last_blk; i < 16; i++)
|
||||
pmsg[i] = Xn[i] ^ 0x00;
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* MIC = C_mic ^ X_1 */
|
||||
for (i = 0; i < sizeof(mic); i++)
|
||||
mic[i] = cmic[i] ^ Xn[i];
|
||||
} else {
|
||||
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
|
||||
pmsg[0] = 0x01;
|
||||
memcpy(pmsg + 1, nonce, 13);
|
||||
l_put_be16(j + 1, pmsg + 14);
|
||||
|
||||
result = aes_ecb(fd, pmsg, cmsg);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
/* Encrypted = Payload[0-15] ^ C_1 */
|
||||
for (i = 0; i < 16; i++)
|
||||
msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
|
||||
|
||||
if (out_msg)
|
||||
memcpy(out_msg + (j * 16), msg, 16);
|
||||
|
||||
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
|
||||
for (i = 0; i < 16; i++)
|
||||
pmsg[i] = Xn[i] ^ msg[i];
|
||||
|
||||
result = aes_ecb(fd, pmsg, Xn);
|
||||
if (!result)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (out_mic) {
|
||||
switch (mic_size) {
|
||||
case 4:
|
||||
*(uint32_t *)out_mic = l_get_be32(mic);
|
||||
break;
|
||||
case 8:
|
||||
*(uint64_t *)out_mic = l_get_be64(mic);
|
||||
break;
|
||||
default:
|
||||
/* Unsupported MIC size */
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
aes_ecb_destroy(fd);
|
||||
l_aead_cipher_free(cipher);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -582,7 +172,7 @@ bool mesh_crypto_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
|
||||
uint8_t enc_key[16],
|
||||
uint8_t priv_key[16])
|
||||
{
|
||||
int fd;
|
||||
void *checksum;
|
||||
uint8_t output[16];
|
||||
uint8_t t[16];
|
||||
uint8_t *stage;
|
||||
@ -598,14 +188,14 @@ bool mesh_crypto_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
|
||||
if (!aes_cmac_one(stage, n, 16, t))
|
||||
goto fail;
|
||||
|
||||
fd = aes_cmac_N_start(t);
|
||||
if (fd < 0)
|
||||
checksum = l_checksum_new_cmac_aes(t, 16);
|
||||
if (!checksum)
|
||||
goto fail;
|
||||
|
||||
memcpy(stage, p, p_len);
|
||||
stage[p_len] = 1;
|
||||
|
||||
if (!aes_cmac(fd, stage, p_len + 1, output))
|
||||
if (!aes_cmac(checksum, stage, p_len + 1, output))
|
||||
goto done;
|
||||
|
||||
net_id[0] = output[15] & 0x7f;
|
||||
@ -614,7 +204,7 @@ bool mesh_crypto_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
|
||||
memcpy(stage + 16, p, p_len);
|
||||
stage[p_len + 16] = 2;
|
||||
|
||||
if (!aes_cmac(fd, stage, p_len + 16 + 1, output))
|
||||
if (!aes_cmac(checksum, stage, p_len + 16 + 1, output))
|
||||
goto done;
|
||||
|
||||
memcpy(enc_key, output, 16);
|
||||
@ -623,14 +213,14 @@ bool mesh_crypto_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
|
||||
memcpy(stage + 16, p, p_len);
|
||||
stage[p_len + 16] = 3;
|
||||
|
||||
if (!aes_cmac(fd, stage, p_len + 16 + 1, output))
|
||||
if (!aes_cmac(checksum, stage, p_len + 16 + 1, output))
|
||||
goto done;
|
||||
|
||||
memcpy(priv_key, output, 16);
|
||||
success = true;
|
||||
|
||||
done:
|
||||
aes_cmac_destroy(fd);
|
||||
l_checksum_free(checksum);
|
||||
fail:
|
||||
l_free(stage);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user