|
|
@ -85,13 +85,17 @@ static void le64_nonce(unsigned char *npub, u64 nonce) |
|
|
|
memcpy(npub + zerolen, &le_nonce, sizeof(le_nonce)); |
|
|
|
} |
|
|
|
|
|
|
|
static struct io_plan *peer_decrypt_body(struct io_conn *conn, |
|
|
|
struct crypto_state *cs) |
|
|
|
u8 *cryptomsg_decrypt_body(const tal_t *ctx, |
|
|
|
struct crypto_state *cs, const u8 *in) |
|
|
|
{ |
|
|
|
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES]; |
|
|
|
unsigned long long mlen; |
|
|
|
u8 *decrypted = tal_arr(cs->in, u8, tal_count(cs->in) - 16), *in; |
|
|
|
struct io_plan *plan; |
|
|
|
size_t inlen = tal_count(in); |
|
|
|
u8 *decrypted; |
|
|
|
|
|
|
|
if (inlen < 16) |
|
|
|
return NULL; |
|
|
|
decrypted = tal_arr(ctx, u8, inlen - 16); |
|
|
|
|
|
|
|
le64_nonce(npub, cs->rn++); |
|
|
|
|
|
|
@ -104,17 +108,28 @@ static struct io_plan *peer_decrypt_body(struct io_conn *conn, |
|
|
|
*/ |
|
|
|
if (crypto_aead_chacha20poly1305_ietf_decrypt(decrypted, |
|
|
|
&mlen, NULL, |
|
|
|
memcheck(cs->in, |
|
|
|
tal_count(cs->in)), |
|
|
|
tal_count(cs->in), |
|
|
|
memcheck(in, inlen), |
|
|
|
inlen, |
|
|
|
NULL, 0, |
|
|
|
npub, cs->rk.u.u8) != 0) { |
|
|
|
/* FIXME: Report error! */ |
|
|
|
return io_close(conn); |
|
|
|
return tal_free(decrypted); |
|
|
|
} |
|
|
|
assert(mlen == tal_count(decrypted)); |
|
|
|
|
|
|
|
maybe_rotate_key(&cs->rn, &cs->rk, &cs->r_ck); |
|
|
|
return decrypted; |
|
|
|
} |
|
|
|
|
|
|
|
static struct io_plan *peer_decrypt_body(struct io_conn *conn, |
|
|
|
struct crypto_state *cs) |
|
|
|
{ |
|
|
|
struct io_plan *plan; |
|
|
|
u8 *in, *decrypted; |
|
|
|
|
|
|
|
decrypted = cryptomsg_decrypt_body(cs->in, cs, cs->in); |
|
|
|
if (!decrypted) |
|
|
|
return io_close(conn); |
|
|
|
|
|
|
|
/* Steal cs->in: we free it after, and decrypted too unless
|
|
|
|
* they steal but be careful not to touch anything after |
|
|
@ -127,8 +142,7 @@ static struct io_plan *peer_decrypt_body(struct io_conn *conn, |
|
|
|
return plan; |
|
|
|
} |
|
|
|
|
|
|
|
static struct io_plan *peer_decrypt_header(struct io_conn *conn, |
|
|
|
struct crypto_state *cs) |
|
|
|
bool cryptomsg_decrypt_header(struct crypto_state *cs, u8 *hdr, u16 *lenp) |
|
|
|
{ |
|
|
|
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES]; |
|
|
|
unsigned long long mlen; |
|
|
@ -148,15 +162,27 @@ static struct io_plan *peer_decrypt_header(struct io_conn *conn, |
|
|
|
*/ |
|
|
|
if (crypto_aead_chacha20poly1305_ietf_decrypt((unsigned char *)&len, |
|
|
|
&mlen, NULL, |
|
|
|
memcheck(cs->in, |
|
|
|
tal_count(cs->in)), |
|
|
|
tal_count(cs->in), |
|
|
|
memcheck(hdr, |
|
|
|
tal_count(hdr)), |
|
|
|
tal_count(hdr), |
|
|
|
NULL, 0, |
|
|
|
npub, cs->rk.u.u8) != 0) { |
|
|
|
/* FIXME: Report error! */ |
|
|
|
return io_close(conn); |
|
|
|
return false; |
|
|
|
} |
|
|
|
assert(mlen == sizeof(len)); |
|
|
|
*lenp = be16_to_cpu(len); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static struct io_plan *peer_decrypt_header(struct io_conn *conn, |
|
|
|
struct crypto_state *cs) |
|
|
|
{ |
|
|
|
u16 len; |
|
|
|
|
|
|
|
if (!cryptomsg_decrypt_header(cs, cs->in, &len)) |
|
|
|
return io_close(conn); |
|
|
|
|
|
|
|
tal_free(cs->in); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
@ -164,7 +190,7 @@ static struct io_plan *peer_decrypt_header(struct io_conn *conn, |
|
|
|
* * Read _exactly_ `l+16` bytes from the network buffer, let |
|
|
|
* the bytes be known as `c`. |
|
|
|
*/ |
|
|
|
cs->in = tal_arr(cs, u8, (u32)be16_to_cpu(len) + 16); |
|
|
|
cs->in = tal_arr(cs, u8, (u32)len + 16); |
|
|
|
return io_read(conn, cs->in, tal_count(cs->in), peer_decrypt_body, cs); |
|
|
|
} |
|
|
|
|
|
|
@ -196,21 +222,17 @@ static struct io_plan *peer_write_done(struct io_conn *conn, |
|
|
|
return cs->next_out(conn, cs->peer); |
|
|
|
} |
|
|
|
|
|
|
|
struct io_plan *peer_write_message(struct io_conn *conn, |
|
|
|
struct crypto_state *cs, |
|
|
|
const u8 *msg, |
|
|
|
struct io_plan *(*next)(struct io_conn *, |
|
|
|
struct peer *)) |
|
|
|
u8 *cryptomsg_encrypt_msg(const tal_t *ctx, |
|
|
|
struct crypto_state *cs, |
|
|
|
const u8 *msg) |
|
|
|
{ |
|
|
|
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES]; |
|
|
|
unsigned long long clen, mlen = tal_count(msg); |
|
|
|
be16 l; |
|
|
|
int ret; |
|
|
|
u8 *out; |
|
|
|
|
|
|
|
assert(!cs->out); |
|
|
|
|
|
|
|
cs->out = tal_arr(cs, u8, sizeof(l) + 16 + mlen + 16); |
|
|
|
cs->next_out = next; |
|
|
|
out = tal_arr(cs, u8, sizeof(l) + 16 + mlen + 16); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
@ -236,7 +258,7 @@ struct io_plan *peer_write_message(struct io_conn *conn, |
|
|
|
* * A zero-length byte slice is to be passed as the AD |
|
|
|
*/ |
|
|
|
le64_nonce(npub, cs->sn++); |
|
|
|
ret = crypto_aead_chacha20poly1305_ietf_encrypt(cs->out, &clen, |
|
|
|
ret = crypto_aead_chacha20poly1305_ietf_encrypt(out, &clen, |
|
|
|
(unsigned char *) |
|
|
|
memcheck(&l, sizeof(l)), |
|
|
|
sizeof(l), |
|
|
@ -250,7 +272,7 @@ struct io_plan *peer_write_message(struct io_conn *conn, |
|
|
|
tal_hexstr(trc, &l, sizeof(l)), |
|
|
|
tal_hexstr(trc, npub, sizeof(npub)), |
|
|
|
tal_hexstr(trc, &cs->sk, sizeof(cs->sk)), |
|
|
|
tal_hexstr(trc, cs->out, clen)); |
|
|
|
tal_hexstr(trc, out, clen)); |
|
|
|
#endif |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
@ -262,7 +284,7 @@ struct io_plan *peer_write_message(struct io_conn *conn, |
|
|
|
* * The nonce `sn` MUST be incremented after this step. |
|
|
|
*/ |
|
|
|
le64_nonce(npub, cs->sn++); |
|
|
|
ret = crypto_aead_chacha20poly1305_ietf_encrypt(cs->out + clen, &clen, |
|
|
|
ret = crypto_aead_chacha20poly1305_ietf_encrypt(out + clen, &clen, |
|
|
|
memcheck(msg, mlen), |
|
|
|
mlen, |
|
|
|
NULL, 0, |
|
|
@ -275,11 +297,25 @@ struct io_plan *peer_write_message(struct io_conn *conn, |
|
|
|
tal_hexstr(trc, msg, mlen), |
|
|
|
tal_hexstr(trc, npub, sizeof(npub)), |
|
|
|
tal_hexstr(trc, &cs->sk, sizeof(cs->sk)), |
|
|
|
tal_hexstr(trc, cs->out + 18, clen)); |
|
|
|
tal_hexstr(trc, out + 18, clen)); |
|
|
|
#endif |
|
|
|
|
|
|
|
maybe_rotate_key(&cs->sn, &cs->sk, &cs->s_ck); |
|
|
|
|
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
struct io_plan *peer_write_message(struct io_conn *conn, |
|
|
|
struct crypto_state *cs, |
|
|
|
const u8 *msg, |
|
|
|
struct io_plan *(*next)(struct io_conn *, |
|
|
|
struct peer *)) |
|
|
|
{ |
|
|
|
assert(!cs->out); |
|
|
|
|
|
|
|
cs->out = cryptomsg_encrypt_msg(cs, cs, msg); |
|
|
|
cs->next_out = next; |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* * Send `lc || c` over the network buffer. |
|
|
|
*/ |
|
|
|