From b99c5620efc8dac60e3db714ab1aa028a959e7a9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 6 May 2017 11:49:44 +0930 Subject: [PATCH] struct secret: use everywhere. 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 --- bitcoin/base58.c | 6 +- bitcoin/privkey.h | 7 ++- bitcoin/pubkey.c | 3 +- bitcoin/signature.c | 2 +- daemon/lightningd.h | 2 +- daemon/peer.c | 7 +-- daemon/secrets.c | 24 ++++---- daemon/sphinx.c | 2 +- daemon/wallet.c | 3 +- lightningd/channel/channel.c | 5 +- lightningd/channel/channel_wire.csv | 2 +- lightningd/cryptomsg.c | 36 ++++++------ lightningd/cryptomsg.h | 6 +- lightningd/derive_basepoints.c | 6 +- lightningd/derive_basepoints.h | 6 +- lightningd/dev_newhtlc.c | 2 +- lightningd/handshake/handshake.c | 50 +++++++--------- lightningd/handshake/test/run-handshake.c | 22 +++---- lightningd/hsm/client.c | 2 +- lightningd/hsm/client.h | 4 +- lightningd/hsm/hsm.c | 24 ++++---- lightningd/hsm/hsm_client_wire_csv | 4 +- lightningd/hsm/hsm_wire.csv | 4 +- lightningd/htlc_end.h | 4 +- lightningd/key_derive.c | 23 ++++---- lightningd/key_derive.h | 7 ++- lightningd/lightningd.h | 2 +- lightningd/pay.c | 2 +- lightningd/peer_control.c | 13 ++--- lightningd/sphinx.c | 22 +++---- lightningd/sphinx.h | 11 ++-- lightningd/test/run-commit_tx.c | 70 +++++++++++++---------- lightningd/test/run-cryptomsg.c | 16 +++--- lightningd/test/run-key_derive.c | 23 +++++--- test/test_sphinx.c | 26 ++++++--- type_to_string.h | 1 + wire/fromwire.c | 7 ++- wire/towire.c | 7 ++- wire/wire.h | 2 + 39 files changed, 250 insertions(+), 215 deletions(-) diff --git a/bitcoin/base58.c b/bitcoin/base58.c index 555002aa5..159ed55da 100644 --- a/bitcoin/base58.c +++ b/bitcoin/base58.c @@ -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; @@ -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. */ diff --git a/bitcoin/privkey.h b/bitcoin/privkey.h index 5ed4c4937..817606c1e 100644 --- a/bitcoin/privkey.h +++ b/bitcoin/privkey.h @@ -3,8 +3,13 @@ #include "config.h" #include +/* 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 */ diff --git a/bitcoin/pubkey.c b/bitcoin/pubkey.c index 4424bda95..499814b92 100644 --- a/bitcoin/pubkey.c +++ b/bitcoin/pubkey.c @@ -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; } @@ -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); diff --git a/bitcoin/signature.c b/bitcoin/signature.c index df64d769c..9b823025e 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -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); } diff --git a/daemon/lightningd.h b/daemon/lightningd.h index 56dca1dbf..ae6c826fd 100644 --- a/daemon/lightningd.h +++ b/daemon/lightningd.h @@ -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; diff --git a/daemon/peer.c b/daemon/peer.c index dce48987d..36f591bdc 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -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; @@ -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, diff --git a/daemon/secrets.c b/daemon/secrets.c index c1f367a83..0ce9ca78c 100644 --- a/daemon/secrets.c +++ b/daemon/secrets.c @@ -22,18 +22,13 @@ #include #include -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 { @@ -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)); } @@ -215,7 +211,7 @@ 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) { @@ -223,14 +219,14 @@ void secrets_init(struct lightningd_state *dstate) 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)); @@ -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); diff --git a/daemon/sphinx.c b/daemon/sphinx.c index 0bd99c7ab..b60e27380 100644 --- a/daemon/sphinx.c +++ b/daemon/sphinx.c @@ -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( diff --git a/daemon/wallet.c b/daemon/wallet.c index 8f33c6137..9e39c54ad 100644 --- a/daemon/wallet.c +++ b/daemon/wallet.c @@ -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)); } diff --git a/lightningd/channel/channel.c b/lightningd/channel/channel.c index 2dd846e78..48be0c9be 100644 --- a/lightningd/channel/channel.c +++ b/lightningd/channel/channel.c @@ -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; @@ -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; diff --git a/lightningd/channel/channel_wire.csv b/lightningd/channel/channel_wire.csv index 9eb3f0362..9c31a6b84 100644 --- a/lightningd/channel/channel_wire.csv +++ b/lightningd/channel/channel_wire.csv @@ -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! diff --git a/lightningd/cryptomsg.c b/lightningd/cryptomsg.c index df1948cf0..3e37191cc 100644 --- a/lightningd/cryptomsg.c +++ b/lightningd/cryptomsg.c @@ -14,9 +14,9 @@ #include #include -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: * @@ -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), @@ -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: * @@ -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); } @@ -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; } @@ -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 @@ -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 @@ -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); } diff --git a/lightningd/cryptomsg.h b/lightningd/cryptomsg.h index 2028fcecb..5bd21e41e 100644 --- a/lightningd/cryptomsg.h +++ b/lightningd/cryptomsg.h @@ -1,7 +1,7 @@ #ifndef LIGHTNING_LIGHTNINGD_CRYPTOMSG_H #define LIGHTNING_LIGHTNINGD_CRYPTOMSG_H #include "config.h" -#include +#include #include #include @@ -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 { diff --git a/lightningd/derive_basepoints.c b/lightningd/derive_basepoints.c index ba3f85c71..d846e2189 100644 --- a/lightningd/derive_basepoints.c +++ b/lightningd/derive_basepoints.c @@ -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) diff --git a/lightningd/derive_basepoints.h b/lightningd/derive_basepoints.h index c92e4e423..560c08df1 100644 --- a/lightningd/derive_basepoints.h +++ b/lightningd/derive_basepoints.h @@ -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, diff --git a/lightningd/dev_newhtlc.c b/lightningd/dev_newhtlc.c index 17ad3adeb..0e13b42ab 100644 --- a/lightningd/dev_newhtlc.c +++ b/lightningd/dev_newhtlc.c @@ -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, diff --git a/lightningd/handshake/handshake.c b/lightningd/handshake/handshake.c index f3c5aaf74..3f8aed0f9 100644 --- a/lightningd/handshake/handshake.c +++ b/lightningd/handshake/handshake.c @@ -25,12 +25,6 @@ #define REQ_FD STDIN_FILENO -/* Representing chacha keys and ecdh results we derive them from; - * even though it's not really an SHA */ -struct secret { - struct sha256 s; -}; - /* BOLT #8: * * * `generateKey()` @@ -51,9 +45,9 @@ static struct keypair generate_key(void) struct keypair k; do { - randombytes_buf(k.priv.secret, sizeof(k.priv.secret)); + randombytes_buf(k.priv.secret.data, sizeof(k.priv.secret.data)); } while (!secp256k1_ec_pubkey_create(secp256k1_ctx, - &k.pub.pubkey, k.priv.secret)); + &k.pub.pubkey, k.priv.secret.data)); return k; } @@ -181,7 +175,7 @@ static void encrypt_ad(const struct secret *k, u64 nonce, memcheck(plaintext, plaintext_len), plaintext_len, additional_data, additional_data_len, - NULL, npub, k->s.u.u8); + NULL, npub, k->data); assert(ret == 0); assert(clen == plaintext_len + crypto_aead_chacha20poly1305_ietf_ABYTES); } @@ -213,7 +207,7 @@ static bool decrypt(const struct secret *k, u64 nonce, memcheck(ciphertext, ciphertext_len), ciphertext_len, additional_data, additional_data_len, - npub, k->s.u.u8) != 0) + npub, k->data) != 0) return false; assert(mlen == ciphertext_len - crypto_aead_chacha20poly1305_ietf_ABYTES); @@ -337,10 +331,10 @@ static void act_one_initiator(struct handshake *h, int fd, * * The initiator performs a `ECDH` between its newly generated * ephemeral key with the remote node's static public key. */ - if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8, - &their_id->pubkey, h->e.priv.secret)) + if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, + &their_id->pubkey, h->e.priv.secret.data)) status_failed(WIRE_INITR_ACT1_BAD_ECDH_FOR_SS, "%s", ""); - status_trace("# ss=0x%s", tal_hexstr(trc, &h->ss.s, sizeof(h->ss.s))); + status_trace("# ss=0x%s", tal_hexstr(trc, h->ss.data, sizeof(h->ss.data))); /* BOLT #8: * @@ -442,7 +436,7 @@ static void act_one_responder(struct handshake *h, int fd, struct pubkey *re) * * The responder performs an `ECDH` between its static public * key and the initiator's ephemeral public key. */ - if (!hsm_do_ecdh(&h->ss.s, re)) + if (!hsm_do_ecdh(&h->ss, re)) status_failed(WIRE_RESPR_ACT1_BAD_HSM_ECDH, "re=%s", type_to_string(trc, struct pubkey, re)); @@ -547,12 +541,12 @@ static void act_two_responder(struct handshake *h, int fd, * * where `re` is the ephemeral key of the initiator which was * received during `ActOne`. */ - if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8, &re->pubkey, - h->e.priv.secret)) + if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &re->pubkey, + h->e.priv.secret.data)) status_failed(WIRE_RESPR_ACT2_BAD_ECDH_FOR_SS, "re=%s e.priv=%s", type_to_string(trc, struct pubkey, re), tal_hexstr(trc, &h->e.priv, sizeof(h->e.priv))); - status_trace("# ss=0x%s", tal_hexstr(trc, &h->ss.s, sizeof(h->ss.s))); + status_trace("# ss=0x%s", tal_hexstr(trc, &h->ss, sizeof(h->ss))); /* BOLT #8: * @@ -652,8 +646,8 @@ static void act_two_initiator(struct handshake *h, int fd, struct pubkey *re) * * * `ss = ECDH(re, e.priv)` */ - if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8, &re->pubkey, - h->e.priv.secret)) + if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &re->pubkey, + h->e.priv.secret.data)) status_failed(WIRE_INITR_ACT2_BAD_ECDH_FOR_SS, "re=%s e.priv=%s", type_to_string(trc, struct pubkey, re), tal_hexstr(trc, &h->e.priv, sizeof(h->e.priv))); @@ -757,7 +751,7 @@ static void act_three_initiator(struct handshake *h, int fd, * * where `re` is the ephemeral public key of the responder. * */ - if (!hsm_do_ecdh(&h->ss.s, re)) + if (!hsm_do_ecdh(&h->ss, re)) status_failed(WIRE_INITR_ACT3_BAD_HSM_ECDH, "re=%s", type_to_string(trc, struct pubkey, re)); @@ -862,8 +856,8 @@ static void act_three_responder(struct handshake *h, int fd, * * `ss = ECDH(rs, e.priv)` * * where `e` is the responder's original ephemeral key */ - if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8, &their_id->pubkey, - h->e.priv.secret)) + if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &their_id->pubkey, + h->e.priv.secret.data)) status_failed(WIRE_RESPR_ACT3_BAD_ECDH_FOR_SS, "rs=%s e.priv=%s", type_to_string(trc, struct pubkey, their_id), tal_hexstr(trc, &h->e.priv, sizeof(h->e.priv))); @@ -990,9 +984,9 @@ int main(int argc, char *argv[]) if (fromwire_handshake_responder(msg, NULL, &my_id)) { responder(clientfd, &my_id, &their_id, &ck, &sk, &rk); cs.rn = cs.sn = 0; - cs.sk = sk.s; - cs.rk = rk.s; - cs.r_ck = cs.s_ck = ck.s; + cs.sk = sk; + cs.rk = rk; + cs.r_ck = cs.s_ck = ck; wire_sync_write(REQ_FD, towire_handshake_responder_reply(msg, &their_id, @@ -1001,9 +995,9 @@ int main(int argc, char *argv[]) &their_id)) { initiator(clientfd, &my_id, &their_id, &ck, &sk, &rk); cs.rn = cs.sn = 0; - cs.sk = sk.s; - cs.rk = rk.s; - cs.r_ck = cs.s_ck = ck.s; + cs.sk = sk; + cs.rk = rk; + cs.r_ck = cs.s_ck = ck; wire_sync_write(REQ_FD, towire_handshake_initiator_reply(msg, &cs)); } else diff --git a/lightningd/handshake/test/run-handshake.c b/lightningd/handshake/test/run-handshake.c index 81eef856b..8d0eba46e 100644 --- a/lightningd/handshake/test/run-handshake.c +++ b/lightningd/handshake/test/run-handshake.c @@ -61,10 +61,10 @@ void hsm_setup(int fd) { } -bool hsm_do_ecdh(struct sha256 *ss, const struct pubkey *point) +bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point) { - return secp256k1_ecdh(secp256k1_ctx, ss->u.u8, &point->pubkey, - privkey.secret) == 1; + return secp256k1_ecdh(secp256k1_ctx, ss->data, &point->pubkey, + privkey.secret.data) == 1; } int main(void) @@ -80,11 +80,11 @@ int main(void) secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); - memset(responder_privkey.secret, 0x21, - sizeof(responder_privkey.secret)); + memset(responder_privkey.secret.data, 0x21, + sizeof(responder_privkey.secret.data)); if (!secp256k1_ec_pubkey_create(secp256k1_ctx, &responder_id.pubkey, - responder_privkey.secret)) + responder_privkey.secret.data)) errx(1, "Keygen failed"); if (pipe(fds1) != 0 || pipe(fds2) != 0) @@ -104,7 +104,7 @@ int main(void) privkey = responder_privkey; status_prefix = "RESPR"; status_trace("ls.priv: 0x%s", - tal_hexstr(trc, responder_privkey.secret, + tal_hexstr(trc, &responder_privkey, sizeof(responder_privkey))); status_trace("ls.pub: 0x%s", type_to_string(trc, struct pubkey, &responder_id)); @@ -125,19 +125,19 @@ int main(void) close(fds2[1]); close(fds1[0]); - memset(initiator_privkey.secret, 0x11, - sizeof(initiator_privkey.secret)); + memset(initiator_privkey.secret.data, 0x11, + sizeof(initiator_privkey.secret.data)); memset(e_priv, 0x12, sizeof(e_priv)); if (!secp256k1_ec_pubkey_create(secp256k1_ctx, &initiator_id.pubkey, - initiator_privkey.secret)) + initiator_privkey.secret.data)) errx(1, "Initiator keygen failed"); privkey = initiator_privkey; status_prefix = "INITR"; status_trace("rs.pub: 0x%s", type_to_string(trc, struct pubkey, &responder_id)); status_trace("ls.priv: 0x%s", - tal_hexstr(trc, initiator_privkey.secret, + tal_hexstr(trc, &initiator_privkey, sizeof(initiator_privkey))); status_trace("ls.pub: 0x%s", type_to_string(trc, struct pubkey, &initiator_id)); diff --git a/lightningd/hsm/client.c b/lightningd/hsm/client.c index a3d4c5588..6656fd5fc 100644 --- a/lightningd/hsm/client.c +++ b/lightningd/hsm/client.c @@ -9,7 +9,7 @@ void hsm_setup(int fd) hsm_fd = fd; } -bool hsm_do_ecdh(struct sha256 *ss, const struct pubkey *point) +bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point) { u8 *req = towire_hsm_ecdh_req(NULL, point), *resp; size_t len; diff --git a/lightningd/hsm/client.h b/lightningd/hsm/client.h index d1be785f1..d31e8d82e 100644 --- a/lightningd/hsm/client.h +++ b/lightningd/hsm/client.h @@ -7,11 +7,11 @@ #include struct pubkey; -struct sha256; +struct secret; /* Setup communication to the HSM */ void hsm_setup(int fd); /* Do ECDH using this node id secret. */ -bool hsm_do_ecdh(struct sha256 *ss, const struct pubkey *point); +bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point); #endif /* LIGHTNING_LIGHTNINGD_HSM_H */ diff --git a/lightningd/hsm/hsm.c b/lightningd/hsm/hsm.c index f38af87ec..0298b1374 100644 --- a/lightningd/hsm/hsm.c +++ b/lightningd/hsm/hsm.c @@ -37,7 +37,7 @@ /* Nobody will ever find it here! */ static struct { - struct privkey hsm_secret; + struct secret hsm_secret; struct ext_key bip32; } secretstuff; @@ -49,26 +49,26 @@ struct client { struct io_plan *(*handle)(struct io_conn *, struct daemon_conn *); }; -static void node_key(struct privkey *node_secret, struct pubkey *node_id) +static void node_key(struct privkey *node_privkey, struct pubkey *node_id) { u32 salt = 0; struct privkey unused_s; struct pubkey unused_k; - if (node_secret == NULL) - node_secret = &unused_s; + if (node_privkey == NULL) + node_privkey = &unused_s; else if (node_id == NULL) node_id = &unused_k; do { - hkdf_sha256(node_secret, sizeof(*node_secret), + hkdf_sha256(node_privkey, sizeof(*node_privkey), &salt, sizeof(salt), &secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret), "nodeid", 6); salt++; } while (!secp256k1_ec_pubkey_create(secp256k1_ctx, &node_id->pubkey, - node_secret->secret)); + node_privkey->secret.data)); } static struct client *new_client(struct daemon_conn *master, @@ -95,7 +95,7 @@ static struct io_plan *handle_ecdh(struct io_conn *conn, struct daemon_conn *dc) struct client *c = container_of(dc, struct client, dc); struct privkey privkey; struct pubkey point; - struct sha256 ss; + struct secret ss; if (!fromwire_hsm_ecdh_req(dc->msg_in, NULL, &point)) { daemon_conn_send(c->master, @@ -106,8 +106,8 @@ static struct io_plan *handle_ecdh(struct io_conn *conn, struct daemon_conn *dc) } node_key(&privkey, NULL); - if (secp256k1_ecdh(secp256k1_ctx, ss.u.u8, &point.pubkey, - privkey.secret) != 1) { + if (secp256k1_ecdh(secp256k1_ctx, ss.data, &point.pubkey, + privkey.secret.data) != 1) { status_trace("secp256k1_ecdh fail for client %"PRIu64, c->id); daemon_conn_send(c->master, take(towire_hsmstatus_client_bad_request(c, @@ -238,7 +238,7 @@ static struct io_plan *handle_channeld(struct io_conn *conn, static void send_init_response(struct daemon_conn *master) { struct pubkey node_id; - struct privkey peer_seed; + struct secret peer_seed; u8 *serialized_extkey = tal_arr(master, u8, BIP32_SERIALIZED_LEN), *msg; hkdf_sha256(&peer_seed, sizeof(peer_seed), NULL, 0, @@ -343,9 +343,9 @@ static void bitcoin_keypair(struct privkey *privkey, "BIP32 of %u failed", index); /* libwally says: The private key with prefix byte 0 */ - memcpy(privkey->secret, ext.priv_key+1, 32); + memcpy(privkey->secret.data, ext.priv_key+1, 32); if (!secp256k1_ec_pubkey_create(secp256k1_ctx, &pubkey->pubkey, - privkey->secret)) + privkey->secret.data)) status_failed(WIRE_HSMSTATUS_KEY_FAILED, "BIP32 pubkey %u create failed", index); } diff --git a/lightningd/hsm/hsm_client_wire_csv b/lightningd/hsm/hsm_client_wire_csv index ba9366aed..66291be3d 100644 --- a/lightningd/hsm/hsm_client_wire_csv +++ b/lightningd/hsm/hsm_client_wire_csv @@ -1,8 +1,8 @@ # Give me ECDH(node-id-secret,point) hsm_ecdh_req,1 -hsm_ecdh_req,0,point,33 +hsm_ecdh_req,0,point,struct pubkey hsm_ecdh_resp,100 -hsm_ecdh_resp,0,ss,32 +hsm_ecdh_resp,0,ss,struct secret hsm_cannouncement_sig_req,2 hsm_cannouncement_sig_req,0,bitcoin_id,struct pubkey diff --git a/lightningd/hsm/hsm_wire.csv b/lightningd/hsm/hsm_wire.csv index 62ba2f86e..aefe3aeb6 100644 --- a/lightningd/hsm/hsm_wire.csv +++ b/lightningd/hsm/hsm_wire.csv @@ -17,7 +17,7 @@ hsmctl_init,0,new,bool hsmctl_init_reply,101 hsmctl_init_reply,0,node_id,33 -hsmctl_init_reply,33,peer_seed,struct privkey +hsmctl_init_reply,33,peer_seed,struct secret hsmctl_init_reply,65,bip32_len,2 hsmctl_init_reply,67,bip32_seed,bip32_len*u8 @@ -49,4 +49,4 @@ hsmctl_hsmfd_channeld,5 hsmctl_hsmfd_channeld,0,unique_id,8 # Empty reply, just an fd -hsmctl_hsmfd_channeld_reply,105 \ No newline at end of file +hsmctl_hsmfd_channeld_reply,105 diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index 10628fdf4..047cd9197 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -31,11 +31,11 @@ struct htlc_end { /* If we are forwarding, remember the shared secret for an * eventual reply */ - struct sha256 *shared_secret; + struct secret *shared_secret; /* If we are the origin, remember all shared secrets, so we * can unwrap an eventual reply */ - struct sha256 *path_secrets; + struct secret *path_secrets; }; static inline const struct htlc_end *keyof_htlc_end(const struct htlc_end *e) diff --git a/lightningd/key_derive.c b/lightningd/key_derive.c index f5aee1538..77d39ed60 100644 --- a/lightningd/key_derive.c +++ b/lightningd/key_derive.c @@ -58,7 +58,7 @@ bool derive_simple_key(const struct pubkey *basepoint, * * secretkey = basepoint-secret + SHA256(per-commitment-point || basepoint) */ -bool derive_simple_privkey(const struct privkey *base_secret, +bool derive_simple_privkey(const struct secret *base_secret, const struct pubkey *basepoint, const struct pubkey *per_commitment_point, struct privkey *key) @@ -77,8 +77,8 @@ bool derive_simple_privkey(const struct privkey *base_secret, printf("# = 0x%s\n", tal_hexstr(tmpctx, &sha, sizeof(sha))); #endif - *key = *base_secret; - if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret, + key->secret = *base_secret; + if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret.data, sha.u.u8) != 1) return false; #ifdef SUPERVERBOSE @@ -175,15 +175,15 @@ bool derive_revocation_key(const struct pubkey *basepoint, * * revocationsecretkey = revocation-basepoint-secret * SHA256(revocation-basepoint || per-commitment-point) + per-commitment-secret*SHA256(per-commitment-point || revocation-basepoint) */ -bool derive_revocation_privkey(const struct privkey *base_secret, - const struct privkey *per_commitment_secret, +bool derive_revocation_privkey(const struct secret *base_secret, + const struct secret *per_commitment_secret, const struct pubkey *basepoint, const struct pubkey *per_commitment_point, struct privkey *key) { struct sha256 sha; unsigned char der_keys[PUBKEY_DER_LEN * 2]; - struct privkey part2; + struct secret part2; pubkey_to_der(der_keys, basepoint); pubkey_to_der(der_keys + PUBKEY_DER_LEN, per_commitment_point); @@ -196,8 +196,9 @@ bool derive_revocation_privkey(const struct privkey *base_secret, printf("# = 0x%s\n", tal_hexstr(tmpctx, sha.u.u8, sizeof(sha.u.u8))), #endif - *key = *base_secret; - if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, key->secret, sha.u.u8) + key->secret = *base_secret; + if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, key->secret.data, + sha.u.u8) != 1) return false; #ifdef SUPERVERBOSE @@ -218,7 +219,7 @@ bool derive_revocation_privkey(const struct privkey *base_secret, #endif part2 = *per_commitment_secret; - if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, part2.secret, + if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, part2.data, sha.u.u8) != 1) return false; #ifdef SUPERVERBOSE @@ -228,8 +229,8 @@ bool derive_revocation_privkey(const struct privkey *base_secret, printf("# = 0x%s\n", tal_hexstr(tmpctx, &part2, sizeof(part2))); #endif - if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret, - part2.secret) != 1) + if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret.data, + part2.data) != 1) return false; #ifdef SUPERVERBOSE diff --git a/lightningd/key_derive.h b/lightningd/key_derive.h index a46a5bde1..0735d13bb 100644 --- a/lightningd/key_derive.h +++ b/lightningd/key_derive.h @@ -3,13 +3,14 @@ #include "config.h" struct pubkey; +struct secret; /* For `localkey`, `remotekey`, `local-delayedkey` and `remote-delayedkey` */ bool derive_simple_key(const struct pubkey *basepoint, const struct pubkey *per_commitment_point, struct pubkey *key); -bool derive_simple_privkey(const struct privkey *base_secret, +bool derive_simple_privkey(const struct secret *base_secret, const struct pubkey *basepoint, const struct pubkey *per_commitment_point, struct privkey *key); @@ -19,8 +20,8 @@ bool derive_revocation_key(const struct pubkey *basepoint, const struct pubkey *per_commitment_point, struct pubkey *key); -bool derive_revocation_privkey(const struct privkey *base_secret, - const struct privkey *per_commitment_secret, +bool derive_revocation_privkey(const struct secret *base_secret, + const struct secret *per_commitment_secret, const struct pubkey *basepoint, const struct pubkey *per_commitment_point, struct privkey *key); diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index d52af114f..169bae71e 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -33,7 +33,7 @@ struct lightningd { /* All peers we're tracking. */ struct list_head peers; /* FIXME: This should stay in HSM */ - struct privkey peer_seed; + struct secret peer_seed; /* Used to give a unique seed to every peer. */ u64 peer_counter; diff --git a/lightningd/pay.c b/lightningd/pay.c index 3573aa528..168090432 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -163,7 +163,7 @@ static void json_sendpay(struct command *cmd, u64 amount, lastamount; struct onionpacket *packet; u8 *msg; - struct sha256 *path_secrets; + struct secret *path_secrets; if (!json_get_params(buffer, params, "route", &routetok, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 3acb8b5f8..01b90c0b5 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -641,12 +641,12 @@ struct decoding_htlc { u32 cltv_expiry; struct sha256 payment_hash; u8 onion[TOTAL_PACKET_SIZE]; - u8 shared_secret[32]; + struct secret shared_secret; }; static void fail_htlc(struct peer *peer, struct htlc_end *hend, const u8 *msg) { - u8 *reply = wrap_onionreply(hend, hend->shared_secret->u.u8, msg); + u8 *reply = wrap_onionreply(hend, hend->shared_secret, msg); subd_send_msg(peer->owner, take(towire_channel_fail_htlc(peer, hend->htlc_id, reply))); if (taken(msg)) @@ -660,7 +660,7 @@ static void fail_local_htlc(struct peer *peer, struct htlc_end *hend, const u8 * log_broken(peer->log, "failed htlc %"PRIu64" code 0x%04x (%s)", hend->htlc_id, failcode, onion_type_name(failcode)); - reply = create_onionreply(hend, hend->shared_secret->u.u8, msg); + reply = create_onionreply(hend, hend->shared_secret, msg); fail_htlc(peer, hend, reply); } @@ -1088,7 +1088,7 @@ static int peer_accepted_htlc(struct peer *peer, const u8 *msg) u8 *req; hend = tal(msg, struct htlc_end); - hend->shared_secret = tal(hend, struct sha256); + hend->shared_secret = tal(hend, struct secret); if (!fromwire_channel_accepted_htlc(msg, NULL, &hend->htlc_id, &hend->msatoshis, &hend->cltv_expiry, &hend->payment_hash, @@ -1179,10 +1179,9 @@ static int peer_failed_htlc(struct peer *peer, const u8 *msg) reason); } else { size_t numhops = tal_count(hend->path_secrets); - u8 **shared_secrets = tal_arr(hend, u8*, numhops); + struct secret *shared_secrets = tal_arr(hend, struct secret, numhops); for (size_t i=0; ipath_secrets[i].u.u8, 32); + shared_secrets[i] = hend->path_secrets[i]; } reply = unwrap_onionreply(msg, shared_secrets, numhops, reason); failcode = fromwire_peektype(reply->msg); diff --git a/lightningd/sphinx.c b/lightningd/sphinx.c index 22d0e2efc..a0a941451 100644 --- a/lightningd/sphinx.c +++ b/lightningd/sphinx.c @@ -233,7 +233,7 @@ bool onion_shared_secret( const struct privkey *privkey) { return create_shared_secret(secret, &packet->ephemeralkey, - privkey->secret); + privkey->secret.data); } void pubkey_hash160( @@ -363,7 +363,7 @@ struct onionpacket *create_onionpacket( const u8 *sessionkey, const u8 *assocdata, const size_t assocdatalen, - struct sha256 **path_secrets + struct secret **path_secrets ) { struct onionpacket *packet = talz(ctx, struct onionpacket); @@ -373,7 +373,7 @@ struct onionpacket *create_onionpacket( u8 nexthmac[SECURITY_PARAMETER]; u8 stream[ROUTING_INFO_SIZE]; struct hop_params *params = generate_hop_params(ctx, sessionkey, path); - struct sha256 *secrets = tal_arr(ctx, struct sha256, num_hops); + struct secret *secrets = tal_arr(ctx, struct secret, num_hops); if (!params) return NULL; @@ -470,7 +470,7 @@ struct route_step *process_onionpacket( return step; } -u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, +u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret, const u8 *failure_msg) { size_t msglen = tal_len(failure_msg); @@ -485,7 +485,7 @@ u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, towire_pad(&payload, padlen); assert(tal_len(payload) == ONION_REPLY_SIZE + 4); - generate_key(key, "um", 2, shared_secret); + generate_key(key, "um", 2, shared_secret->data); compute_hmac(hmac, payload, tal_len(payload), key, KEY_LEN); towire(&reply, hmac, sizeof(hmac)); @@ -495,19 +495,21 @@ u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, return reply; } -u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply) +u8 *wrap_onionreply(const tal_t *ctx, + const struct secret *shared_secret, const u8 *reply) { u8 key[KEY_LEN]; size_t streamlen = tal_len(reply); u8 stream[streamlen]; u8 *result = tal_arr(ctx, u8, streamlen); - generate_key(key, "ammag", 5, shared_secret); + generate_key(key, "ammag", 5, shared_secret->data); generate_cipher_stream(stream, key, streamlen); xorbytes(result, stream, reply, streamlen); return result; } -struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets, +struct onionreply *unwrap_onionreply(const tal_t *ctx, + const struct secret *shared_secrets, const int numhops, const u8 *reply) { tal_t *tmpctx = tal_tmpctx(ctx); @@ -528,11 +530,11 @@ struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets, for (int i = 0; i < numhops; i++) { /* Since the encryption is just XORing with the cipher * stream encryption is identical to decryption */ - msg = wrap_onionreply(tmpctx, shared_secrets[i], msg); + msg = wrap_onionreply(tmpctx, &shared_secrets[i], msg); /* Check if the HMAC matches, this means that this is * the origin */ - generate_key(key, "um", 2, shared_secrets[i]); + generate_key(key, "um", 2, shared_secrets[i].data); compute_hmac(hmac, msg + sizeof(hmac), tal_len(msg) - sizeof(hmac), key, KEY_LEN); if (memcmp(hmac, msg, sizeof(hmac)) == 0) { diff --git a/lightningd/sphinx.h b/lightningd/sphinx.h index beb039249..0b2b8ef17 100644 --- a/lightningd/sphinx.h +++ b/lightningd/sphinx.h @@ -87,7 +87,7 @@ struct onionpacket *create_onionpacket( const u8 * sessionkey, const u8 *assocdata, const size_t assocdatalen, - struct sha256 **path_secrets + struct secret **path_secrets ); /** @@ -162,7 +162,8 @@ struct onionreply { * HMAC * @failure_msg: message (must support tal_len) */ -u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *failure_msg); +u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret, + const u8 *failure_msg); /** * wrap_onionreply - Add another encryption layer to the reply. @@ -172,7 +173,8 @@ u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *failu * encryption. * @reply: the reply to wrap */ -u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply); +u8 *wrap_onionreply(const tal_t *ctx, const struct secret *shared_secret, + const u8 *reply); /** * unwrap_onionreply - Remove layers, check integrity and parse reply @@ -182,7 +184,8 @@ u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply); * @numhops: path length and number of shared_secrets provided * @reply: the incoming reply */ -struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets, +struct onionreply *unwrap_onionreply(const tal_t *ctx, + const struct secret *shared_secrets, const int numhops, const u8 *reply); #endif /* LIGHTNING_DAEMON_SPHINX_H */ diff --git a/lightningd/test/run-commit_tx.c b/lightningd/test/run-commit_tx.c index 417d218e6..b7a8960db 100644 --- a/lightningd/test/run-commit_tx.c +++ b/lightningd/test/run-commit_tx.c @@ -41,9 +41,9 @@ static struct sha256_double txid_from_hex(const char *hex) return sha256; } -static struct privkey privkey_from_hex(const char *hex) +static struct secret secret_from_hex(const char *hex) { - struct privkey pk; + struct secret s; size_t len; if (strstarts(hex, "0x")) hex += 2; @@ -56,9 +56,17 @@ static struct privkey privkey_from_hex(const char *hex) */ if (len == 66 && strends(hex, "01")) len -= 2; - if (!hex_decode(hex, len, &pk, sizeof(pk))) + if (!hex_decode(hex, len, &s, sizeof(s))) abort(); - return pk; + return s; +} + +static bool pubkey_from_secret(const struct secret *secret, + struct pubkey *key) +{ + return secp256k1_ec_pubkey_create(secp256k1_ctx, + &key->pubkey, + secret->data); } static void tx_must_be_eq(const struct bitcoin_tx *a, @@ -420,10 +428,10 @@ int main(void) u16 to_self_delay; /* x_ prefix means internal vars we used to derive spec */ struct privkey local_funding_privkey, x_remote_funding_privkey; - struct privkey x_local_payment_basepoint_secret, x_remote_payment_basepoint_secret; - struct privkey x_local_per_commitment_secret; - struct privkey x_local_delayed_payment_basepoint_secret; - struct privkey x_remote_revocation_basepoint_secret; + struct secret x_local_payment_basepoint_secret, x_remote_payment_basepoint_secret; + struct secret x_local_per_commitment_secret; + struct secret x_local_delayed_payment_basepoint_secret; + struct secret x_remote_revocation_basepoint_secret; struct privkey local_secretkey, x_remote_secretkey; struct privkey x_local_delayed_secretkey; struct pubkey local_funding_pubkey, remote_funding_pubkey; @@ -503,61 +511,61 @@ int main(void) * # From local_delayed_payment_basepoint_secret, local_per_commitment_point and local_delayed_payment_basepoint * INTERNAL: local_delayed_secretkey: adf3464ce9c2f230fd2582fda4c6965e4993ca5524e8c9580e3df0cf226981ad01 */ - local_funding_privkey = privkey_from_hex("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f374901"); - x_remote_funding_privkey = privkey_from_hex("1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e1301"); + local_funding_privkey.secret = secret_from_hex("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f374901"); + x_remote_funding_privkey.secret = secret_from_hex("1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e1301"); SUPERVERBOSE("INTERNAL: remote_funding_privkey: %s01\n", type_to_string(tmpctx, struct privkey, &x_remote_funding_privkey)); - x_local_payment_basepoint_secret = privkey_from_hex("1111111111111111111111111111111111111111111111111111111111111111"); + x_local_payment_basepoint_secret = secret_from_hex("1111111111111111111111111111111111111111111111111111111111111111"); SUPERVERBOSE("INTERNAL: local_payment_basepoint_secret: %s\n", - type_to_string(tmpctx, struct privkey, + type_to_string(tmpctx, struct secret, &x_local_payment_basepoint_secret)); - x_remote_revocation_basepoint_secret = privkey_from_hex("2222222222222222222222222222222222222222222222222222222222222222"); + x_remote_revocation_basepoint_secret = secret_from_hex("2222222222222222222222222222222222222222222222222222222222222222"); SUPERVERBOSE("INTERNAL: remote_revocation_basepoint_secret: %s\n", - type_to_string(tmpctx, struct privkey, + type_to_string(tmpctx, struct secret, &x_remote_revocation_basepoint_secret)); - x_local_delayed_payment_basepoint_secret = privkey_from_hex("3333333333333333333333333333333333333333333333333333333333333333"); + x_local_delayed_payment_basepoint_secret = secret_from_hex("3333333333333333333333333333333333333333333333333333333333333333"); SUPERVERBOSE("INTERNAL: local_delayed_payment_basepoint_secret: %s\n", - type_to_string(tmpctx, struct privkey, + type_to_string(tmpctx, struct secret, &x_local_delayed_payment_basepoint_secret)); - x_remote_payment_basepoint_secret = privkey_from_hex("4444444444444444444444444444444444444444444444444444444444444444"); + x_remote_payment_basepoint_secret = secret_from_hex("4444444444444444444444444444444444444444444444444444444444444444"); SUPERVERBOSE("INTERNAL: remote_payment_basepoint_secret: %s\n", - type_to_string(tmpctx, struct privkey, + type_to_string(tmpctx, struct secret, &x_remote_payment_basepoint_secret)); - x_local_per_commitment_secret = privkey_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); + x_local_per_commitment_secret = secret_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); SUPERVERBOSE("x_local_per_commitment_secret: %s\n", - type_to_string(tmpctx, struct privkey, + type_to_string(tmpctx, struct secret, &x_local_per_commitment_secret)); - if (!pubkey_from_privkey(&x_remote_revocation_basepoint_secret, - &x_remote_revocation_basepoint)) - abort(); + if (!pubkey_from_secret(&x_remote_revocation_basepoint_secret, + &x_remote_revocation_basepoint)) + abort(); SUPERVERBOSE("# From remote_revocation_basepoint_secret\n" "INTERNAL: remote_revocation_basepoint: %s\n", type_to_string(tmpctx, struct pubkey, &x_remote_revocation_basepoint)); - if (!pubkey_from_privkey(&x_local_delayed_payment_basepoint_secret, - &x_local_delayed_payment_basepoint)) + if (!pubkey_from_secret(&x_local_delayed_payment_basepoint_secret, + &x_local_delayed_payment_basepoint)) abort(); SUPERVERBOSE("# From local_delayed_payment_basepoint_secret\n" "INTERNAL: local_delayed_payment_basepoint: %s\n", type_to_string(tmpctx, struct pubkey, &x_local_delayed_payment_basepoint)); - if (!pubkey_from_privkey(&x_local_per_commitment_secret, - &x_local_per_commitment_point)) + if (!pubkey_from_secret(&x_local_per_commitment_secret, + &x_local_per_commitment_point)) abort(); SUPERVERBOSE("INTERNAL: local_per_commitment_point: %s\n", type_to_string(tmpctx, struct pubkey, &x_local_per_commitment_point)); - if (!pubkey_from_privkey(&x_local_payment_basepoint_secret, - &local_payment_basepoint)) + if (!pubkey_from_secret(&x_local_payment_basepoint_secret, + &local_payment_basepoint)) abort(); - if (!pubkey_from_privkey(&x_remote_payment_basepoint_secret, - &remote_payment_basepoint)) + if (!pubkey_from_secret(&x_remote_payment_basepoint_secret, + &remote_payment_basepoint)) abort(); if (!derive_simple_privkey(&x_remote_payment_basepoint_secret, diff --git a/lightningd/test/run-cryptomsg.c b/lightningd/test/run-cryptomsg.c index 75759e556..16b04bd4c 100644 --- a/lightningd/test/run-cryptomsg.c +++ b/lightningd/test/run-cryptomsg.c @@ -59,20 +59,20 @@ static struct io_plan *check_msg_read(struct io_conn *conn, struct peer *peer, return NULL; } -static struct sha256 sha256_from_hex(const char *hex) +static struct secret secret_from_hex(const char *hex) { - struct sha256 sha256; + struct secret secret; hex += 2; - if (!hex_decode(hex, strlen(hex), &sha256, sizeof(sha256))) + if (!hex_decode(hex, strlen(hex), &secret, sizeof(secret))) abort(); - return sha256; + return secret; } int main(void) { tal_t *tmpctx = tal_tmpctx(NULL); struct peer_crypto_state cs_out, cs_in; - struct sha256 sk, rk, ck; + struct secret sk, rk, ck; const void *msg = tal_dup_arr(tmpctx, char, "hello", 5, 0); size_t i; @@ -89,9 +89,9 @@ int main(void) * # HKDF(0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,zero) * output: sk,rk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9,0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442 */ - ck = sha256_from_hex("0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01"); - sk = sha256_from_hex("0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9"); - rk = sha256_from_hex("0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442"); + ck = secret_from_hex("0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01"); + sk = secret_from_hex("0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9"); + rk = secret_from_hex("0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442"); cs_out.cs.sn = cs_out.cs.rn = cs_in.cs.sn = cs_in.cs.rn = 0; cs_out.cs.sk = cs_in.cs.rk = sk; diff --git a/lightningd/test/run-key_derive.c b/lightningd/test/run-key_derive.c index e8e3e8252..b4ab327a5 100644 --- a/lightningd/test/run-key_derive.c +++ b/lightningd/test/run-key_derive.c @@ -10,35 +10,40 @@ static void *tmpctx; #include #include -static struct privkey privkey_from_hex(const char *hex) +static struct secret secret_from_hex(const char *hex) { - struct privkey privkey; + struct secret s; hex += 2; - if (!hex_decode(hex, strlen(hex), &privkey, sizeof(privkey))) + if (!hex_decode(hex, strlen(hex), &s, sizeof(s))) abort(); - return privkey; + return s; } int main(void) { - struct privkey base_secret, per_commitment_secret, privkey; + struct privkey privkey; + struct secret base_secret, per_commitment_secret; struct pubkey base_point, per_commitment_point, pubkey, pubkey2; tmpctx = tal_tmpctx(NULL); secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); - base_secret = privkey_from_hex("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); - per_commitment_secret = privkey_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); + base_secret = secret_from_hex("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + per_commitment_secret = secret_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); printf("base_secret: 0x%s\n", tal_hexstr(tmpctx, &base_secret, sizeof(base_secret))); printf("per_commitment_secret: 0x%s\n", tal_hexstr(tmpctx, &per_commitment_secret, sizeof(per_commitment_secret))); - if (!pubkey_from_privkey(&per_commitment_secret, &per_commitment_point)) + if (!secp256k1_ec_pubkey_create(secp256k1_ctx, + &per_commitment_point.pubkey, + per_commitment_secret.data)) abort(); - if (!pubkey_from_privkey(&base_secret, &base_point)) + if (!secp256k1_ec_pubkey_create(secp256k1_ctx, + &base_point.pubkey, + base_secret.data)) abort(); printf("base_point: 0x%s\n", type_to_string(tmpctx, struct pubkey, &base_point)); diff --git a/test/test_sphinx.c b/test/test_sphinx.c index 11fc79c4e..6460d8ebf 100644 --- a/test/test_sphinx.c +++ b/test/test_sphinx.c @@ -14,6 +14,14 @@ secp256k1_context *secp256k1_ctx; +static struct secret secret_from_hex(const char *hex) +{ + struct secret s; + if (!hex_decode(hex, strlen(hex), &s, sizeof(s))) + abort(); + return s; +} + /* Create an onionreply with the test vector parameters and check that * we match the test vectors and that we can also unwrap it. */ static void run_unit_tests(void) @@ -31,12 +39,12 @@ static void run_unit_tests(void) "21e13c2d7cfe7e18836df50872466117a295783ab8aab0e7ecc8c725503ad02d", "b5756b9b542727dbafc6765a49488b023a725d631af688fc031217e90770c328", }; - u8 *ss[] = { - tal_hexdata(tmpctx, secrets[0], 64), - tal_hexdata(tmpctx, secrets[1], 64), - tal_hexdata(tmpctx, secrets[2], 64), - tal_hexdata(tmpctx, secrets[3], 64), - tal_hexdata(tmpctx, secrets[4], 64), + struct secret ss[] = { + secret_from_hex(secrets[0]), + secret_from_hex(secrets[1]), + secret_from_hex(secrets[2]), + secret_from_hex(secrets[3]), + secret_from_hex(secrets[4]) }; int replylen = 164 * 2; @@ -90,10 +98,10 @@ static void run_unit_tests(void) replylen), }; - reply = create_onionreply(tmpctx, ss[4], raw); + reply = create_onionreply(tmpctx, &ss[4], raw); for (int i = 4; i >= 0; i--) { printf("input_packet %s\n", tal_hex(tmpctx, reply)); - reply = wrap_onionreply(tmpctx, ss[i], reply); + reply = wrap_onionreply(tmpctx, &ss[i], reply); printf("obfuscated_packet %s\n", tal_hex(tmpctx, reply)); assert(memcmp(reply, intermediates[i], tal_len(reply)) == 0); } @@ -140,7 +148,7 @@ int main(int argc, char **argv) u8 privkeys[argc - 1][32]; u8 sessionkey[32]; struct hop_data hops_data[num_hops]; - struct sha256 *shared_secrets; + struct secret *shared_secrets; memset(&sessionkey, 'A', sizeof(sessionkey)); diff --git a/type_to_string.h b/type_to_string.h index 0169776d3..d72a71664 100644 --- a/type_to_string.h +++ b/type_to_string.h @@ -21,6 +21,7 @@ union printable_types { const secp256k1_pubkey *secp256k1_pubkey; const struct channel_id *channel_id; const struct short_channel_id *short_channel_id; + const struct secret *secret; const struct privkey *privkey; const secp256k1_ecdsa_signature *secp256k1_ecdsa_signature; const struct channel *channel; diff --git a/wire/fromwire.c b/wire/fromwire.c index 413a8c297..3ffd05d03 100644 --- a/wire/fromwire.c +++ b/wire/fromwire.c @@ -106,9 +106,14 @@ void fromwire_pubkey(const u8 **cursor, size_t *max, struct pubkey *pubkey) fail_pull(cursor, max); } +void fromwire_secret(const u8 **cursor, size_t *max, struct secret *secret) +{ + fromwire(cursor, max, secret->data, sizeof(secret->data)); +} + void fromwire_privkey(const u8 **cursor, size_t *max, struct privkey *privkey) { - fromwire(cursor, max, privkey->secret, sizeof(privkey->secret)); + fromwire_secret(cursor, max, &privkey->secret); } void fromwire_secp256k1_ecdsa_signature(const u8 **cursor, diff --git a/wire/towire.c b/wire/towire.c index d0dfa2cbf..3f53e1f15 100644 --- a/wire/towire.c +++ b/wire/towire.c @@ -58,9 +58,14 @@ void towire_pubkey(u8 **pptr, const struct pubkey *pubkey) towire(pptr, output, outputlen); } +void towire_secret(u8 **pptr, const struct secret *secret) +{ + towire(pptr, secret->data, sizeof(secret->data)); +} + void towire_privkey(u8 **pptr, const struct privkey *privkey) { - towire(pptr, privkey->secret, sizeof(privkey->secret)); + towire_secret(pptr, &privkey->secret); } void towire_secp256k1_ecdsa_signature(u8 **pptr, diff --git a/wire/wire.h b/wire/wire.h index ae93e607a..1aea3e09e 100644 --- a/wire/wire.h +++ b/wire/wire.h @@ -31,6 +31,7 @@ int fromwire_peektype(const u8 *cursor); void towire(u8 **pptr, const void *data, size_t len); void towire_pubkey(u8 **pptr, const struct pubkey *pubkey); void towire_privkey(u8 **pptr, const struct privkey *privkey); +void towire_secret(u8 **pptr, const struct secret *secret); void towire_secp256k1_ecdsa_signature(u8 **pptr, const secp256k1_ecdsa_signature *signature); void towire_channel_id(u8 **pptr, const struct channel_id *channel_id); @@ -55,6 +56,7 @@ u16 fromwire_u16(const u8 **cursor, size_t *max); u32 fromwire_u32(const u8 **cursor, size_t *max); u64 fromwire_u64(const u8 **cursor, size_t *max); bool fromwire_bool(const u8 **cursor, size_t *max); +void fromwire_secret(const u8 **cursor, size_t *max, struct secret *secret); void fromwire_privkey(const u8 **cursor, size_t *max, struct privkey *privkey); void fromwire_pubkey(const u8 **cursor, size_t *max, struct pubkey *pubkey); void fromwire_secp256k1_ecdsa_signature(const u8 **cursor, size_t *max,