Skip to content

Commit

Permalink
struct secret: use everywhere.
Browse files Browse the repository at this point in the history
We alternated between using a sha256 and using a privkey, but there are
numerous places where we have a random 32 bytes which are neither.

This fixes many of them (plus, struct privkey is now defined in terms of
struct secret).

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed May 9, 2017
1 parent 42601c2 commit b99c562
Show file tree
Hide file tree
Showing 39 changed files with 250 additions and 215 deletions.
6 changes: 3 additions & 3 deletions bitcoin/base58.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ char *key_to_base58(const tal_t *ctx, bool test_net, const struct privkey *key)
u8 version = test_net ? 239 : 128;
size_t outlen = sizeof(out);

memcpy(buf, key->secret, sizeof(key->secret));
memcpy(buf, key->secret.data, sizeof(key->secret.data));
/* Mark this as a compressed key. */
buf[32] = 1;

Expand Down Expand Up @@ -148,9 +148,9 @@ bool key_from_base58(const char *base58, size_t base58_len,
return false;

/* Copy out secret. */
memcpy(priv->secret, keybuf + 1, sizeof(priv->secret));
memcpy(priv->secret.data, keybuf + 1, sizeof(priv->secret.data));

if (!secp256k1_ec_seckey_verify(secp256k1_ctx, priv->secret))
if (!secp256k1_ec_seckey_verify(secp256k1_ctx, priv->secret.data))
return false;

/* Get public key, too. */
Expand Down
7 changes: 6 additions & 1 deletion bitcoin/privkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
#include "config.h"
#include <ccan/short_types/short_types.h>

/* General 256-bit secret, which must be private. Used in various places. */
struct secret {
u8 data[32];
};

/* This is a private key. Keep it secret. */
struct privkey {
u8 secret[32];
struct secret secret;
};
#endif /* LIGHTNING_BITCOIN_PRIVKEY_H */
3 changes: 2 additions & 1 deletion bitcoin/pubkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bool pubkey_from_privkey(const struct privkey *privkey,
struct pubkey *key)
{
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&key->pubkey, privkey->secret))
&key->pubkey, privkey->secret.data))
return false;
return true;
}
Expand Down Expand Up @@ -98,3 +98,4 @@ static char *privkey_to_hexstr(const tal_t *ctx, const struct privkey *secret)
return str;
}
REGISTER_TYPE_TO_STRING(privkey, privkey_to_hexstr);
REGISTER_TYPE_TO_HEXSTR(secret);
2 changes: 1 addition & 1 deletion bitcoin/signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void sign_hash(const struct privkey *privkey,
ok = secp256k1_ecdsa_sign(secp256k1_ctx,
s,
h->sha.u.u8,
privkey->secret, NULL, NULL);
privkey->secret.data, NULL, NULL);
assert(ok);
}

Expand Down
2 changes: 1 addition & 1 deletion daemon/lightningd.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct lightningd_state {
struct list_head pay_commands;

/* Our private key */
struct secret *secret;
struct privkey *privkey;

/* This is us. */
struct pubkey id;
Expand Down
7 changes: 2 additions & 5 deletions daemon/peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,6 @@ static void their_htlc_added(struct peer *peer, struct htlc *htlc,
struct peer *only_dest)
{
struct invoice *invoice;
struct privkey pk;
struct onionpacket *packet;
struct route_step *step = NULL;

Expand Down Expand Up @@ -909,15 +908,13 @@ static void their_htlc_added(struct peer *peer, struct htlc *htlc,
return;
}

//FIXME: dirty trick to retrieve unexported state
memcpy(&pk, peer->dstate->secret, sizeof(pk));

packet = parse_onionpacket(peer,
htlc->routing, tal_count(htlc->routing));
if (packet) {
u8 shared_secret[32];

if (onion_shared_secret(shared_secret, packet, &pk))
if (onion_shared_secret(shared_secret, packet,
peer->dstate->privkey))
step = process_onionpacket(packet, packet,
shared_secret,
htlc->rhash.u.u8,
Expand Down
24 changes: 10 additions & 14 deletions daemon/secrets.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,13 @@
#include <sys/types.h>
#include <unistd.h>

struct secret {
/* Secret ID of our node; public is dstate->id. */
struct privkey privkey;
};

void privkey_sign(struct lightningd_state *dstate, const void *src, size_t len,
secp256k1_ecdsa_signature *sig)
{
struct sha256_double h;

sha256_double(&h, memcheck(src, len), len);
sign_hash(&dstate->secret->privkey, &h, sig);
sign_hash(dstate->privkey, &h, sig);
}

struct peer_secrets {
Expand Down Expand Up @@ -142,7 +137,8 @@ static void new_keypair(struct lightningd_state *dstate,
struct privkey *privkey, struct pubkey *pubkey)
{
do {
randombytes_buf(privkey->secret, sizeof(privkey->secret));
randombytes_buf(privkey->secret.data,
sizeof(privkey->secret.data));
} while (!pubkey_from_privkey(privkey, pubkey));
}

Expand Down Expand Up @@ -215,22 +211,22 @@ void secrets_init(struct lightningd_state *dstate)
{
int fd;

dstate->secret = tal(dstate, struct secret);
dstate->privkey = tal(dstate, struct privkey);

fd = open("privkey", O_RDONLY);
if (fd < 0) {
if (errno != ENOENT)
fatal("Failed to open privkey: %s", strerror(errno));

log_unusual(dstate->base_log, "Creating privkey file");
new_keypair(dstate, &dstate->secret->privkey, &dstate->id);
new_keypair(dstate, dstate->privkey, &dstate->id);

fd = open("privkey", O_CREAT|O_EXCL|O_WRONLY, 0400);
if (fd < 0)
fatal("Failed to create privkey file: %s",
strerror(errno));
if (!write_all(fd, dstate->secret->privkey.secret,
sizeof(dstate->secret->privkey.secret))) {
if (!write_all(fd, &dstate->privkey->secret,
sizeof(dstate->privkey->secret))) {
unlink_noerr("privkey");
fatal("Failed to write to privkey file: %s",
strerror(errno));
Expand All @@ -244,11 +240,11 @@ void secrets_init(struct lightningd_state *dstate)
if (fd < 0)
fatal("Failed to reopen privkey: %s", strerror(errno));
}
if (!read_all(fd, dstate->secret->privkey.secret,
sizeof(dstate->secret->privkey.secret)))
if (!read_all(fd, &dstate->privkey->secret,
sizeof(dstate->privkey->secret)))
fatal("Failed to read privkey: %s", strerror(errno));
close(fd);
if (!pubkey_from_privkey(&dstate->secret->privkey, &dstate->id))
if (!pubkey_from_privkey(dstate->privkey, &dstate->id))
fatal("Invalid privkey");

log_info_struct(dstate->base_log, "ID: %s", struct pubkey, &dstate->id);
Expand Down
2 changes: 1 addition & 1 deletion daemon/sphinx.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ bool onion_shared_secret(
const struct privkey *privkey)
{
return create_shared_secret(secret, &packet->ephemeralkey,
privkey->secret);
privkey->secret.data);
}

void pubkey_hash160(
Expand Down
3 changes: 2 additions & 1 deletion daemon/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ bool restore_wallet_address(struct lightningd_state *dstate,
static void new_keypair(struct privkey *privkey, struct pubkey *pubkey)
{
do {
randombytes_buf(privkey->secret, sizeof(privkey->secret));
randombytes_buf(privkey->secret.data,
sizeof(privkey->secret.data));
} while (!pubkey_from_privkey(privkey, pubkey));
}

Expand Down
5 changes: 3 additions & 2 deletions lightningd/channel/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ static void their_htlc_locked(const struct htlc *htlc, struct peer *peer)
u8 *msg;
struct onionpacket *op;
struct route_step *rs;
struct sha256 ss, bad_onion_sha;
struct sha256 bad_onion_sha;
struct secret ss;
enum onion_type failcode;
enum channel_remove_err rerr;
struct pubkey ephemeral;
Expand Down Expand Up @@ -625,7 +626,7 @@ static void their_htlc_locked(const struct htlc *htlc, struct peer *peer)
goto bad_onion;
}

rs = process_onionpacket(tmpctx, op, ss.u.u8, htlc->rhash.u.u8,
rs = process_onionpacket(tmpctx, op, ss.data, htlc->rhash.u.u8,
sizeof(htlc->rhash));
if (!rs) {
failcode = WIRE_INVALID_ONION_HMAC;
Expand Down
2 changes: 1 addition & 1 deletion lightningd/channel/channel_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ channel_accepted_htlc,0,forward,bool
channel_accepted_htlc,0,amt_to_forward,u64
channel_accepted_htlc,0,outgoing_cltv_value,u32
channel_accepted_htlc,0,next_channel,struct short_channel_id
channel_accepted_htlc,0,shared_secret,32
channel_accepted_htlc,0,shared_secret,struct secret

# FIXME: Add code to commit current channel state!

Expand Down
36 changes: 18 additions & 18 deletions lightningd/cryptomsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
#include <wire/wire.h>
#include <wire/wire_io.h>

static void hkdf_two_keys(struct sha256 *out1, struct sha256 *out2,
const struct sha256 *in1,
const struct sha256 *in2)
static void hkdf_two_keys(struct secret *out1, struct secret *out2,
const struct secret *in1,
const struct secret *in2)
{
/* BOLT #8:
*
Expand All @@ -26,7 +26,7 @@ static void hkdf_two_keys(struct sha256 *out1, struct sha256 *out2,
* of cryptographic randomness using the extract-and-expand
* component of the `HKDF`.
*/
struct sha256 okm[2];
struct secret okm[2];

BUILD_ASSERT(sizeof(okm) == 64);
hkdf_sha256(okm, sizeof(okm), in1, sizeof(*in1), in2, sizeof(*in2),
Expand All @@ -35,9 +35,9 @@ static void hkdf_two_keys(struct sha256 *out1, struct sha256 *out2,
*out2 = okm[1];
}

static void maybe_rotate_key(u64 *n, struct sha256 *k, struct sha256 *ck)
static void maybe_rotate_key(u64 *n, struct secret *k, struct secret *ck)
{
struct sha256 new_k, new_ck;
struct secret new_k, new_ck;

/* BOLT #8:
*
Expand Down Expand Up @@ -113,7 +113,7 @@ u8 *cryptomsg_decrypt_body(const tal_t *ctx,
memcheck(in, inlen),
inlen,
NULL, 0,
npub, cs->rk.u.u8) != 0) {
npub, cs->rk.data) != 0) {
/* FIXME: Report error! */
return tal_free(decrypted);
}
Expand Down Expand Up @@ -176,7 +176,7 @@ bool cryptomsg_decrypt_header(struct crypto_state *cs, u8 hdr[18], u16 *lenp)
&mlen, NULL,
memcheck(hdr, 18), 18,
NULL, 0,
npub, cs->rk.u.u8) != 0) {
npub, cs->rk.data) != 0) {
/* FIXME: Report error! */
return false;
}
Expand Down Expand Up @@ -275,7 +275,7 @@ u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
sizeof(l),
NULL, 0,
NULL, npub,
cs->sk.u.u8);
cs->sk.data);
assert(ret == 0);
assert(clen == sizeof(l) + 16);
#ifdef SUPERVERBOSE
Expand All @@ -300,7 +300,7 @@ u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
mlen,
NULL, 0,
NULL, npub,
cs->sk.u.u8);
cs->sk.data);
assert(ret == 0);
assert(clen == mlen + 16);
#ifdef SUPERVERBOSE
Expand Down Expand Up @@ -346,18 +346,18 @@ void towire_crypto_state(u8 **ptr, const struct crypto_state *cs)
{
towire_u64(ptr, cs->rn);
towire_u64(ptr, cs->sn);
towire_sha256(ptr, &cs->sk);
towire_sha256(ptr, &cs->rk);
towire_sha256(ptr, &cs->s_ck);
towire_sha256(ptr, &cs->r_ck);
towire_secret(ptr, &cs->sk);
towire_secret(ptr, &cs->rk);
towire_secret(ptr, &cs->s_ck);
towire_secret(ptr, &cs->r_ck);
}

void fromwire_crypto_state(const u8 **ptr, size_t *max, struct crypto_state *cs)
{
cs->rn = fromwire_u64(ptr, max);
cs->sn = fromwire_u64(ptr, max);
fromwire_sha256(ptr, max, &cs->sk);
fromwire_sha256(ptr, max, &cs->rk);
fromwire_sha256(ptr, max, &cs->s_ck);
fromwire_sha256(ptr, max, &cs->r_ck);
fromwire_secret(ptr, max, &cs->sk);
fromwire_secret(ptr, max, &cs->rk);
fromwire_secret(ptr, max, &cs->s_ck);
fromwire_secret(ptr, max, &cs->r_ck);
}
6 changes: 3 additions & 3 deletions lightningd/cryptomsg.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef LIGHTNING_LIGHTNINGD_CRYPTOMSG_H
#define LIGHTNING_LIGHTNINGD_CRYPTOMSG_H
#include "config.h"
#include <ccan/crypto/sha256/sha256.h>
#include <bitcoin/privkey.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>

Expand All @@ -12,9 +12,9 @@ struct crypto_state {
/* Received and sent nonces. */
u64 rn, sn;
/* Sending and receiving keys. */
struct sha256 sk, rk;
struct secret sk, rk;
/* Chaining key for re-keying */
struct sha256 s_ck, r_ck;
struct secret s_ck, r_ck;
};

struct peer_crypto_state {
Expand Down
6 changes: 3 additions & 3 deletions lightningd/derive_basepoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ bool derive_basepoints(const struct privkey *seed,
"c-lightning", strlen("c-lightning"));

secrets->funding_privkey = keys.f;
secrets->revocation_basepoint_secret = keys.r;
secrets->payment_basepoint_secret = keys.p;
secrets->delayed_payment_basepoint_secret = keys.d;
secrets->revocation_basepoint_secret = keys.r.secret;
secrets->payment_basepoint_secret = keys.p.secret;
secrets->delayed_payment_basepoint_secret = keys.d.secret;

if (!pubkey_from_privkey(&keys.f, funding_pubkey)
|| !pubkey_from_privkey(&keys.r, &basepoints->revocation)
Expand Down
6 changes: 3 additions & 3 deletions lightningd/derive_basepoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ struct basepoints {

struct secrets {
struct privkey funding_privkey;
struct privkey revocation_basepoint_secret;
struct privkey payment_basepoint_secret;
struct privkey delayed_payment_basepoint_secret;
struct secret revocation_basepoint_secret;
struct secret payment_basepoint_secret;
struct secret delayed_payment_basepoint_secret;
};

bool derive_basepoints(const struct privkey *seed,
Expand Down
2 changes: 1 addition & 1 deletion lightningd/dev_newhtlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static void json_dev_newhtlc(struct command *cmd,
u8 *onion;
struct htlc_end *hend;
struct pubkey *path = tal_arrz(cmd, struct pubkey, 1);
struct sha256 *shared_secrets;
struct secret *shared_secrets;

if (!json_get_params(buffer, params,
"peerid", &peeridtok,
Expand Down
Loading

0 comments on commit b99c562

Please sign in to comment.