mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
common: make sphinx.c use hmac.c.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
b122e44a0b
commit
8c984fbf1d
7 changed files with 61 additions and 73 deletions
|
@ -51,6 +51,7 @@ CHANNELD_COMMON_OBJS := \
|
||||||
common/gen_peer_status_wire.o \
|
common/gen_peer_status_wire.o \
|
||||||
common/gossip_rcvd_filter.o \
|
common/gossip_rcvd_filter.o \
|
||||||
common/gossip_store.o \
|
common/gossip_store.o \
|
||||||
|
common/hmac.o \
|
||||||
common/htlc_state.o \
|
common/htlc_state.o \
|
||||||
common/htlc_trim.o \
|
common/htlc_trim.o \
|
||||||
common/htlc_tx.o \
|
common/htlc_tx.o \
|
||||||
|
|
119
common/sphinx.c
119
common/sphinx.c
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include <secp256k1_ecdh.h>
|
#include <secp256k1_ecdh.h>
|
||||||
|
|
||||||
#include <sodium/crypto_auth_hmacsha256.h>
|
|
||||||
#include <sodium/crypto_stream_chacha20.h>
|
#include <sodium/crypto_stream_chacha20.h>
|
||||||
|
|
||||||
#include <wire/wire.h>
|
#include <wire/wire.h>
|
||||||
|
@ -141,7 +140,7 @@ u8 *serialize_onionpacket(
|
||||||
write_buffer(dst, &m->version, 1, &p);
|
write_buffer(dst, &m->version, 1, &p);
|
||||||
write_buffer(dst, der, sizeof(der), &p);
|
write_buffer(dst, der, sizeof(der), &p);
|
||||||
write_buffer(dst, m->routinginfo, ROUTING_INFO_SIZE, &p);
|
write_buffer(dst, m->routinginfo, ROUTING_INFO_SIZE, &p);
|
||||||
write_buffer(dst, m->mac, sizeof(m->mac), &p);
|
write_buffer(dst, m->hmac.bytes, sizeof(m->hmac.bytes), &p);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +165,7 @@ enum onion_type parse_onionpacket(const u8 *src,
|
||||||
}
|
}
|
||||||
|
|
||||||
fromwire_u8_array(&cursor, &max, dest->routinginfo, ROUTING_INFO_SIZE);
|
fromwire_u8_array(&cursor, &max, dest->routinginfo, ROUTING_INFO_SIZE);
|
||||||
fromwire_u8_array(&cursor, &max, dest->mac, HMAC_SIZE);
|
fromwire_hmac(&cursor, &max, &dest->hmac);
|
||||||
assert(max == 0);
|
assert(max == 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -198,43 +197,29 @@ static void xor_cipher_stream(void *dst, const struct secret *k, size_t dstlen)
|
||||||
crypto_stream_chacha20_xor(dst, dst, dstlen, nonce, k->data);
|
crypto_stream_chacha20_xor(dst, dst, dstlen, nonce, k->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compute_hmac(
|
static void compute_hmac(const u8 *src, size_t slen,
|
||||||
void *dst,
|
const struct secret *key,
|
||||||
const void *src,
|
struct hmac *h)
|
||||||
size_t len,
|
|
||||||
const void *key,
|
|
||||||
size_t keylen)
|
|
||||||
{
|
{
|
||||||
crypto_auth_hmacsha256_state state;
|
hmac(src, slen, key->data, sizeof(key->data), h);
|
||||||
|
|
||||||
crypto_auth_hmacsha256_init(&state, key, keylen);
|
|
||||||
crypto_auth_hmacsha256_update(&state, memcheck(src, len), len);
|
|
||||||
crypto_auth_hmacsha256_final(&state, dst);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compute_packet_hmac(const struct onionpacket *packet,
|
static void compute_packet_hmac(const struct onionpacket *packet,
|
||||||
const u8 *assocdata, const size_t assocdatalen,
|
const u8 *assocdata, const size_t assocdatalen,
|
||||||
const struct secret *mukey, u8 *hmac)
|
const struct secret *mukey,
|
||||||
|
struct hmac *hmac)
|
||||||
{
|
{
|
||||||
u8 mactemp[ROUTING_INFO_SIZE + assocdatalen];
|
u8 mactemp[ROUTING_INFO_SIZE + assocdatalen];
|
||||||
u8 mac[32];
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
write_buffer(mactemp, packet->routinginfo, ROUTING_INFO_SIZE, &pos);
|
write_buffer(mactemp, packet->routinginfo, ROUTING_INFO_SIZE, &pos);
|
||||||
write_buffer(mactemp, assocdata, assocdatalen, &pos);
|
write_buffer(mactemp, assocdata, assocdatalen, &pos);
|
||||||
|
assert(pos == sizeof(mactemp));
|
||||||
|
|
||||||
compute_hmac(mac, mactemp, sizeof(mactemp), mukey->data, sizeof(mukey->data));
|
compute_hmac(mactemp, sizeof(mactemp), mukey, hmac);
|
||||||
memcpy(hmac, mac, HMAC_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool generate_key(struct secret *k, const char *t, u8 tlen,
|
static void generate_header_padding(void *dst, size_t dstlen,
|
||||||
const struct secret *s)
|
|
||||||
{
|
|
||||||
return compute_hmac(k->data, s->data, sizeof(s->data), t, tlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool generate_header_padding(void *dst, size_t dstlen,
|
|
||||||
const struct sphinx_path *path,
|
const struct sphinx_path *path,
|
||||||
struct hop_params *params)
|
struct hop_params *params)
|
||||||
{
|
{
|
||||||
|
@ -244,9 +229,7 @@ static bool generate_header_padding(void *dst, size_t dstlen,
|
||||||
|
|
||||||
memset(dst, 0, dstlen);
|
memset(dst, 0, dstlen);
|
||||||
for (int i = 0; i < tal_count(path->hops) - 1; i++) {
|
for (int i = 0; i < tal_count(path->hops) - 1; i++) {
|
||||||
if (!generate_key(&key, RHO_KEYTYPE, strlen(RHO_KEYTYPE),
|
subkey_from_hmac("rho", ¶ms[i].secret, &key);
|
||||||
¶ms[i].secret))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
generate_cipher_stream(stream, &key, sizeof(stream));
|
generate_cipher_stream(stream, &key, sizeof(stream));
|
||||||
|
|
||||||
|
@ -267,10 +250,9 @@ static bool generate_header_padding(void *dst, size_t dstlen,
|
||||||
xorbytes(dst, dst, stream + fillerStart,
|
xorbytes(dst, dst, stream + fillerStart,
|
||||||
fillerEnd - fillerStart);
|
fillerEnd - fillerStart);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool generate_prefill(void *dst, size_t dstlen,
|
static void generate_prefill(void *dst, size_t dstlen,
|
||||||
const struct sphinx_path *path,
|
const struct sphinx_path *path,
|
||||||
struct hop_params *params)
|
struct hop_params *params)
|
||||||
{
|
{
|
||||||
|
@ -280,9 +262,7 @@ static bool generate_prefill(void *dst, size_t dstlen,
|
||||||
|
|
||||||
memset(dst, 0, dstlen);
|
memset(dst, 0, dstlen);
|
||||||
for (int i = 0; i < tal_count(path->hops); i++) {
|
for (int i = 0; i < tal_count(path->hops); i++) {
|
||||||
if (!generate_key(&key, RHO_KEYTYPE, strlen(RHO_KEYTYPE),
|
subkey_from_hmac("rho", ¶ms[i].secret, &key);
|
||||||
¶ms[i].secret))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
generate_cipher_stream(stream, &key, sizeof(stream));
|
generate_cipher_stream(stream, &key, sizeof(stream));
|
||||||
|
|
||||||
|
@ -297,7 +277,6 @@ static bool generate_prefill(void *dst, size_t dstlen,
|
||||||
* be added by this hop */
|
* be added by this hop */
|
||||||
xorbytes(dst, dst, stream + fillerStart, dstlen);
|
xorbytes(dst, dst, stream + fillerStart, dstlen);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compute_blinding_factor(const struct pubkey *key,
|
static void compute_blinding_factor(const struct pubkey *key,
|
||||||
|
@ -351,10 +330,10 @@ bool onion_shared_secret(
|
||||||
static void generate_key_set(const struct secret *secret,
|
static void generate_key_set(const struct secret *secret,
|
||||||
struct keyset *keys)
|
struct keyset *keys)
|
||||||
{
|
{
|
||||||
generate_key(&keys->rho, "rho", 3, secret);
|
subkey_from_hmac("rho", secret, &keys->rho);
|
||||||
generate_key(&keys->pi, "pi", 2, secret);
|
subkey_from_hmac("pi", secret, &keys->pi);
|
||||||
generate_key(&keys->mu, "mu", 2, secret);
|
subkey_from_hmac("mu", secret, &keys->mu);
|
||||||
generate_key(&keys->gamma, "gamma", 5, secret);
|
subkey_from_hmac("gamma", secret, &keys->gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hop_params *generate_hop_params(
|
static struct hop_params *generate_hop_params(
|
||||||
|
@ -424,14 +403,15 @@ static struct hop_params *generate_hop_params(
|
||||||
static void sphinx_write_frame(u8 *dest, const struct sphinx_hop *hop)
|
static void sphinx_write_frame(u8 *dest, const struct sphinx_hop *hop)
|
||||||
{
|
{
|
||||||
memcpy(dest, hop->raw_payload, tal_bytelen(hop->raw_payload));
|
memcpy(dest, hop->raw_payload, tal_bytelen(hop->raw_payload));
|
||||||
memcpy(dest + tal_bytelen(hop->raw_payload), hop->hmac, HMAC_SIZE);
|
memcpy(dest + tal_bytelen(hop->raw_payload),
|
||||||
|
hop->hmac.bytes, sizeof(hop->hmac.bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sphinx_prefill_stream_xor(u8 *dst, size_t dstlen,
|
static void sphinx_prefill_stream_xor(u8 *dst, size_t dstlen,
|
||||||
const struct secret *shared_secret)
|
const struct secret *shared_secret)
|
||||||
{
|
{
|
||||||
struct secret padkey;
|
struct secret padkey;
|
||||||
generate_key(&padkey, "prefill", 7, shared_secret);
|
subkey_from_hmac("prefill", shared_secret, &padkey);
|
||||||
xor_cipher_stream(dst, &padkey, dstlen);
|
xor_cipher_stream(dst, &padkey, dstlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +453,7 @@ struct onionpacket *create_onionpacket(
|
||||||
u8 filler[fillerSize];
|
u8 filler[fillerSize];
|
||||||
struct keyset keys;
|
struct keyset keys;
|
||||||
struct secret padkey;
|
struct secret padkey;
|
||||||
u8 nexthmac[HMAC_SIZE];
|
struct hmac nexthmac;
|
||||||
struct hop_params *params;
|
struct hop_params *params;
|
||||||
struct secret *secrets = tal_arr(ctx, struct secret, num_hops);
|
struct secret *secrets = tal_arr(ctx, struct secret, num_hops);
|
||||||
size_t payloads_size = sphinx_path_payloads_size(sp);
|
size_t payloads_size = sphinx_path_payloads_size(sp);
|
||||||
|
@ -497,7 +477,7 @@ struct onionpacket *create_onionpacket(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
packet->version = 0;
|
packet->version = 0;
|
||||||
memset(nexthmac, 0, HMAC_SIZE);
|
memset(nexthmac.bytes, 0, sizeof(nexthmac.bytes));
|
||||||
|
|
||||||
/* BOLT-e116441ee836447ac3f24cdca62bac1e0f223d5f #4:
|
/* BOLT-e116441ee836447ac3f24cdca62bac1e0f223d5f #4:
|
||||||
*
|
*
|
||||||
|
@ -506,7 +486,7 @@ struct onionpacket *create_onionpacket(
|
||||||
*/
|
*/
|
||||||
/* Note that this is just hop_payloads: the rest of the packet is
|
/* Note that this is just hop_payloads: the rest of the packet is
|
||||||
* overwritten below or above anyway. */
|
* overwritten below or above anyway. */
|
||||||
generate_key(&padkey, "pad", 3, sp->session_key);
|
subkey_from_hmac("pad", sp->session_key, &padkey);
|
||||||
generate_cipher_stream(packet->routinginfo, &padkey, ROUTING_INFO_SIZE);
|
generate_cipher_stream(packet->routinginfo, &padkey, ROUTING_INFO_SIZE);
|
||||||
|
|
||||||
generate_header_padding(filler, sizeof(filler), sp, params);
|
generate_header_padding(filler, sizeof(filler), sp, params);
|
||||||
|
@ -517,7 +497,7 @@ struct onionpacket *create_onionpacket(
|
||||||
sphinx_prefill(packet->routinginfo, sp, max_prefill, params);
|
sphinx_prefill(packet->routinginfo, sp, max_prefill, params);
|
||||||
|
|
||||||
for (i = num_hops - 1; i >= 0; i--) {
|
for (i = num_hops - 1; i >= 0; i--) {
|
||||||
memcpy(sp->hops[i].hmac, nexthmac, HMAC_SIZE);
|
sp->hops[i].hmac = nexthmac;
|
||||||
generate_key_set(¶ms[i].secret, &keys);
|
generate_key_set(¶ms[i].secret, &keys);
|
||||||
|
|
||||||
/* Rightshift mix-header by FRAME_SIZE */
|
/* Rightshift mix-header by FRAME_SIZE */
|
||||||
|
@ -533,10 +513,10 @@ struct onionpacket *create_onionpacket(
|
||||||
}
|
}
|
||||||
|
|
||||||
compute_packet_hmac(packet, sp->associated_data, tal_bytelen(sp->associated_data), &keys.mu,
|
compute_packet_hmac(packet, sp->associated_data, tal_bytelen(sp->associated_data), &keys.mu,
|
||||||
nexthmac);
|
&nexthmac);
|
||||||
}
|
}
|
||||||
memcpy(packet->mac, nexthmac, sizeof(nexthmac));
|
packet->hmac = nexthmac;
|
||||||
memcpy(&packet->ephemeralkey, ¶ms[0].ephemeralkey, sizeof(secp256k1_pubkey));
|
packet->ephemeralkey = params[0].ephemeralkey;
|
||||||
|
|
||||||
for (i=0; i<num_hops; i++) {
|
for (i=0; i<num_hops; i++) {
|
||||||
secrets[i] = params[i].secret;
|
secrets[i] = params[i].secret;
|
||||||
|
@ -564,7 +544,7 @@ struct route_step *process_onionpacket(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
struct route_step *step = talz(ctx, struct route_step);
|
struct route_step *step = talz(ctx, struct route_step);
|
||||||
u8 hmac[HMAC_SIZE];
|
struct hmac hmac;
|
||||||
struct keyset keys;
|
struct keyset keys;
|
||||||
u8 blind[BLINDING_FACTOR_SIZE];
|
u8 blind[BLINDING_FACTOR_SIZE];
|
||||||
u8 paddedheader[2*ROUTING_INFO_SIZE];
|
u8 paddedheader[2*ROUTING_INFO_SIZE];
|
||||||
|
@ -576,9 +556,9 @@ struct route_step *process_onionpacket(
|
||||||
step->next->version = msg->version;
|
step->next->version = msg->version;
|
||||||
generate_key_set(shared_secret, &keys);
|
generate_key_set(shared_secret, &keys);
|
||||||
|
|
||||||
compute_packet_hmac(msg, assocdata, assocdatalen, &keys.mu, hmac);
|
compute_packet_hmac(msg, assocdata, assocdatalen, &keys.mu, &hmac);
|
||||||
|
|
||||||
if (memcmp(msg->mac, hmac, sizeof(hmac)) != 0
|
if (!hmac_eq(&msg->hmac, &hmac)
|
||||||
|| IFDEV(dev_fail_process_onionpacket, false)) {
|
|| IFDEV(dev_fail_process_onionpacket, false)) {
|
||||||
/* Computed MAC does not match expected MAC, the message was modified. */
|
/* Computed MAC does not match expected MAC, the message was modified. */
|
||||||
return tal_free(step);
|
return tal_free(step);
|
||||||
|
@ -599,12 +579,13 @@ struct route_step *process_onionpacket(
|
||||||
/* Can't decode? Treat it as terminal. */
|
/* Can't decode? Treat it as terminal. */
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
shift_size = payload_size;
|
shift_size = payload_size;
|
||||||
memset(step->next->mac, 0, sizeof(step->next->mac));
|
memset(step->next->hmac.bytes, 0, sizeof(step->next->hmac.bytes));
|
||||||
} else {
|
} else {
|
||||||
assert(payload_size <= ROUTING_INFO_SIZE - HMAC_SIZE);
|
assert(payload_size <= ROUTING_INFO_SIZE - HMAC_SIZE);
|
||||||
/* Copy hmac */
|
/* Copy hmac */
|
||||||
shift_size = payload_size + HMAC_SIZE;
|
shift_size = payload_size + HMAC_SIZE;
|
||||||
memcpy(step->next->mac, paddedheader + payload_size, HMAC_SIZE);
|
memcpy(step->next->hmac.bytes,
|
||||||
|
paddedheader + payload_size, HMAC_SIZE);
|
||||||
}
|
}
|
||||||
step->raw_payload = tal_dup_arr(step, u8, paddedheader, payload_size, 0);
|
step->raw_payload = tal_dup_arr(step, u8, paddedheader, payload_size, 0);
|
||||||
|
|
||||||
|
@ -612,7 +593,7 @@ struct route_step *process_onionpacket(
|
||||||
memcpy(&step->next->routinginfo, paddedheader + shift_size,
|
memcpy(&step->next->routinginfo, paddedheader + shift_size,
|
||||||
ROUTING_INFO_SIZE);
|
ROUTING_INFO_SIZE);
|
||||||
|
|
||||||
if (memeqzero(step->next->mac, sizeof(step->next->mac))) {
|
if (memeqzero(step->next->hmac.bytes, sizeof(step->next->hmac.bytes))) {
|
||||||
step->nextcase = ONION_END;
|
step->nextcase = ONION_END;
|
||||||
} else {
|
} else {
|
||||||
step->nextcase = ONION_FORWARD;
|
step->nextcase = ONION_FORWARD;
|
||||||
|
@ -630,7 +611,7 @@ struct onionreply *create_onionreply(const tal_t *ctx,
|
||||||
struct onionreply *reply = tal(ctx, struct onionreply);
|
struct onionreply *reply = tal(ctx, struct onionreply);
|
||||||
u8 *payload = tal_arr(ctx, u8, 0);
|
u8 *payload = tal_arr(ctx, u8, 0);
|
||||||
struct secret key;
|
struct secret key;
|
||||||
u8 hmac[HMAC_SIZE];
|
struct hmac hmac;
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
|
@ -665,11 +646,11 @@ struct onionreply *create_onionreply(const tal_t *ctx,
|
||||||
* Where `hmac` is an HMAC authenticating the remainder of the packet,
|
* Where `hmac` is an HMAC authenticating the remainder of the packet,
|
||||||
* with a key generated using the above process, with key type `um`
|
* with a key generated using the above process, with key type `um`
|
||||||
*/
|
*/
|
||||||
generate_key(&key, "um", 2, shared_secret);
|
subkey_from_hmac("um", shared_secret, &key);
|
||||||
|
|
||||||
compute_hmac(hmac, payload, tal_count(payload), key.data, sizeof(key.data));
|
compute_hmac(payload, tal_count(payload), &key, &hmac);
|
||||||
reply->contents = tal_arr(reply, u8, 0),
|
reply->contents = tal_arr(reply, u8, 0),
|
||||||
towire(&reply->contents, hmac, sizeof(hmac));
|
towire_hmac(&reply->contents, &hmac);
|
||||||
|
|
||||||
towire(&reply->contents, payload, tal_count(payload));
|
towire(&reply->contents, payload, tal_count(payload));
|
||||||
tal_free(payload);
|
tal_free(payload);
|
||||||
|
@ -692,7 +673,7 @@ struct onionreply *wrap_onionreply(const tal_t *ctx,
|
||||||
*
|
*
|
||||||
* The obfuscation step is repeated by every hop along the return path.
|
* The obfuscation step is repeated by every hop along the return path.
|
||||||
*/
|
*/
|
||||||
generate_key(&key, "ammag", 5, shared_secret);
|
subkey_from_hmac("ammag", shared_secret, &key);
|
||||||
result->contents = tal_dup_talarr(result, u8, reply->contents);
|
result->contents = tal_dup_talarr(result, u8, reply->contents);
|
||||||
xor_cipher_stream(result->contents, &key, tal_bytelen(result->contents));
|
xor_cipher_stream(result->contents, &key, tal_bytelen(result->contents));
|
||||||
return result;
|
return result;
|
||||||
|
@ -706,7 +687,7 @@ u8 *unwrap_onionreply(const tal_t *ctx,
|
||||||
{
|
{
|
||||||
struct onionreply *r;
|
struct onionreply *r;
|
||||||
struct secret key;
|
struct secret key;
|
||||||
u8 hmac[HMAC_SIZE];
|
struct hmac hmac;
|
||||||
const u8 *cursor;
|
const u8 *cursor;
|
||||||
u8 *final;
|
u8 *final;
|
||||||
size_t max;
|
size_t max;
|
||||||
|
@ -726,11 +707,11 @@ u8 *unwrap_onionreply(const tal_t *ctx,
|
||||||
|
|
||||||
/* Check if the HMAC matches, this means that this is
|
/* Check if the HMAC matches, this means that this is
|
||||||
* the origin */
|
* the origin */
|
||||||
generate_key(&key, "um", 2, &shared_secrets[i]);
|
subkey_from_hmac("um", &shared_secrets[i], &key);
|
||||||
compute_hmac(hmac, r->contents + sizeof(hmac),
|
compute_hmac(r->contents + sizeof(hmac.bytes),
|
||||||
tal_count(r->contents) - sizeof(hmac),
|
tal_count(r->contents) - sizeof(hmac.bytes),
|
||||||
key.data, sizeof(key.data));
|
&key, &hmac);
|
||||||
if (memcmp(hmac, r->contents, sizeof(hmac)) == 0) {
|
if (memcmp(hmac.bytes, r->contents, sizeof(hmac.bytes)) == 0) {
|
||||||
*origin_index = i;
|
*origin_index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -763,7 +744,7 @@ struct onionpacket *sphinx_decompress(const tal_t *ctx,
|
||||||
|
|
||||||
res->version = src->version;
|
res->version = src->version;
|
||||||
res->ephemeralkey = src->ephemeralkey;
|
res->ephemeralkey = src->ephemeralkey;
|
||||||
memcpy(res->mac, src->mac, HMAC_SIZE);
|
res->hmac = src->hmac;
|
||||||
|
|
||||||
/* Decompress routinginfo by copying the unmodified prefix, setting
|
/* Decompress routinginfo by copying the unmodified prefix, setting
|
||||||
* the compressed suffix to 0x00 bytes and then xoring the obfuscation
|
* the compressed suffix to 0x00 bytes and then xoring the obfuscation
|
||||||
|
@ -790,7 +771,7 @@ sphinx_compress(const tal_t *ctx, const struct onionpacket *packet,
|
||||||
res = tal(ctx, struct sphinx_compressed_onion);
|
res = tal(ctx, struct sphinx_compressed_onion);
|
||||||
res->version = packet->version;
|
res->version = packet->version;
|
||||||
res->ephemeralkey = packet->ephemeralkey;
|
res->ephemeralkey = packet->ephemeralkey;
|
||||||
memcpy(res->mac, packet->mac, HMAC_SIZE);
|
res->hmac = packet->hmac;
|
||||||
|
|
||||||
res->routinginfo = tal_arr(res, u8, payloads_size);
|
res->routinginfo = tal_arr(res, u8, payloads_size);
|
||||||
memcpy(res->routinginfo, packet->routinginfo, payloads_size);
|
memcpy(res->routinginfo, packet->routinginfo, payloads_size);
|
||||||
|
@ -811,7 +792,7 @@ u8 *sphinx_compressed_onion_serialize(const tal_t *ctx, const struct sphinx_comp
|
||||||
write_buffer(dst, &onion->version, VERSION_SIZE, &p);
|
write_buffer(dst, &onion->version, VERSION_SIZE, &p);
|
||||||
write_buffer(dst, der, PUBKEY_SIZE, &p);
|
write_buffer(dst, der, PUBKEY_SIZE, &p);
|
||||||
write_buffer(dst, onion->routinginfo, routelen, &p);
|
write_buffer(dst, onion->routinginfo, routelen, &p);
|
||||||
write_buffer(dst, onion->mac, HMAC_SIZE, &p);
|
write_buffer(dst, onion->hmac.bytes, sizeof(onion->hmac.bytes), &p);
|
||||||
|
|
||||||
assert(p == len);
|
assert(p == len);
|
||||||
return dst;
|
return dst;
|
||||||
|
@ -835,7 +816,7 @@ sphinx_compressed_onion_deserialize(const tal_t *ctx, const u8 *src)
|
||||||
|
|
||||||
fromwire_pubkey(&cursor, &max, &dst->ephemeralkey);
|
fromwire_pubkey(&cursor, &max, &dst->ephemeralkey);
|
||||||
dst->routinginfo = fromwire_tal_arrn(dst, &cursor, &max, max - HMAC_SIZE);
|
dst->routinginfo = fromwire_tal_arrn(dst, &cursor, &max, max - HMAC_SIZE);
|
||||||
fromwire_u8_array(&cursor, &max, dst->mac, HMAC_SIZE);
|
fromwire_hmac(&cursor, &max, &dst->hmac);
|
||||||
|
|
||||||
/* If at any point we failed to pull from the serialized compressed
|
/* If at any point we failed to pull from the serialized compressed
|
||||||
* onion the entire deserialization is considered to have failed. */
|
* onion the entire deserialization is considered to have failed. */
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <ccan/short_types/short_types.h>
|
#include <ccan/short_types/short_types.h>
|
||||||
#include <ccan/tal/tal.h>
|
#include <ccan/tal/tal.h>
|
||||||
|
#include <common/hmac.h>
|
||||||
#include <secp256k1.h>
|
#include <secp256k1.h>
|
||||||
#include <sodium/randombytes.h>
|
#include <sodium/randombytes.h>
|
||||||
#include <wire/gen_onion_wire.h>
|
#include <wire/gen_onion_wire.h>
|
||||||
|
@ -22,7 +23,7 @@
|
||||||
struct onionpacket {
|
struct onionpacket {
|
||||||
/* Cleartext information */
|
/* Cleartext information */
|
||||||
u8 version;
|
u8 version;
|
||||||
u8 mac[HMAC_SIZE];
|
struct hmac hmac;
|
||||||
struct pubkey ephemeralkey;
|
struct pubkey ephemeralkey;
|
||||||
|
|
||||||
/* Encrypted information */
|
/* Encrypted information */
|
||||||
|
@ -33,7 +34,7 @@ struct sphinx_compressed_onion {
|
||||||
u8 version;
|
u8 version;
|
||||||
struct pubkey ephemeralkey;
|
struct pubkey ephemeralkey;
|
||||||
u8 *routinginfo;
|
u8 *routinginfo;
|
||||||
u8 mac[HMAC_SIZE];
|
struct hmac hmac;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ struct hop_data_legacy {
|
||||||
struct sphinx_hop {
|
struct sphinx_hop {
|
||||||
struct pubkey pubkey;
|
struct pubkey pubkey;
|
||||||
const u8 *raw_payload;
|
const u8 *raw_payload;
|
||||||
u8 hmac[HMAC_SIZE];
|
struct hmac hmac;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct route_step {
|
struct route_step {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "../hmac.c"
|
||||||
#include "../onion.c"
|
#include "../onion.c"
|
||||||
#include "../onionreply.c"
|
#include "../onionreply.c"
|
||||||
#include "../sphinx.c"
|
#include "../sphinx.c"
|
||||||
|
|
|
@ -19,6 +19,7 @@ DEVTOOLS_COMMON_OBJS := \
|
||||||
common/fee_states.o \
|
common/fee_states.o \
|
||||||
common/gossip_rcvd_filter.o \
|
common/gossip_rcvd_filter.o \
|
||||||
common/hash_u5.o \
|
common/hash_u5.o \
|
||||||
|
common/hmac.o \
|
||||||
common/htlc_state.o \
|
common/htlc_state.o \
|
||||||
common/memleak.o \
|
common/memleak.o \
|
||||||
common/node_id.o \
|
common/node_id.o \
|
||||||
|
|
|
@ -287,7 +287,9 @@ static void runtest(const char *filename)
|
||||||
printf(" Type: %d\n", type);
|
printf(" Type: %d\n", type);
|
||||||
printf(" Payload: %s\n", tal_hex(ctx, step->raw_payload));
|
printf(" Payload: %s\n", tal_hex(ctx, step->raw_payload));
|
||||||
printf(" Next onion: %s\n", tal_hex(ctx, serialized));
|
printf(" Next onion: %s\n", tal_hex(ctx, serialized));
|
||||||
printf(" Next HMAC: %s\n", tal_hexstr(ctx, step->next->mac, HMAC_SIZE));
|
printf(" Next HMAC: %s\n",
|
||||||
|
tal_hexstr(ctx, step->next->hmac.bytes,
|
||||||
|
crypto_auth_hmacsha256_BYTES));
|
||||||
}
|
}
|
||||||
|
|
||||||
tal_free(ctx);
|
tal_free(ctx);
|
||||||
|
|
|
@ -35,6 +35,7 @@ LIGHTNINGD_COMMON_OBJS := \
|
||||||
common/gen_status_wire.o \
|
common/gen_status_wire.o \
|
||||||
common/gossip_rcvd_filter.o \
|
common/gossip_rcvd_filter.o \
|
||||||
common/hash_u5.o \
|
common/hash_u5.o \
|
||||||
|
common/hmac.o \
|
||||||
common/htlc_state.o \
|
common/htlc_state.o \
|
||||||
common/htlc_trim.o \
|
common/htlc_trim.o \
|
||||||
common/htlc_wire.o \
|
common/htlc_wire.o \
|
||||||
|
|
Loading…
Add table
Reference in a new issue