From c51c6f9133d71cc08ad3da92b321a77ce553b189 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 27 Feb 2020 12:47:21 +1030 Subject: [PATCH] sphinx: use crypto_stream_chacha20_xor to generate stream and xor at once. Slightly more efficient. We still generate an overlong stream in a couple of other places though. Signed-off-by: Rusty Russell --- common/sphinx.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/common/sphinx.c b/common/sphinx.c index 0849c218e..80ab1adae 100644 --- a/common/sphinx.c +++ b/common/sphinx.c @@ -174,11 +174,19 @@ static void xorbytes(uint8_t *d, const uint8_t *a, const uint8_t *b, size_t len) */ static void generate_cipher_stream(void *dst, const u8 *k, size_t dstlen) { - u8 nonce[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + const u8 nonce[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; crypto_stream_chacha20(dst, dstlen, nonce, k); } +/* xor cipher stream into dst */ +static void xor_cipher_stream(void *dst, const u8 *k, size_t dstlen) +{ + const u8 nonce[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + crypto_stream_chacha20_xor(dst, dst, dstlen, nonce, k); +} + static bool compute_hmac( void *dst, const void *src, @@ -392,7 +400,6 @@ struct onionpacket *create_onionpacket( struct keyset keys; u8 padkey[KEY_LEN]; u8 nexthmac[HMAC_SIZE]; - u8 stream[ROUTING_INFO_SIZE]; struct hop_params *params; struct secret *secrets = tal_arr(ctx, struct secret, num_hops); @@ -431,14 +438,14 @@ struct onionpacket *create_onionpacket( for (i = num_hops - 1; i >= 0; i--) { memcpy(sp->hops[i].hmac, nexthmac, HMAC_SIZE); generate_key_set(¶ms[i].secret, &keys); - generate_cipher_stream(stream, keys.rho, ROUTING_INFO_SIZE); /* Rightshift mix-header by FRAME_SIZE */ size_t shiftSize = sphinx_hop_size(&sp->hops[i]); memmove(packet->routinginfo + shiftSize, packet->routinginfo, ROUTING_INFO_SIZE-shiftSize); sphinx_write_frame(packet->routinginfo, &sp->hops[i]); - xorbytes(packet->routinginfo, packet->routinginfo, stream, ROUTING_INFO_SIZE); + xor_cipher_stream(packet->routinginfo, keys.rho, + ROUTING_INFO_SIZE); if (i == num_hops - 1) { memcpy(packet->routinginfo + ROUTING_INFO_SIZE - fillerSize, filler, fillerSize); @@ -478,7 +485,6 @@ struct route_step *process_onionpacket( u8 hmac[HMAC_SIZE]; struct keyset keys; u8 blind[BLINDING_FACTOR_SIZE]; - u8 stream[NUM_STREAM_BYTES]; u8 paddedheader[2*ROUTING_INFO_SIZE]; size_t payload_size; bigsize_t shift_size; @@ -497,11 +503,9 @@ struct route_step *process_onionpacket( } //FIXME:store seen secrets to avoid replay attacks - generate_cipher_stream(stream, keys.rho, sizeof(stream)); - memset(paddedheader, 0, sizeof(paddedheader)); memcpy(paddedheader, msg->routinginfo, ROUTING_INFO_SIZE); - xorbytes(paddedheader, paddedheader, stream, sizeof(stream)); + xor_cipher_stream(paddedheader, keys.rho, sizeof(paddedheader)); compute_blinding_factor(&msg->ephemeralkey, shared_secret, blind); if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind)) @@ -596,8 +600,6 @@ struct onionreply *wrap_onionreply(const tal_t *ctx, const struct onionreply *reply) { u8 key[KEY_LEN]; - size_t streamlen = tal_count(reply->contents); - u8 stream[streamlen]; struct onionreply *result = tal(ctx, struct onionreply); /* BOLT #4: @@ -609,9 +611,8 @@ struct onionreply *wrap_onionreply(const tal_t *ctx, * The obfuscation step is repeated by every hop along the return path. */ generate_key(key, "ammag", 5, shared_secret); - generate_cipher_stream(stream, key, streamlen); - result->contents = tal_arr(result, u8, streamlen); - xorbytes(result->contents, stream, reply->contents, streamlen); + result->contents = tal_dup_talarr(result, u8, reply->contents); + xor_cipher_stream(result->contents, key, tal_bytelen(result->contents)); return result; }