| 680 | } |
| 681 | |
| 682 | struct onionreply *create_onionreply(const tal_t *ctx, |
| 683 | const struct secret *shared_secret, |
| 684 | const u8 *failure_msg) |
| 685 | { |
| 686 | size_t msglen = tal_count(failure_msg); |
| 687 | size_t padlen = ONION_REPLY_SIZE - msglen; |
| 688 | struct onionreply *reply = tal(ctx, struct onionreply); |
| 689 | u8 *payload = tal_arr(ctx, u8, 0); |
| 690 | struct secret key; |
| 691 | struct hmac hmac; |
| 692 | |
| 693 | /* BOLT #4: |
| 694 | * |
| 695 | * The node generating the error message (_erring node_) builds a return |
| 696 | * packet consisting of |
| 697 | * the following fields: |
| 698 | * |
| 699 | * 1. data: |
| 700 | * * [`32*byte`:`hmac`] |
| 701 | * * [`u16`:`failure_len`] |
| 702 | * * [`failure_len*byte`:`failuremsg`] |
| 703 | * * [`u16`:`pad_len`] |
| 704 | * * [`pad_len*byte`:`pad`] |
| 705 | */ |
| 706 | towire_u16(&payload, msglen); |
| 707 | towire(&payload, failure_msg, msglen); |
| 708 | towire_u16(&payload, padlen); |
| 709 | towire_pad(&payload, padlen); |
| 710 | |
| 711 | /* BOLT #4: |
| 712 | * |
| 713 | * The _erring node_: |
| 714 | * - SHOULD set `pad` such that the `failure_len` plus `pad_len` is |
| 715 | * equal to 256. |
| 716 | * - Note: this value is 118 bytes longer than the longest |
| 717 | * currently-defined message. |
| 718 | */ |
| 719 | assert(tal_count(payload) == ONION_REPLY_SIZE + 4); |
| 720 | |
| 721 | /* BOLT #4: |
| 722 | * |
| 723 | * Where `hmac` is an HMAC authenticating the remainder of the packet, |
| 724 | * with a key generated using the above process, with key type `um` |
| 725 | */ |
| 726 | subkey_from_hmac("um", shared_secret, &key); |
| 727 | |
| 728 | compute_hmac(&key, payload, tal_count(payload), NULL, 0, &hmac); |
| 729 | reply->contents = tal_arr(reply, u8, 0), |
| 730 | towire_hmac(&reply->contents, &hmac); |
| 731 | |
| 732 | towire(&reply->contents, payload, tal_count(payload)); |
| 733 | tal_free(payload); |
| 734 | |
| 735 | return reply; |
| 736 | } |
| 737 | |
| 738 | struct onionreply *wrap_onionreply(const tal_t *ctx, |
| 739 | const struct secret *shared_secret, |