Browse Source

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 <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
c51c6f9133
  1. 27
      common/sphinx.c

27
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) 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); 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( static bool compute_hmac(
void *dst, void *dst,
const void *src, const void *src,
@ -392,7 +400,6 @@ struct onionpacket *create_onionpacket(
struct keyset keys; struct keyset keys;
u8 padkey[KEY_LEN]; u8 padkey[KEY_LEN];
u8 nexthmac[HMAC_SIZE]; u8 nexthmac[HMAC_SIZE];
u8 stream[ROUTING_INFO_SIZE];
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);
@ -431,14 +438,14 @@ struct onionpacket *create_onionpacket(
for (i = num_hops - 1; i >= 0; i--) { for (i = num_hops - 1; i >= 0; i--) {
memcpy(sp->hops[i].hmac, nexthmac, HMAC_SIZE); memcpy(sp->hops[i].hmac, nexthmac, HMAC_SIZE);
generate_key_set(&params[i].secret, &keys); generate_key_set(&params[i].secret, &keys);
generate_cipher_stream(stream, keys.rho, ROUTING_INFO_SIZE);
/* Rightshift mix-header by FRAME_SIZE */ /* Rightshift mix-header by FRAME_SIZE */
size_t shiftSize = sphinx_hop_size(&sp->hops[i]); size_t shiftSize = sphinx_hop_size(&sp->hops[i]);
memmove(packet->routinginfo + shiftSize, packet->routinginfo, memmove(packet->routinginfo + shiftSize, packet->routinginfo,
ROUTING_INFO_SIZE-shiftSize); ROUTING_INFO_SIZE-shiftSize);
sphinx_write_frame(packet->routinginfo, &sp->hops[i]); 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) { if (i == num_hops - 1) {
memcpy(packet->routinginfo + ROUTING_INFO_SIZE - fillerSize, filler, fillerSize); memcpy(packet->routinginfo + ROUTING_INFO_SIZE - fillerSize, filler, fillerSize);
@ -478,7 +485,6 @@ struct route_step *process_onionpacket(
u8 hmac[HMAC_SIZE]; u8 hmac[HMAC_SIZE];
struct keyset keys; struct keyset keys;
u8 blind[BLINDING_FACTOR_SIZE]; u8 blind[BLINDING_FACTOR_SIZE];
u8 stream[NUM_STREAM_BYTES];
u8 paddedheader[2*ROUTING_INFO_SIZE]; u8 paddedheader[2*ROUTING_INFO_SIZE];
size_t payload_size; size_t payload_size;
bigsize_t shift_size; bigsize_t shift_size;
@ -497,11 +503,9 @@ struct route_step *process_onionpacket(
} }
//FIXME:store seen secrets to avoid replay attacks //FIXME:store seen secrets to avoid replay attacks
generate_cipher_stream(stream, keys.rho, sizeof(stream));
memset(paddedheader, 0, sizeof(paddedheader)); memset(paddedheader, 0, sizeof(paddedheader));
memcpy(paddedheader, msg->routinginfo, ROUTING_INFO_SIZE); 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); 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))
@ -596,8 +600,6 @@ struct onionreply *wrap_onionreply(const tal_t *ctx,
const struct onionreply *reply) const struct onionreply *reply)
{ {
u8 key[KEY_LEN]; u8 key[KEY_LEN];
size_t streamlen = tal_count(reply->contents);
u8 stream[streamlen];
struct onionreply *result = tal(ctx, struct onionreply); struct onionreply *result = tal(ctx, struct onionreply);
/* BOLT #4: /* 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. * The obfuscation step is repeated by every hop along the return path.
*/ */
generate_key(key, "ammag", 5, shared_secret); generate_key(key, "ammag", 5, shared_secret);
generate_cipher_stream(stream, key, streamlen); result->contents = tal_dup_talarr(result, u8, reply->contents);
result->contents = tal_arr(result, u8, streamlen); xor_cipher_stream(result->contents, key, tal_bytelen(result->contents));
xorbytes(result->contents, stream, reply->contents, streamlen);
return result; return result;
} }

Loading…
Cancel
Save