Browse Source

daemon/sphinx: split handling.

We want to use HSM to do the ECDH part, so split that out.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
8146b838e8
  1. 13
      daemon/peer.c
  2. 20
      daemon/sphinx.c
  3. 16
      daemon/sphinx.h
  4. 6
      test/test_sphinx.c

13
daemon/peer.c

@ -911,11 +911,18 @@ static void their_htlc_added(struct peer *peer, struct htlc *htlc,
//FIXME: dirty trick to retrieve unexported state //FIXME: dirty trick to retrieve unexported state
memcpy(&pk, peer->dstate->secret, sizeof(pk)); memcpy(&pk, peer->dstate->secret, sizeof(pk));
packet = parse_onionpacket(peer, packet = parse_onionpacket(peer,
htlc->routing, tal_count(htlc->routing)); htlc->routing, tal_count(htlc->routing));
if (packet) if (packet) {
step = process_onionpacket(packet, packet, &pk, htlc->rhash.u.u8, u8 shared_secret[32];
sizeof(htlc->rhash));
if (onion_shared_secret(shared_secret, packet, &pk))
step = process_onionpacket(packet, packet,
shared_secret,
htlc->rhash.u.u8,
sizeof(htlc->rhash));
}
if (!step) { if (!step) {
log_unusual(peer->log, "Bad onion, failing HTLC %"PRIu64, log_unusual(peer->log, "Bad onion, failing HTLC %"PRIu64,

20
daemon/sphinx.c

@ -247,6 +247,15 @@ static bool create_shared_secret(
return true; return true;
} }
bool onion_shared_secret(
u8 *secret,
const struct onionpacket *packet,
const struct privkey *privkey)
{
return create_shared_secret(secret, &packet->ephemeralkey,
privkey->secret);
}
void pubkey_hash160( void pubkey_hash160(
u8 *dst, u8 *dst,
const struct pubkey *pubkey) const struct pubkey *pubkey)
@ -267,7 +276,8 @@ void pubkey_hash160(
memcpy(dst, r.u.u8, sizeof(r)); memcpy(dst, r.u.u8, sizeof(r));
} }
static void generate_key_set(u8 secret[SHARED_SECRET_SIZE], struct keyset *keys) static void generate_key_set(const u8 secret[SHARED_SECRET_SIZE],
struct keyset *keys)
{ {
generate_key(keys->rho, "rho", 3, secret); generate_key(keys->rho, "rho", 3, secret);
generate_key(keys->pi, "pi", 2, secret); generate_key(keys->pi, "pi", 2, secret);
@ -417,13 +427,12 @@ struct onionpacket *create_onionpacket(
struct route_step *process_onionpacket( struct route_step *process_onionpacket(
const tal_t *ctx, const tal_t *ctx,
const struct onionpacket *msg, const struct onionpacket *msg,
struct privkey *hop_privkey, const u8 *shared_secret,
const u8 *assocdata, const u8 *assocdata,
const size_t assocdatalen const size_t assocdatalen
) )
{ {
struct route_step *step = talz(ctx, struct route_step); struct route_step *step = talz(ctx, struct route_step);
u8 secret[SHARED_SECRET_SIZE];
u8 hmac[20]; u8 hmac[20];
struct keyset keys; struct keyset keys;
u8 paddedhoppayloads[TOTAL_HOP_PAYLOAD_SIZE + HOP_PAYLOAD_SIZE]; u8 paddedhoppayloads[TOTAL_HOP_PAYLOAD_SIZE + HOP_PAYLOAD_SIZE];
@ -434,8 +443,7 @@ struct route_step *process_onionpacket(
step->next = talz(step, struct onionpacket); step->next = talz(step, struct onionpacket);
step->next->version = msg->version; step->next->version = msg->version;
create_shared_secret(secret, &msg->ephemeralkey, hop_privkey->secret); generate_key_set(shared_secret, &keys);
generate_key_set(secret, &keys);
compute_packet_hmac(msg, assocdata, assocdatalen, keys.mu, hmac); compute_packet_hmac(msg, assocdata, assocdatalen, keys.mu, hmac);
@ -461,7 +469,7 @@ struct route_step *process_onionpacket(
memcpy(&step->next->hoppayloads, paddedhoppayloads + HOP_PAYLOAD_SIZE, memcpy(&step->next->hoppayloads, paddedhoppayloads + HOP_PAYLOAD_SIZE,
TOTAL_HOP_PAYLOAD_SIZE); TOTAL_HOP_PAYLOAD_SIZE);
compute_blinding_factor(&msg->ephemeralkey, secret, blind); compute_blinding_factor(&msg->ephemeralkey, shared_secret, blind);
if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind)) if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind))
return tal_free(step); return tal_free(step);
memcpy(&step->next->nexthop, paddedheader, SECURITY_PARAMETER); memcpy(&step->next->nexthop, paddedheader, SECURITY_PARAMETER);

16
daemon/sphinx.h

@ -69,13 +69,25 @@ struct onionpacket *create_onionpacket(
const size_t assocdatalen const size_t assocdatalen
); );
/**
* onion_shared_secret - calculate ECDH shared secret between nodes.
*
* @secret: the shared secret (32 bytes long)
* @pubkey: the public key of the other node
* @privkey: the private key of this node (32 bytes long)
*/
bool onion_shared_secret(
u8 *secret,
const struct onionpacket *packet,
const struct privkey *privkey);
/** /**
* process_onionpacket - process an incoming packet by stripping one * process_onionpacket - process an incoming packet by stripping one
* onion layer and return the packet for the next hop. * onion layer and return the packet for the next hop.
* *
* @ctx: tal context to allocate from * @ctx: tal context to allocate from
* @packet: incoming packet being processed * @packet: incoming packet being processed
* @hop_privkey: the processing node's private key to decrypt the packet * @shared_secret: the result of onion_shared_secret.
* @hoppayload: the per-hop payload destined for the processing node. * @hoppayload: the per-hop payload destined for the processing node.
* @assocdata: associated data to commit to in HMACs * @assocdata: associated data to commit to in HMACs
* @assocdatalen: length of the assocdata * @assocdatalen: length of the assocdata
@ -83,7 +95,7 @@ struct onionpacket *create_onionpacket(
struct route_step *process_onionpacket( struct route_step *process_onionpacket(
const tal_t * ctx, const tal_t * ctx,
const struct onionpacket *packet, const struct onionpacket *packet,
struct privkey *hop_privkey, const u8 *shared_secret,
const u8 *assocdata, const u8 *assocdata,
const size_t assocdatalen const size_t assocdatalen
); );

6
test/test_sphinx.c

@ -78,6 +78,7 @@ int main(int argc, char **argv)
u8 serialized[TOTAL_PACKET_SIZE]; u8 serialized[TOTAL_PACKET_SIZE];
char hextemp[2 * sizeof(serialized) + 1]; char hextemp[2 * sizeof(serialized) + 1];
memset(hextemp, 0, sizeof(hextemp)); memset(hextemp, 0, sizeof(hextemp));
u8 shared_secret[32];
if (argc != 2) if (argc != 2)
opt_usage_exit_fail("Expect a privkey with --decode"); opt_usage_exit_fail("Expect a privkey with --decode");
@ -91,7 +92,10 @@ int main(int argc, char **argv)
if (!msg) if (!msg)
errx(1, "Error parsing message."); errx(1, "Error parsing message.");
step = process_onionpacket(ctx, msg, &seckey, assocdata, if (!onion_shared_secret(shared_secret, msg, &seckey))
errx(1, "Error creating shared secret.");
step = process_onionpacket(ctx, msg, shared_secret, assocdata,
sizeof(assocdata)); sizeof(assocdata));
if (!step->next) if (!step->next)

Loading…
Cancel
Save