diff options
Diffstat (limited to 'module/zfs/dsl_crypt.c')
-rw-r--r-- | module/zfs/dsl_crypt.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index 579b32c42..e2067448c 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -2661,23 +2661,23 @@ error: * these fields to populate pabd (the plaintext). */ int -spa_do_crypt_abd(boolean_t encrypt, spa_t *spa, uint64_t dsobj, - const blkptr_t *bp, uint64_t txgid, uint_t datalen, abd_t *pabd, - abd_t *cabd, uint8_t *iv, uint8_t *mac, uint8_t *salt, boolean_t *no_crypt) +spa_do_crypt_abd(boolean_t encrypt, spa_t *spa, const zbookmark_phys_t *zb, + dmu_object_type_t ot, boolean_t dedup, boolean_t bswap, uint8_t *salt, + uint8_t *iv, uint8_t *mac, uint_t datalen, abd_t *pabd, abd_t *cabd, + boolean_t *no_crypt) { int ret; - dmu_object_type_t ot = BP_GET_TYPE(bp); dsl_crypto_key_t *dck = NULL; uint8_t *plainbuf = NULL, *cipherbuf = NULL; ASSERT(spa_feature_is_active(spa, SPA_FEATURE_ENCRYPTION)); - ASSERT(!BP_IS_EMBEDDED(bp)); - ASSERT(BP_IS_ENCRYPTED(bp)); /* look up the key from the spa's keystore */ - ret = spa_keystore_lookup_key(spa, dsobj, FTAG, &dck); - if (ret != 0) + ret = spa_keystore_lookup_key(spa, zb->zb_objset, FTAG, &dck); + if (ret != 0) { + ret = SET_ERROR(EACCES); return (ret); + } if (encrypt) { plainbuf = abd_borrow_buf_copy(pabd, datalen); @@ -2696,7 +2696,7 @@ spa_do_crypt_abd(boolean_t encrypt, spa_t *spa, uint64_t dsobj, * at allocation time in zio_alloc_zil(). On decryption, we simply use * the provided values. */ - if (encrypt && ot != DMU_OT_INTENT_LOG && !BP_GET_DEDUP(bp)) { + if (encrypt && ot != DMU_OT_INTENT_LOG && !dedup) { ret = zio_crypt_key_get_salt(&dck->dck_key, salt); if (ret != 0) goto error; @@ -2704,7 +2704,7 @@ spa_do_crypt_abd(boolean_t encrypt, spa_t *spa, uint64_t dsobj, ret = zio_crypt_generate_iv(iv); if (ret != 0) goto error; - } else if (encrypt && BP_GET_DEDUP(bp)) { + } else if (encrypt && dedup) { ret = zio_crypt_generate_iv_salt_dedup(&dck->dck_key, plainbuf, datalen, iv, salt); if (ret != 0) @@ -2712,8 +2712,17 @@ spa_do_crypt_abd(boolean_t encrypt, spa_t *spa, uint64_t dsobj, } /* call lower level function to perform encryption / decryption */ - ret = zio_do_crypt_data(encrypt, &dck->dck_key, salt, ot, iv, mac, - datalen, BP_SHOULD_BYTESWAP(bp), plainbuf, cipherbuf, no_crypt); + ret = zio_do_crypt_data(encrypt, &dck->dck_key, ot, bswap, salt, iv, + mac, datalen, plainbuf, cipherbuf, no_crypt); + + /* + * Handle injected decryption faults. Unfortunately, we cannot inject + * faults for dnode blocks because we might trigger the panic in + * dbuf_prepare_encrypted_dnode_leaf(), which exists because syncing + * context is not prepared to handle malicious decryption failures. + */ + if (zio_injection_enabled && !encrypt && ot != DMU_OT_DNODE && ret == 0) + ret = zio_handle_decrypt_injection(spa, zb, ot, ECKSUM); if (ret != 0) goto error; |