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)
{
struct pubkey node_id;
struct privkey peer_seed;
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);
if (bip32_key_serialize(&secretstuff.bip32, BIP32_FLAG_KEY_PUBLIC,
serialized_extkey, tal_len(serialized_extkey))
@ -148,7 +154,8 @@ static u8 *init_response(struct conn_info *control)
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"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);
return msg;
}

View file

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

View file

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

View file

@ -4,6 +4,7 @@
#include "peer_control.h"
#include "subdaemon.h"
#include <ccan/array_size/array_size.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/err/err.h>
#include <ccan/io/fdpass/fdpass.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);
list_head_init(&ld->peers);
ld->peer_counter = 0;
ld->bip32_max_index = 0;
list_head_init(&ld->utxos);
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));
}
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[])
{
struct lightningd *ld = new_lightningd(NULL);

View file

@ -1,6 +1,7 @@
#ifndef LIGHTNING_LIGHTNINGD_LIGHTNINGD_H
#define LIGHTNING_LIGHTNINGD_LIGHTNINGD_H
#include "config.h"
#include <bitcoin/privkey.h>
#include <ccan/container_of/container_of.h>
#include <daemon/lightningd.h>
@ -30,6 +31,10 @@ struct lightningd {
/* All peers we're tracking. */
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. */
struct ext_key *bip32_base;
@ -39,6 +44,9 @@ struct lightningd {
struct list_head utxos;
};
void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed,
const struct pubkey *peer_id);
/* FIXME */
static inline struct lightningd *
ld_from_dstate(const struct lightningd_state *dstate)