| 1794 | } |
| 1795 | |
| 1796 | static int |
| 1797 | arc_hdr_authenticate(arc_buf_hdr_t *hdr, spa_t *spa, uint64_t dsobj) |
| 1798 | { |
| 1799 | int ret; |
| 1800 | uint64_t csize; |
| 1801 | uint64_t lsize = HDR_GET_LSIZE(hdr); |
| 1802 | uint64_t psize = HDR_GET_PSIZE(hdr); |
| 1803 | void *tmpbuf = NULL; |
| 1804 | abd_t *abd = hdr->b_l1hdr.b_pabd; |
| 1805 | |
| 1806 | ASSERT(HDR_EMPTY_OR_LOCKED(hdr)); |
| 1807 | ASSERT(HDR_AUTHENTICATED(hdr)); |
| 1808 | ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL); |
| 1809 | |
| 1810 | /* |
| 1811 | * The MAC is calculated on the compressed data that is stored on disk. |
| 1812 | * However, if compressed arc is disabled we will only have the |
| 1813 | * decompressed data available to us now. Compress it into a temporary |
| 1814 | * abd so we can verify the MAC. The performance overhead of this will |
| 1815 | * be relatively low, since most objects in an encrypted objset will |
| 1816 | * be encrypted (instead of authenticated) anyway. |
| 1817 | */ |
| 1818 | if (HDR_GET_COMPRESS(hdr) != ZIO_COMPRESS_OFF && |
| 1819 | !HDR_COMPRESSION_ENABLED(hdr)) { |
| 1820 | tmpbuf = zio_buf_alloc(lsize); |
| 1821 | abd = abd_get_from_buf(tmpbuf, lsize); |
| 1822 | abd_take_ownership_of_buf(abd, B_TRUE); |
| 1823 | csize = zio_compress_data(HDR_GET_COMPRESS(hdr), |
| 1824 | hdr->b_l1hdr.b_pabd, tmpbuf, lsize, hdr->b_complevel); |
| 1825 | ASSERT3U(csize, <=, psize); |
| 1826 | abd_zero_off(abd, csize, psize - csize); |
| 1827 | } |
| 1828 | |
| 1829 | /* |
| 1830 | * Authentication is best effort. We authenticate whenever the key is |
| 1831 | * available. If we succeed we clear ARC_FLAG_NOAUTH. |
| 1832 | */ |
| 1833 | if (hdr->b_crypt_hdr.b_ot == DMU_OT_OBJSET) { |
| 1834 | ASSERT3U(HDR_GET_COMPRESS(hdr), ==, ZIO_COMPRESS_OFF); |
| 1835 | ASSERT3U(lsize, ==, psize); |
| 1836 | ret = spa_do_crypt_objset_mac_abd(B_FALSE, spa, dsobj, abd, |
| 1837 | psize, hdr->b_l1hdr.b_byteswap != DMU_BSWAP_NUMFUNCS); |
| 1838 | } else { |
| 1839 | ret = spa_do_crypt_mac_abd(B_FALSE, spa, dsobj, abd, psize, |
| 1840 | hdr->b_crypt_hdr.b_mac); |
| 1841 | } |
| 1842 | |
| 1843 | if (ret == 0) |
| 1844 | arc_hdr_clear_flags(hdr, ARC_FLAG_NOAUTH); |
| 1845 | else if (ret != ENOENT) |
| 1846 | goto error; |
| 1847 | |
| 1848 | if (tmpbuf != NULL) |
| 1849 | abd_free(abd); |
| 1850 | |
| 1851 | return (0); |
| 1852 | |
| 1853 | error: |
no test coverage detected