lightningd/hsm: create a peer-seed for peer secrets.

For the moment this is simply handed through to lightningd for
generating the per-peer secrets; eventually the HSM should keep it and
all peer secret key operations would be done via HSM-ops.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-02-24 16:22:56 +10:30
parent 90737371d0
commit 7525ed787a
5 changed files with 39 additions and 3 deletions

View file

@ -139,8 +139,14 @@ static u8 *handle_ecdh(struct client *c, const void *data)
static u8 *init_response(struct conn_info *control) static u8 *init_response(struct conn_info *control)
{ {
struct pubkey node_id; struct pubkey node_id;
struct privkey peer_seed;
u8 *serialized_extkey = tal_arr(control, u8, BIP32_SERIALIZED_LEN), *msg; u8 *serialized_extkey = tal_arr(control, u8, BIP32_SERIALIZED_LEN), *msg;
hkdf_sha256(&peer_seed, sizeof(peer_seed), NULL, 0,
&secretstuff.hsm_secret,
sizeof(secretstuff.hsm_secret),
"peer seed", strlen("peer seed"));
node_key(NULL, &node_id); node_key(NULL, &node_id);
if (bip32_key_serialize(&secretstuff.bip32, BIP32_FLAG_KEY_PUBLIC, if (bip32_key_serialize(&secretstuff.bip32, BIP32_FLAG_KEY_PUBLIC,
serialized_extkey, tal_len(serialized_extkey)) serialized_extkey, tal_len(serialized_extkey))
@ -148,7 +154,8 @@ static u8 *init_response(struct conn_info *control)
status_failed(WIRE_HSMSTATUS_KEY_FAILED, status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"Can't serialize bip32 public key"); "Can't serialize bip32 public key");
msg = towire_hsmctl_init_response(control, &node_id, serialized_extkey); msg = towire_hsmctl_init_response(control, &node_id, &peer_seed,
serialized_extkey);
tal_free(serialized_extkey); tal_free(serialized_extkey);
return msg; return msg;
} }

View file

@ -4,8 +4,9 @@ hsmctl_init_load,2
hsmctl_init_response,100 hsmctl_init_response,100
hsmctl_init_response,0,node_id,33 hsmctl_init_response,0,node_id,33
hsmctl_init_response,33,bip32_len,2 hsmctl_init_response,33,peer_seed,32,struct privkey
hsmctl_init_response,35,bip32_seed,bip32_len*1,u8 hsmctl_init_response,65,bip32_len,2
hsmctl_init_response,67,bip32_seed,bip32_len*1,u8
# ECDH returns an fd. # ECDH returns an fd.
hsmctl_hsmfd_ecdh,3 hsmctl_hsmfd_ecdh,3

View file

@ -17,6 +17,7 @@ static void hsm_init_done(struct subdaemon *hsm, const u8 *msg,
u8 *serialized_extkey; u8 *serialized_extkey;
if (!fromwire_hsmctl_init_response(hsm, msg, NULL, &ld->dstate.id, if (!fromwire_hsmctl_init_response(hsm, msg, NULL, &ld->dstate.id,
&ld->peer_seed,
&serialized_extkey)) &serialized_extkey))
errx(1, "HSM did not give init response"); errx(1, "HSM did not give init response");

View file

@ -4,6 +4,7 @@
#include "peer_control.h" #include "peer_control.h"
#include "subdaemon.h" #include "subdaemon.h"
#include <ccan/array_size/array_size.h> #include <ccan/array_size/array_size.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/err/err.h> #include <ccan/err/err.h>
#include <ccan/io/fdpass/fdpass.h> #include <ccan/io/fdpass/fdpass.h>
#include <ccan/io/io.h> #include <ccan/io/io.h>
@ -71,6 +72,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
struct lightningd *ld = tal(ctx, struct lightningd); struct lightningd *ld = tal(ctx, struct lightningd);
list_head_init(&ld->peers); list_head_init(&ld->peers);
ld->peer_counter = 0;
ld->bip32_max_index = 0; ld->bip32_max_index = 0;
list_head_init(&ld->utxos); list_head_init(&ld->utxos);
ld->dstate.log_book = new_log_book(&ld->dstate, 20*1024*1024,LOG_INFORM); ld->dstate.log_book = new_log_book(&ld->dstate, 20*1024*1024,LOG_INFORM);
@ -143,6 +145,23 @@ static const char *find_my_path(const tal_t *ctx, const char *argv0)
return path_dirname(ctx, take(me)); return path_dirname(ctx, take(me));
} }
void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed,
const struct pubkey *peer_id)
{
be64 counter = cpu_to_be64(ld->peer_counter);
u8 input[PUBKEY_DER_LEN + sizeof(counter)];
pubkey_to_der(input, peer_id);
memcpy(input + PUBKEY_DER_LEN, &counter, sizeof(counter));
hkdf_sha256(peer_seed, sizeof(*peer_seed),
input, sizeof(input),
&ld->peer_seed, sizeof(ld->peer_seed),
"per-ppeer seed", strlen("per-peer seed"));
/* FIXME: This must be saved in db. */
ld->peer_counter++;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct lightningd *ld = new_lightningd(NULL); struct lightningd *ld = new_lightningd(NULL);

View file

@ -1,6 +1,7 @@
#ifndef LIGHTNING_LIGHTNINGD_LIGHTNINGD_H #ifndef LIGHTNING_LIGHTNINGD_LIGHTNINGD_H
#define LIGHTNING_LIGHTNINGD_LIGHTNINGD_H #define LIGHTNING_LIGHTNINGD_LIGHTNINGD_H
#include "config.h" #include "config.h"
#include <bitcoin/privkey.h>
#include <ccan/container_of/container_of.h> #include <ccan/container_of/container_of.h>
#include <daemon/lightningd.h> #include <daemon/lightningd.h>
@ -30,6 +31,10 @@ struct lightningd {
/* All peers we're tracking. */ /* All peers we're tracking. */
struct list_head peers; struct list_head peers;
/* FIXME: This should stay in HSM */
struct privkey peer_seed;
/* Used to give a unique seed to every peer. */
u64 peer_counter;
/* Public base for bip32 keys, and max we've ever used. */ /* Public base for bip32 keys, and max we've ever used. */
struct ext_key *bip32_base; struct ext_key *bip32_base;
@ -39,6 +44,9 @@ struct lightningd {
struct list_head utxos; struct list_head utxos;
}; };
void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed,
const struct pubkey *peer_id);
/* FIXME */ /* FIXME */
static inline struct lightningd * static inline struct lightningd *
ld_from_dstate(const struct lightningd_state *dstate) ld_from_dstate(const struct lightningd_state *dstate)