* Given an onionpacket msg extract the information for the current * node and unwrap the remainder so that the node can forward it. */
| 644 | * node and unwrap the remainder so that the node can forward it. |
| 645 | */ |
| 646 | struct route_step *process_onionpacket( |
| 647 | const tal_t *ctx, |
| 648 | const struct onionpacket *msg, |
| 649 | const struct secret *shared_secret, |
| 650 | const u8 *assocdata, |
| 651 | const size_t assocdatalen |
| 652 | ) |
| 653 | { |
| 654 | struct route_step *step = talz(ctx, struct route_step); |
| 655 | struct hmac hmac; |
| 656 | struct secret mu, rho; |
| 657 | u8 blind[BLINDING_FACTOR_SIZE]; |
| 658 | u8 *paddedheader; |
| 659 | size_t payload_size; |
| 660 | bigsize_t shift_size; |
| 661 | const u8 *cursor; |
| 662 | size_t max; |
| 663 | |
| 664 | step->next = talz(step, struct onionpacket); |
| 665 | step->next->version = msg->version; |
| 666 | |
| 667 | /* BOLT #4: |
| 668 | * - Derive `mu` as $`HMAC256(\text{"mu"}, ss)`$ |
| 669 | * (see [Key Generation](#key-generation)). |
| 670 | * - Derive the HMAC as $`HMAC256(mu, hop\_payloads || associated\_data)`$. |
| 671 | */ |
| 672 | subkey_from_hmac("mu", shared_secret, &mu); |
| 673 | compute_packet_hmac(msg, assocdata, assocdatalen, &mu, &hmac); |
| 674 | |
| 675 | if (!hmac_eq(&msg->hmac, &hmac) || dev_fail_process_onionpacket) { |
| 676 | /* Computed MAC does not match expected MAC, the message was modified. */ |
| 677 | return tal_free(step); |
| 678 | } |
| 679 | |
| 680 | /* BOLT #4: |
| 681 | * - Derive `rho` as $`HMAC256(\text{"rho"}, ss)`$ |
| 682 | * (see [Key Generation](#key-generation)). |
| 683 | * - Derive `bytestream` of twice the length of `hop_payloads` using `rho` |
| 684 | * (see [Pseudo Random Byte Stream](pseudo-random-byte-stream)). |
| 685 | * - Set `unwrapped_payloads` to the XOR of `hop_payloads` and `bytestream`. |
| 686 | */ |
| 687 | subkey_from_hmac("rho", shared_secret, &rho); |
| 688 | |
| 689 | //FIXME:store seen secrets to avoid replay attacks |
| 690 | paddedheader = tal_arrz(step, u8, tal_bytelen(msg->routinginfo)*2); |
| 691 | memcpy(paddedheader, msg->routinginfo, tal_bytelen(msg->routinginfo)); |
| 692 | xor_cipher_stream(paddedheader, &rho, tal_bytelen(paddedheader)); |
| 693 | |
| 694 | compute_blinding_factor(&msg->ephemeralkey, shared_secret, blind); |
| 695 | if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind)) |
| 696 | return tal_free(step); |
| 697 | |
| 698 | /* Now, try to pull data out. */ |
| 699 | cursor = paddedheader; |
| 700 | max = tal_bytelen(msg->routinginfo); |
| 701 | |
| 702 | /* Any of these could fail, falling thru with cursor == NULL */ |
| 703 | payload_size = fromwire_bigsize(&cursor, &max); |