mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +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:
parent
f66445c1d1
commit
e3f2d72d4d
@ -37,6 +37,7 @@ LIGHTNINGD_LIB_SRC := \
|
||||
lightningd/channel_config.c \
|
||||
lightningd/commit_tx.c \
|
||||
lightningd/cryptomsg.c \
|
||||
lightningd/crypto_sync.c \
|
||||
lightningd/funding_tx.c \
|
||||
lightningd/htlc_tx.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));
|
||||
}
|
||||
|
||||
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,
|
||||
u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
|
||||
struct crypto_state *cs,
|
||||
const u8 *msg,
|
||||
struct io_plan *(*next)(struct io_conn *,
|
||||
struct peer *))
|
||||
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.
|
||||
*/
|
||||
|
@ -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 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user