mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
crypto_sync: synchronous routines for inter-peer crypto.
This is used by the opening daemon, for example. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -37,6 +37,7 @@ LIGHTNINGD_LIB_SRC := \
|
|||||||
lightningd/channel_config.c \
|
lightningd/channel_config.c \
|
||||||
lightningd/commit_tx.c \
|
lightningd/commit_tx.c \
|
||||||
lightningd/cryptomsg.c \
|
lightningd/cryptomsg.c \
|
||||||
|
lightningd/crypto_sync.c \
|
||||||
lightningd/funding_tx.c \
|
lightningd/funding_tx.c \
|
||||||
lightningd/htlc_tx.c \
|
lightningd/htlc_tx.c \
|
||||||
lightningd/key_derive.c \
|
lightningd/key_derive.c \
|
||||||
|
|||||||
34
lightningd/crypto_sync.c
Normal file
34
lightningd/crypto_sync.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include <ccan/read_write_all/read_write_all.h>
|
||||||
|
#include <lightningd/crypto_sync.h>
|
||||||
|
#include <lightningd/cryptomsg.h>
|
||||||
|
#include <wire/wire_sync.h>
|
||||||
|
|
||||||
|
bool sync_crypto_write(struct crypto_state *cs, int fd, const void *msg)
|
||||||
|
{
|
||||||
|
u8 *enc = cryptomsg_encrypt_msg(msg, cs, msg);
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
ret = wire_sync_write(fd, enc);
|
||||||
|
tal_free(enc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *sync_crypto_read(const tal_t *ctx, struct crypto_state *cs, int fd)
|
||||||
|
{
|
||||||
|
u8 hdr[18], *enc, *dec;
|
||||||
|
u16 len;
|
||||||
|
|
||||||
|
if (!read_all(fd, hdr, sizeof(hdr)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!cryptomsg_decrypt_header(cs, hdr, &len))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
enc = tal_arr(ctx, u8, len);
|
||||||
|
if (!read_all(fd, enc, len))
|
||||||
|
return tal_free(enc);
|
||||||
|
|
||||||
|
dec = cryptomsg_decrypt_body(ctx, cs, enc);
|
||||||
|
tal_free(enc);
|
||||||
|
return dec;
|
||||||
|
}
|
||||||
12
lightningd/crypto_sync.h
Normal file
12
lightningd/crypto_sync.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef LIGHTNING_LIGHTNINGD_CRYPTO_SYNC_H
|
||||||
|
#define LIGHTNING_LIGHTNINGD_CRYPTO_SYNC_H
|
||||||
|
#include "config.h"
|
||||||
|
#include <ccan/short_types/short_types.h>
|
||||||
|
#include <ccan/tal/tal.h>
|
||||||
|
|
||||||
|
struct crypto_state;
|
||||||
|
|
||||||
|
bool sync_crypto_write(struct crypto_state *cs, int fd, const void *msg);
|
||||||
|
u8 *sync_crypto_read(const tal_t *ctx, struct crypto_state *cs, int fd);
|
||||||
|
|
||||||
|
#endif /* LIGHTNING_LIGHTNINGD_CRYPTO_SYNC_H */
|
||||||
@@ -85,13 +85,17 @@ static void le64_nonce(unsigned char *npub, u64 nonce)
|
|||||||
memcpy(npub + zerolen, &le_nonce, sizeof(le_nonce));
|
memcpy(npub + zerolen, &le_nonce, sizeof(le_nonce));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct io_plan *peer_decrypt_body(struct io_conn *conn,
|
u8 *cryptomsg_decrypt_body(const tal_t *ctx,
|
||||||
struct crypto_state *cs)
|
struct crypto_state *cs, const u8 *in)
|
||||||
{
|
{
|
||||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||||
unsigned long long mlen;
|
unsigned long long mlen;
|
||||||
u8 *decrypted = tal_arr(cs->in, u8, tal_count(cs->in) - 16), *in;
|
size_t inlen = tal_count(in);
|
||||||
struct io_plan *plan;
|
u8 *decrypted;
|
||||||
|
|
||||||
|
if (inlen < 16)
|
||||||
|
return NULL;
|
||||||
|
decrypted = tal_arr(ctx, u8, inlen - 16);
|
||||||
|
|
||||||
le64_nonce(npub, cs->rn++);
|
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,
|
if (crypto_aead_chacha20poly1305_ietf_decrypt(decrypted,
|
||||||
&mlen, NULL,
|
&mlen, NULL,
|
||||||
memcheck(cs->in,
|
memcheck(in, inlen),
|
||||||
tal_count(cs->in)),
|
inlen,
|
||||||
tal_count(cs->in),
|
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
npub, cs->rk.u.u8) != 0) {
|
npub, cs->rk.u.u8) != 0) {
|
||||||
/* FIXME: Report error! */
|
/* FIXME: Report error! */
|
||||||
return io_close(conn);
|
return tal_free(decrypted);
|
||||||
}
|
}
|
||||||
assert(mlen == tal_count(decrypted));
|
assert(mlen == tal_count(decrypted));
|
||||||
|
|
||||||
maybe_rotate_key(&cs->rn, &cs->rk, &cs->r_ck);
|
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
|
/* Steal cs->in: we free it after, and decrypted too unless
|
||||||
* they steal but be careful not to touch anything after
|
* 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;
|
return plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct io_plan *peer_decrypt_header(struct io_conn *conn,
|
bool cryptomsg_decrypt_header(struct crypto_state *cs, u8 *hdr, u16 *lenp)
|
||||||
struct crypto_state *cs)
|
|
||||||
{
|
{
|
||||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||||
unsigned long long mlen;
|
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,
|
if (crypto_aead_chacha20poly1305_ietf_decrypt((unsigned char *)&len,
|
||||||
&mlen, NULL,
|
&mlen, NULL,
|
||||||
memcheck(cs->in,
|
memcheck(hdr,
|
||||||
tal_count(cs->in)),
|
tal_count(hdr)),
|
||||||
tal_count(cs->in),
|
tal_count(hdr),
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
npub, cs->rk.u.u8) != 0) {
|
npub, cs->rk.u.u8) != 0) {
|
||||||
/* FIXME: Report error! */
|
/* FIXME: Report error! */
|
||||||
return io_close(conn);
|
return false;
|
||||||
}
|
}
|
||||||
assert(mlen == sizeof(len));
|
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);
|
tal_free(cs->in);
|
||||||
|
|
||||||
/* BOLT #8:
|
/* 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
|
* * Read _exactly_ `l+16` bytes from the network buffer, let
|
||||||
* the bytes be known as `c`.
|
* 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);
|
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);
|
return cs->next_out(conn, cs->peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct io_plan *peer_write_message(struct io_conn *conn,
|
u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
|
||||||
struct crypto_state *cs,
|
struct crypto_state *cs,
|
||||||
const u8 *msg,
|
const u8 *msg)
|
||||||
struct io_plan *(*next)(struct io_conn *,
|
|
||||||
struct peer *))
|
|
||||||
{
|
{
|
||||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||||
unsigned long long clen, mlen = tal_count(msg);
|
unsigned long long clen, mlen = tal_count(msg);
|
||||||
be16 l;
|
be16 l;
|
||||||
int ret;
|
int ret;
|
||||||
|
u8 *out;
|
||||||
|
|
||||||
assert(!cs->out);
|
out = tal_arr(cs, u8, sizeof(l) + 16 + mlen + 16);
|
||||||
|
|
||||||
cs->out = tal_arr(cs, u8, sizeof(l) + 16 + mlen + 16);
|
|
||||||
cs->next_out = next;
|
|
||||||
|
|
||||||
/* BOLT #8:
|
/* 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
|
* * A zero-length byte slice is to be passed as the AD
|
||||||
*/
|
*/
|
||||||
le64_nonce(npub, cs->sn++);
|
le64_nonce(npub, cs->sn++);
|
||||||
ret = crypto_aead_chacha20poly1305_ietf_encrypt(cs->out, &clen,
|
ret = crypto_aead_chacha20poly1305_ietf_encrypt(out, &clen,
|
||||||
(unsigned char *)
|
(unsigned char *)
|
||||||
memcheck(&l, sizeof(l)),
|
memcheck(&l, sizeof(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, &l, sizeof(l)),
|
||||||
tal_hexstr(trc, npub, sizeof(npub)),
|
tal_hexstr(trc, npub, sizeof(npub)),
|
||||||
tal_hexstr(trc, &cs->sk, sizeof(cs->sk)),
|
tal_hexstr(trc, &cs->sk, sizeof(cs->sk)),
|
||||||
tal_hexstr(trc, cs->out, clen));
|
tal_hexstr(trc, out, clen));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BOLT #8:
|
/* 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.
|
* * The nonce `sn` MUST be incremented after this step.
|
||||||
*/
|
*/
|
||||||
le64_nonce(npub, cs->sn++);
|
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),
|
memcheck(msg, mlen),
|
||||||
mlen,
|
mlen,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
@@ -275,11 +297,25 @@ struct io_plan *peer_write_message(struct io_conn *conn,
|
|||||||
tal_hexstr(trc, msg, mlen),
|
tal_hexstr(trc, msg, mlen),
|
||||||
tal_hexstr(trc, npub, sizeof(npub)),
|
tal_hexstr(trc, npub, sizeof(npub)),
|
||||||
tal_hexstr(trc, &cs->sk, sizeof(cs->sk)),
|
tal_hexstr(trc, &cs->sk, sizeof(cs->sk)),
|
||||||
tal_hexstr(trc, cs->out + 18, clen));
|
tal_hexstr(trc, out + 18, clen));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
maybe_rotate_key(&cs->sn, &cs->sk, &cs->s_ck);
|
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:
|
/* BOLT #8:
|
||||||
* * Send `lc || c` over the network buffer.
|
* * Send `lc || c` over the network buffer.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -49,4 +49,12 @@ struct io_plan *peer_write_message(struct io_conn *conn,
|
|||||||
|
|
||||||
void towire_crypto_state(u8 **pptr, const struct crypto_state *cs);
|
void towire_crypto_state(u8 **pptr, const struct crypto_state *cs);
|
||||||
void fromwire_crypto_state(const u8 **ptr, size_t *max, struct crypto_state *cs);
|
void fromwire_crypto_state(const u8 **ptr, size_t *max, struct crypto_state *cs);
|
||||||
|
|
||||||
|
/* Low-level functions for sync comms. */
|
||||||
|
u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
|
||||||
|
struct crypto_state *cs,
|
||||||
|
const u8 *msg);
|
||||||
|
bool cryptomsg_decrypt_header(struct crypto_state *cs, u8 *hdr, u16 *lenp);
|
||||||
|
u8 *cryptomsg_decrypt_body(const tal_t *ctx,
|
||||||
|
struct crypto_state *cs, const u8 *in);
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_CRYPTOMSG_H */
|
#endif /* LIGHTNING_LIGHTNINGD_CRYPTOMSG_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user