mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
sphinx: Variable left-shift when unwrapping onion
This is all it takes on the read side to use multiple frames. We are overshooting the padding a bit since we can at most use 16 additional frames, but ChaCha20 is cheap. Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
7bc4cf83b1
commit
d607afd195
2 changed files with 63 additions and 8 deletions
|
@ -436,8 +436,6 @@ static void deserialize_hop_data(struct hop_data *data, const u8 *src)
|
|||
fromwire_short_channel_id(&cursor, &max, &data->channel_id);
|
||||
data->amt_forward = fromwire_amount_msat(&cursor, &max);
|
||||
data->outgoing_cltv = fromwire_u32(&cursor, &max);
|
||||
fromwire_pad(&cursor, &max, 12);
|
||||
fromwire(&cursor, &max, &data->hmac, HMAC_SIZE);
|
||||
}
|
||||
|
||||
static void sphinx_write_frame(u8 *dest, const struct sphinx_hop *hop)
|
||||
|
@ -457,6 +455,35 @@ static void sphinx_write_frame(u8 *dest, const struct sphinx_hop *hop)
|
|||
memcpy(dest + hop_size - HMAC_SIZE, hop->hmac, HMAC_SIZE);
|
||||
}
|
||||
|
||||
static void sphinx_parse_payload(struct route_step *step, const u8 *src)
|
||||
{
|
||||
size_t hop_size, raw_size, vsize;
|
||||
|
||||
/* Legacy hop_data support */
|
||||
if (src[0] == 0x00) {
|
||||
vsize = 1;
|
||||
raw_size = 32;
|
||||
hop_size = FRAME_SIZE;
|
||||
step->realm = src[0];
|
||||
} else {
|
||||
vsize = varint_get(src, 3, &raw_size);
|
||||
hop_size = raw_size + vsize + HMAC_SIZE;
|
||||
}
|
||||
|
||||
/* Copy common pieces over */
|
||||
step->raw_payload = tal_dup_arr(step, u8, src + vsize, raw_size, 0);
|
||||
memcpy(step->next->mac, src + hop_size - HMAC_SIZE, HMAC_SIZE);
|
||||
|
||||
/* And now try to parse whatever the payload contains so we can use it
|
||||
* later. */
|
||||
if (step->realm == SPHINX_V0_PAYLOAD) {
|
||||
step->type = SPHINX_V0_PAYLOAD;
|
||||
deserialize_hop_data(&step->payload.v0, src);
|
||||
} else {
|
||||
step->type = SPHINX_RAW_PAYLOAD;
|
||||
}
|
||||
}
|
||||
|
||||
struct onionpacket *create_onionpacket(
|
||||
const tal_t *ctx,
|
||||
struct sphinx_path *sp,
|
||||
|
@ -539,7 +566,8 @@ struct route_step *process_onionpacket(
|
|||
struct keyset keys;
|
||||
u8 blind[BLINDING_FACTOR_SIZE];
|
||||
u8 stream[NUM_STREAM_BYTES];
|
||||
u8 paddedheader[ROUTING_INFO_SIZE + FRAME_SIZE];
|
||||
u8 paddedheader[2*ROUTING_INFO_SIZE];
|
||||
size_t shift_size, vsize;
|
||||
|
||||
step->next = talz(step, struct onionpacket);
|
||||
step->next->version = msg->version;
|
||||
|
@ -564,12 +592,30 @@ struct route_step *process_onionpacket(
|
|||
return tal_free(step);
|
||||
|
||||
deserialize_hop_data(&step->hop_data, paddedheader);
|
||||
sphinx_parse_payload(step, paddedheader);
|
||||
|
||||
/* Extract how many bytes we need to shift away */
|
||||
if (paddedheader[0] == 0x00) {
|
||||
shift_size = FRAME_SIZE;
|
||||
} else {
|
||||
/* In addition to the raw payload we need to also shift the
|
||||
* length encoding itself and the HMAC away. */
|
||||
vsize = varint_get(paddedheader, 3, &shift_size);
|
||||
shift_size += vsize + HMAC_SIZE;
|
||||
|
||||
/* If we get an unreasonable shift size we must return an error. */
|
||||
if (shift_size >= ROUTING_INFO_SIZE)
|
||||
return tal_free(step);
|
||||
}
|
||||
|
||||
memcpy(&step->next->mac, step->hop_data.hmac, HMAC_SIZE);
|
||||
step->raw_payload = tal_dup_arr(step, u8, paddedheader + 1,
|
||||
FRAME_SIZE - 1 - HMAC_SIZE, 0);
|
||||
shift_size - 1 - HMAC_SIZE, 0);
|
||||
|
||||
memcpy(&step->next->routinginfo, paddedheader + FRAME_SIZE, ROUTING_INFO_SIZE);
|
||||
/* Copy the hmac from the last HMAC_SIZE bytes */
|
||||
memcpy(&step->next->mac, paddedheader + shift_size - HMAC_SIZE, HMAC_SIZE);
|
||||
|
||||
/* Left shift the current payload out and make the remainder the new onion */
|
||||
memcpy(&step->next->routinginfo, paddedheader + shift_size, ROUTING_INFO_SIZE);
|
||||
|
||||
if (memeqzero(step->next->mac, sizeof(step->next->mac))) {
|
||||
step->nextcase = ONION_END;
|
||||
|
|
|
@ -83,15 +83,24 @@ struct hop_data {
|
|||
struct short_channel_id channel_id;
|
||||
struct amount_msat amt_forward;
|
||||
u32 outgoing_cltv;
|
||||
/* Padding omitted, will be zeroed */
|
||||
u8 hmac[HMAC_SIZE];
|
||||
};
|
||||
|
||||
enum sphinx_payload_type {
|
||||
SPHINX_V0_PAYLOAD = 0,
|
||||
SPHINX_RAW_PAYLOAD = 255,
|
||||
};
|
||||
|
||||
struct route_step {
|
||||
enum route_next_case nextcase;
|
||||
struct onionpacket *next;
|
||||
struct hop_data hop_data;
|
||||
u8 realm;
|
||||
enum sphinx_payload_type type;
|
||||
union {
|
||||
struct hop_data v0;
|
||||
} payload;
|
||||
u8 *raw_payload;
|
||||
u8 payload_frames;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue