| 757 | } |
| 758 | |
| 759 | u8 *unwrap_onionreply(const tal_t *ctx, |
| 760 | const struct secret *shared_secrets, |
| 761 | const int numhops, |
| 762 | const struct onionreply *reply, |
| 763 | int *origin_index) |
| 764 | { |
| 765 | struct onionreply *r; |
| 766 | struct secret key; |
| 767 | struct hmac hmac; |
| 768 | const u8 *cursor; |
| 769 | u8 *final; |
| 770 | size_t max; |
| 771 | u16 msglen; |
| 772 | |
| 773 | if (tal_count(reply->contents) != ONION_REPLY_SIZE + sizeof(hmac) + 4) { |
| 774 | return NULL; |
| 775 | } |
| 776 | |
| 777 | r = new_onionreply(tmpctx, reply->contents); |
| 778 | *origin_index = -1; |
| 779 | |
| 780 | for (int i = 0; i < numhops; i++) { |
| 781 | /* Since the encryption is just XORing with the cipher |
| 782 | * stream encryption is identical to decryption */ |
| 783 | r = wrap_onionreply(tmpctx, &shared_secrets[i], r); |
| 784 | |
| 785 | /* Check if the HMAC matches, this means that this is |
| 786 | * the origin */ |
| 787 | subkey_from_hmac("um", &shared_secrets[i], &key); |
| 788 | compute_hmac(&key, r->contents + sizeof(hmac.bytes), |
| 789 | tal_count(r->contents) - sizeof(hmac.bytes), |
| 790 | NULL, 0, &hmac); |
| 791 | if (memcmp(hmac.bytes, r->contents, sizeof(hmac.bytes)) == 0) { |
| 792 | *origin_index = i; |
| 793 | break; |
| 794 | } |
| 795 | } |
| 796 | if (*origin_index == -1) { |
| 797 | return NULL; |
| 798 | } |
| 799 | |
| 800 | cursor = r->contents + sizeof(hmac); |
| 801 | max = tal_count(r->contents) - sizeof(hmac); |
| 802 | msglen = fromwire_u16(&cursor, &max); |
| 803 | |
| 804 | if (msglen > ONION_REPLY_SIZE) { |
| 805 | return NULL; |
| 806 | } |
| 807 | |
| 808 | final = tal_arr(ctx, u8, msglen); |
| 809 | if (!fromwire(&cursor, &max, final, msglen)) |
| 810 | return tal_free(final); |
| 811 | return final; |
| 812 | } |
| 813 | |
| 814 | struct onionpacket *sphinx_decompress(const tal_t *ctx, |
| 815 | const struct sphinx_compressed_onion *src, |