* This function will take a header that only has raw encrypted data in * b_crypt_hdr.b_rabd and decrypt it into a new buffer which is stored in * b_l1hdr.b_pabd. If designated in the header flags, this function will * also decompress the data. */
| 1864 | * also decompress the data. |
| 1865 | */ |
| 1866 | static int |
| 1867 | arc_hdr_decrypt(arc_buf_hdr_t *hdr, spa_t *spa, const zbookmark_phys_t *zb) |
| 1868 | { |
| 1869 | int ret; |
| 1870 | abd_t *cabd = NULL; |
| 1871 | void *tmp = NULL; |
| 1872 | boolean_t no_crypt = B_FALSE; |
| 1873 | boolean_t bswap = (hdr->b_l1hdr.b_byteswap != DMU_BSWAP_NUMFUNCS); |
| 1874 | |
| 1875 | ASSERT(HDR_EMPTY_OR_LOCKED(hdr)); |
| 1876 | ASSERT(HDR_ENCRYPTED(hdr)); |
| 1877 | |
| 1878 | arc_hdr_alloc_abd(hdr, ARC_HDR_DO_ADAPT); |
| 1879 | |
| 1880 | ret = spa_do_crypt_abd(B_FALSE, spa, zb, hdr->b_crypt_hdr.b_ot, |
| 1881 | B_FALSE, bswap, hdr->b_crypt_hdr.b_salt, hdr->b_crypt_hdr.b_iv, |
| 1882 | hdr->b_crypt_hdr.b_mac, HDR_GET_PSIZE(hdr), hdr->b_l1hdr.b_pabd, |
| 1883 | hdr->b_crypt_hdr.b_rabd, &no_crypt); |
| 1884 | if (ret != 0) |
| 1885 | goto error; |
| 1886 | |
| 1887 | if (no_crypt) { |
| 1888 | abd_copy(hdr->b_l1hdr.b_pabd, hdr->b_crypt_hdr.b_rabd, |
| 1889 | HDR_GET_PSIZE(hdr)); |
| 1890 | } |
| 1891 | |
| 1892 | /* |
| 1893 | * If this header has disabled arc compression but the b_pabd is |
| 1894 | * compressed after decrypting it, we need to decompress the newly |
| 1895 | * decrypted data. |
| 1896 | */ |
| 1897 | if (HDR_GET_COMPRESS(hdr) != ZIO_COMPRESS_OFF && |
| 1898 | !HDR_COMPRESSION_ENABLED(hdr)) { |
| 1899 | /* |
| 1900 | * We want to make sure that we are correctly honoring the |
| 1901 | * zfs_abd_scatter_enabled setting, so we allocate an abd here |
| 1902 | * and then loan a buffer from it, rather than allocating a |
| 1903 | * linear buffer and wrapping it in an abd later. |
| 1904 | */ |
| 1905 | cabd = arc_get_data_abd(hdr, arc_hdr_size(hdr), hdr, B_TRUE); |
| 1906 | tmp = abd_borrow_buf(cabd, arc_hdr_size(hdr)); |
| 1907 | |
| 1908 | ret = zio_decompress_data(HDR_GET_COMPRESS(hdr), |
| 1909 | hdr->b_l1hdr.b_pabd, tmp, HDR_GET_PSIZE(hdr), |
| 1910 | HDR_GET_LSIZE(hdr), &hdr->b_complevel); |
| 1911 | if (ret != 0) { |
| 1912 | abd_return_buf(cabd, tmp, arc_hdr_size(hdr)); |
| 1913 | goto error; |
| 1914 | } |
| 1915 | |
| 1916 | abd_return_buf_copy(cabd, tmp, arc_hdr_size(hdr)); |
| 1917 | arc_free_data_abd(hdr, hdr->b_l1hdr.b_pabd, |
| 1918 | arc_hdr_size(hdr), hdr); |
| 1919 | hdr->b_l1hdr.b_pabd = cabd; |
| 1920 | } |
| 1921 | |
| 1922 | return (0); |
| 1923 |
no test coverage detected