@ -479,16 +479,41 @@ u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret,
u8 key [ KEY_LEN ] ;
u8 hmac [ HMAC_SIZE ] ;
/* BOLT #4:
*
* The node returning the message builds a return packet consisting of
* the following fields :
*
* 1. data :
* * [ ` 32 ` : ` hmac ` ]
* * [ ` 2 ` : ` failure_len ` ]
* * [ ` failure_len ` : ` failuremsg ` ]
* * [ ` 2 ` : ` pad_len ` ]
* * [ ` pad_len ` : ` pad ` ]
*/
towire_u16 ( & payload , msglen ) ;
towire ( & payload , failure_msg , msglen ) ;
towire_u16 ( & payload , padlen ) ;
towire_pad ( & payload , padlen ) ;
/* BOLT #4:
*
* The node SHOULD set ` pad ` such that the ` failure_len ` plus
* ` pad_len ` is equal to 128. This is 28 bytes longer than then the
* longest currently - defined message .
*/
assert ( tal_len ( payload ) = = ONION_REPLY_SIZE + 4 ) ;
/* BOLT #4:
*
* Where ` hmac ` is an HMAC authenticating the remainder of the packet ,
* with a key using the above key generation with key type " _um_ "
*/
generate_key ( key , " um " , 2 , shared_secret - > data ) ;
compute_hmac ( hmac , payload , tal_len ( payload ) , key , KEY_LEN ) ;
towire ( & reply , hmac , sizeof ( hmac ) ) ;
towire ( & reply , payload , tal_len ( payload ) ) ;
tal_free ( payload ) ;
@ -502,6 +527,15 @@ u8 *wrap_onionreply(const tal_t *ctx,
size_t streamlen = tal_len ( reply ) ;
u8 stream [ streamlen ] ;
u8 * result = tal_arr ( ctx , u8 , streamlen ) ;
/* BOLT #4:
*
* The node then generates a new key , using the key type ` ammag ` .
* This key is then used to generate a pseudo - random stream , which is
* then applied to the packet using ` XOR ` .
*
* The obfuscation step is repeated by every node on the return path .
*/
generate_key ( key , " ammag " , 5 , shared_secret - > data ) ;
generate_cipher_stream ( stream , key , streamlen ) ;
xorbytes ( result , stream , reply , streamlen ) ;