| 823 | } |
| 824 | |
| 825 | u8 *unwrap_onionreply(const tal_t *ctx, |
| 826 | const struct secret *shared_secrets, |
| 827 | const int numhops, |
| 828 | const struct onionreply *reply, |
| 829 | int *origin_index) |
| 830 | { |
| 831 | struct onionreply *r; |
| 832 | const u8 *cursor; |
| 833 | size_t max; |
| 834 | u8 *ret; |
| 835 | |
| 836 | r = new_onionreply(tmpctx, reply->contents); |
| 837 | *origin_index = -1; |
| 838 | ret = NULL; |
| 839 | |
| 840 | /* BOLT #4: |
| 841 | * The _origin node_: |
| 842 | * - once the return message has been decrypted: |
| 843 | * - SHOULD store a copy of the message. |
| 844 | * - SHOULD continue decrypting, until the loop has been repeated 27 times |
| 845 | * (maximum route length of tlv payload type). |
| 846 | * - SHOULD use constant `ammag` and `um` keys to obfuscate the route length. |
| 847 | *... |
| 848 | * ### Rationale |
| 849 | * |
| 850 | * The requirements for the _origin node_ should help hide the payment sender. |
| 851 | * By continuing decrypting 27 times (dummy decryption cycles after the error is found) |
| 852 | * the erroring node cannot learn its relative position in the route by performing |
| 853 | * a timing analysis if the sender were to retry the same route multiple times. |
| 854 | */ |
| 855 | for (size_t i = 0; i < 27; i++) { |
| 856 | struct secret ss, key; |
| 857 | struct hmac hmac, expected_hmac; |
| 858 | |
| 859 | if (i < numhops) |
| 860 | ss = shared_secrets[i]; |
| 861 | else |
| 862 | memset(&ss, 0x7, sizeof(ss)); |
| 863 | |
| 864 | /* Since the encryption is just XORing with the cipher |
| 865 | * stream encryption is identical to decryption */ |
| 866 | r = wrap_onionreply(tmpctx, &ss, r); |
| 867 | |
| 868 | /* Check if the HMAC matches, this means that this is |
| 869 | * the origin */ |
| 870 | subkey_from_hmac("um", &ss, &key); |
| 871 | |
| 872 | cursor = r->contents; |
| 873 | max = tal_count(r->contents); |
| 874 | |
| 875 | fromwire_hmac(&cursor, &max, &hmac); |
| 876 | /* Too short. */ |
| 877 | if (!cursor) |
| 878 | return NULL; |
| 879 | |
| 880 | compute_hmac(&key, cursor, max, NULL, 0, &expected_hmac); |
| 881 | if (hmac_eq(&hmac, &expected_hmac)) { |
| 882 | u16 msglen; |