Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
/*
|
|
|
|
* CDDL HEADER START
|
|
|
|
*
|
|
|
|
* This file and its contents are supplied under the terms of the
|
|
|
|
* Common Development and Distribution License ("CDDL"), version 1.0.
|
|
|
|
* You may only use this file in accordance with the terms of version
|
|
|
|
* 1.0 of the CDDL.
|
|
|
|
*
|
|
|
|
* A full copy of the text of the CDDL should have accompanied this
|
|
|
|
* source. A copy of the CDDL is also available via the Internet at
|
|
|
|
* http://www.illumos.org/license/CDDL.
|
|
|
|
*
|
|
|
|
* CDDL HEADER END
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2017, Datto, Inc. All rights reserved.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _SYS_DSL_CRYPT_H
|
|
|
|
#define _SYS_DSL_CRYPT_H
|
|
|
|
|
|
|
|
#include <sys/dmu_tx.h>
|
|
|
|
#include <sys/dmu.h>
|
|
|
|
#include <sys/zio_crypt.h>
|
|
|
|
#include <sys/spa.h>
|
|
|
|
#include <sys/dsl_dataset.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ZAP entry keys for DSL Crypto Keys stored on disk. In addition,
|
|
|
|
* ZFS_PROP_KEYFORMAT, ZFS_PROP_PBKDF2_SALT, and ZFS_PROP_PBKDF2_ITERS are
|
|
|
|
* also maintained here using their respective property names.
|
|
|
|
*/
|
|
|
|
#define DSL_CRYPTO_KEY_CRYPTO_SUITE "DSL_CRYPTO_SUITE"
|
|
|
|
#define DSL_CRYPTO_KEY_GUID "DSL_CRYPTO_GUID"
|
|
|
|
#define DSL_CRYPTO_KEY_IV "DSL_CRYPTO_IV"
|
|
|
|
#define DSL_CRYPTO_KEY_MAC "DSL_CRYPTO_MAC"
|
|
|
|
#define DSL_CRYPTO_KEY_MASTER_KEY "DSL_CRYPTO_MASTER_KEY_1"
|
|
|
|
#define DSL_CRYPTO_KEY_HMAC_KEY "DSL_CRYPTO_HMAC_KEY_1"
|
|
|
|
#define DSL_CRYPTO_KEY_ROOT_DDOBJ "DSL_CRYPTO_ROOT_DDOBJ"
|
|
|
|
#define DSL_CRYPTO_KEY_REFCOUNT "DSL_CRYPTO_REFCOUNT"
|
2017-11-08 22:12:59 +03:00
|
|
|
#define DSL_CRYPTO_KEY_VERSION "DSL_CRYPTO_VERSION"
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* In-memory representation of a wrapping key. One of these structs will exist
|
|
|
|
* for each encryption root with its key loaded.
|
|
|
|
*/
|
|
|
|
typedef struct dsl_wrapping_key {
|
|
|
|
/* link on spa_keystore_t:sk_wkeys */
|
|
|
|
avl_node_t wk_avl_link;
|
|
|
|
|
|
|
|
/* keyformat property enum */
|
|
|
|
zfs_keyformat_t wk_keyformat;
|
|
|
|
|
|
|
|
/* the pbkdf2 salt, if the keyformat is of type passphrase */
|
|
|
|
uint64_t wk_salt;
|
|
|
|
|
|
|
|
/* the pbkdf2 iterations, if the keyformat is of type passphrase */
|
|
|
|
uint64_t wk_iters;
|
|
|
|
|
|
|
|
/* actual wrapping key */
|
|
|
|
crypto_key_t wk_key;
|
|
|
|
|
|
|
|
/* refcount of number of dsl_crypto_key_t's holding this struct */
|
2018-09-26 20:29:26 +03:00
|
|
|
zfs_refcount_t wk_refcnt;
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
|
|
|
|
/* dsl directory object that owns this wrapping key */
|
|
|
|
uint64_t wk_ddobj;
|
|
|
|
} dsl_wrapping_key_t;
|
|
|
|
|
|
|
|
/* enum of commands indicating special actions that should be run */
|
|
|
|
typedef enum dcp_cmd {
|
|
|
|
/* key creation commands */
|
|
|
|
DCP_CMD_NONE = 0, /* no specific command */
|
|
|
|
DCP_CMD_RAW_RECV, /* raw receive */
|
|
|
|
|
|
|
|
/* key changing commands */
|
|
|
|
DCP_CMD_NEW_KEY, /* rewrap key as an encryption root */
|
|
|
|
DCP_CMD_INHERIT, /* rewrap key with parent's wrapping key */
|
|
|
|
DCP_CMD_FORCE_NEW_KEY, /* change to encryption root without rewrap */
|
|
|
|
DCP_CMD_FORCE_INHERIT, /* inherit parent's key without rewrap */
|
|
|
|
|
|
|
|
DCP_CMD_MAX
|
|
|
|
} dcp_cmd_t;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This struct is a simple wrapper around all the parameters that are usually
|
|
|
|
* required to setup encryption. It exists so that all of the params can be
|
|
|
|
* passed around the kernel together for convenience.
|
|
|
|
*/
|
|
|
|
typedef struct dsl_crypto_params {
|
|
|
|
/* command indicating intended action */
|
|
|
|
dcp_cmd_t cp_cmd;
|
|
|
|
|
|
|
|
/* the encryption algorithm */
|
|
|
|
enum zio_encrypt cp_crypt;
|
|
|
|
|
|
|
|
/* keylocation property string */
|
|
|
|
char *cp_keylocation;
|
|
|
|
|
|
|
|
/* the wrapping key */
|
|
|
|
dsl_wrapping_key_t *cp_wkey;
|
|
|
|
} dsl_crypto_params_t;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In-memory representation of a DSL Crypto Key object. One of these structs
|
|
|
|
* (and corresponding on-disk ZAP object) will exist for each encrypted
|
|
|
|
* clone family that is mounted or otherwise reading protected data.
|
|
|
|
*/
|
|
|
|
typedef struct dsl_crypto_key {
|
|
|
|
/* link on spa_keystore_t:sk_dsl_keys */
|
|
|
|
avl_node_t dck_avl_link;
|
|
|
|
|
2018-10-03 19:47:11 +03:00
|
|
|
/* refcount of holders of this key */
|
2018-09-26 20:29:26 +03:00
|
|
|
zfs_refcount_t dck_holds;
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
|
|
|
|
/* master key used to derive encryption keys */
|
|
|
|
zio_crypt_key_t dck_key;
|
|
|
|
|
|
|
|
/* wrapping key for syncing this structure to disk */
|
|
|
|
dsl_wrapping_key_t *dck_wkey;
|
|
|
|
|
|
|
|
/* on-disk object id */
|
|
|
|
uint64_t dck_obj;
|
|
|
|
} dsl_crypto_key_t;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In-memory mapping of a dataset object id to a DSL Crypto Key. This is used
|
|
|
|
* to look up the corresponding dsl_crypto_key_t from the zio layer for
|
|
|
|
* performing data encryption and decryption.
|
|
|
|
*/
|
|
|
|
typedef struct dsl_key_mapping {
|
|
|
|
/* link on spa_keystore_t:sk_key_mappings */
|
|
|
|
avl_node_t km_avl_link;
|
|
|
|
|
|
|
|
/* refcount of how many users are depending on this mapping */
|
2018-09-26 20:29:26 +03:00
|
|
|
zfs_refcount_t km_refcnt;
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
|
|
|
|
/* dataset this crypto key belongs to (index) */
|
|
|
|
uint64_t km_dsobj;
|
|
|
|
|
|
|
|
/* crypto key (value) of this record */
|
|
|
|
dsl_crypto_key_t *km_key;
|
|
|
|
} dsl_key_mapping_t;
|
|
|
|
|
|
|
|
/* in memory structure for holding all wrapping and dsl keys */
|
|
|
|
typedef struct spa_keystore {
|
|
|
|
/* lock for protecting sk_dsl_keys */
|
|
|
|
krwlock_t sk_dk_lock;
|
|
|
|
|
|
|
|
/* tree of all dsl_crypto_key_t's */
|
|
|
|
avl_tree_t sk_dsl_keys;
|
|
|
|
|
|
|
|
/* lock for protecting sk_key_mappings */
|
|
|
|
krwlock_t sk_km_lock;
|
|
|
|
|
|
|
|
/* tree of all dsl_key_mapping_t's, indexed by dsobj */
|
|
|
|
avl_tree_t sk_key_mappings;
|
|
|
|
|
|
|
|
/* lock for protecting the wrapping keys tree */
|
|
|
|
krwlock_t sk_wkeys_lock;
|
|
|
|
|
|
|
|
/* tree of all dsl_wrapping_key_t's, indexed by ddobj */
|
|
|
|
avl_tree_t sk_wkeys;
|
|
|
|
} spa_keystore_t;
|
|
|
|
|
|
|
|
int dsl_crypto_params_create_nvlist(dcp_cmd_t cmd, nvlist_t *props,
|
|
|
|
nvlist_t *crypto_args, dsl_crypto_params_t **dcp_out);
|
|
|
|
void dsl_crypto_params_free(dsl_crypto_params_t *dcp, boolean_t unload);
|
|
|
|
void dsl_dataset_crypt_stats(struct dsl_dataset *ds, nvlist_t *nv);
|
|
|
|
int dsl_crypto_can_set_keylocation(const char *dsname, const char *keylocation);
|
2017-11-08 22:12:59 +03:00
|
|
|
boolean_t dsl_dir_incompatible_encryption_version(dsl_dir_t *dd);
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
|
|
|
|
void spa_keystore_init(spa_keystore_t *sk);
|
|
|
|
void spa_keystore_fini(spa_keystore_t *sk);
|
|
|
|
|
2022-04-19 21:49:30 +03:00
|
|
|
void spa_keystore_dsl_key_rele(spa_t *spa, dsl_crypto_key_t *dck,
|
|
|
|
const void *tag);
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
int spa_keystore_load_wkey_impl(spa_t *spa, dsl_wrapping_key_t *wkey);
|
|
|
|
int spa_keystore_load_wkey(const char *dsname, dsl_crypto_params_t *dcp,
|
|
|
|
boolean_t noop);
|
|
|
|
int spa_keystore_unload_wkey_impl(spa_t *spa, uint64_t ddobj);
|
|
|
|
int spa_keystore_unload_wkey(const char *dsname);
|
|
|
|
|
2022-04-19 21:49:30 +03:00
|
|
|
int spa_keystore_create_mapping(spa_t *spa, struct dsl_dataset *ds,
|
|
|
|
const void *tag, dsl_key_mapping_t **km_out);
|
|
|
|
int spa_keystore_remove_mapping(spa_t *spa, uint64_t dsobj, const void *tag);
|
|
|
|
void key_mapping_add_ref(dsl_key_mapping_t *km, const void *tag);
|
|
|
|
void key_mapping_rele(spa_t *spa, dsl_key_mapping_t *km, const void *tag);
|
|
|
|
int spa_keystore_lookup_key(spa_t *spa, uint64_t dsobj, const void *tag,
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
dsl_crypto_key_t **dck_out);
|
|
|
|
|
dmu_objset_from_ds must be called with dp_config_rwlock held
The normal lock order is that the dp_config_rwlock must be held before
the ds_opening_lock. For example, dmu_objset_hold() does this.
However, dmu_objset_open_impl() is called with the ds_opening_lock held,
and if the dp_config_rwlock is not already held, it will attempt to
acquire it. This may lead to deadlock, since the lock order is
reversed.
Looking at all the callers of dmu_objset_open_impl() (which is
principally the callers of dmu_objset_from_ds()), almost all callers
already have the dp_config_rwlock. However, there are a few places in
the send and receive code paths that do not. For example:
dsl_crypto_populate_key_nvlist, send_cb, dmu_recv_stream,
receive_write_byref, redact_traverse_thread.
This commit resolves the problem by requiring all callers ot
dmu_objset_from_ds() to hold the dp_config_rwlock. In most cases, the
code has been restructured such that we call dmu_objset_from_ds()
earlier on in the send and receive processes, when we already have the
dp_config_rwlock, and save the objset_t until we need it in the middle
of the send or receive (similar to what we already do with the
dsl_dataset_t). Thus we do not need to acquire the dp_config_rwlock in
many new places.
I also cleaned up code in dmu_redact_snap() and send_traverse_thread().
Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Paul Zuchowski <pzuchowski@datto.com>
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Closes #9662
Closes #10115
2020-03-12 20:55:02 +03:00
|
|
|
int dsl_crypto_populate_key_nvlist(struct objset *os,
|
2019-02-04 22:24:55 +03:00
|
|
|
uint64_t from_ivset_guid, nvlist_t **nvl_out);
|
2018-02-21 23:31:03 +03:00
|
|
|
int dsl_crypto_recv_raw_key_check(struct dsl_dataset *ds,
|
|
|
|
nvlist_t *nvl, dmu_tx_t *tx);
|
|
|
|
void dsl_crypto_recv_raw_key_sync(struct dsl_dataset *ds,
|
|
|
|
nvlist_t *nvl, dmu_tx_t *tx);
|
2019-02-04 22:24:55 +03:00
|
|
|
int dsl_crypto_recv_raw(const char *poolname, uint64_t dsobj, uint64_t fromobj,
|
2018-02-21 23:31:03 +03:00
|
|
|
dmu_objset_type_t ostype, nvlist_t *nvl, boolean_t do_key);
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
|
|
|
|
int spa_keystore_change_key(const char *dsname, dsl_crypto_params_t *dcp);
|
|
|
|
int dsl_dir_rename_crypt_check(dsl_dir_t *dd, dsl_dir_t *newparent);
|
|
|
|
int dsl_dataset_promote_crypt_check(dsl_dir_t *target, dsl_dir_t *origin);
|
|
|
|
void dsl_dataset_promote_crypt_sync(dsl_dir_t *target, dsl_dir_t *origin,
|
|
|
|
dmu_tx_t *tx);
|
|
|
|
int dmu_objset_create_crypt_check(dsl_dir_t *parentdd,
|
2018-06-18 22:47:12 +03:00
|
|
|
dsl_crypto_params_t *dcp, boolean_t *will_encrypt);
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
void dsl_dataset_create_crypt_sync(uint64_t dsobj, dsl_dir_t *dd,
|
|
|
|
struct dsl_dataset *origin, dsl_crypto_params_t *dcp, dmu_tx_t *tx);
|
|
|
|
uint64_t dsl_crypto_key_create_sync(uint64_t crypt, dsl_wrapping_key_t *wkey,
|
|
|
|
dmu_tx_t *tx);
|
|
|
|
uint64_t dsl_crypto_key_clone_sync(dsl_dir_t *origindd, dmu_tx_t *tx);
|
|
|
|
void dsl_crypto_key_destroy_sync(uint64_t dckobj, dmu_tx_t *tx);
|
|
|
|
|
|
|
|
int spa_crypt_get_salt(spa_t *spa, uint64_t dsobj, uint8_t *salt);
|
|
|
|
int spa_do_crypt_mac_abd(boolean_t generate, spa_t *spa, uint64_t dsobj,
|
|
|
|
abd_t *abd, uint_t datalen, uint8_t *mac);
|
|
|
|
int spa_do_crypt_objset_mac_abd(boolean_t generate, spa_t *spa, uint64_t dsobj,
|
|
|
|
abd_t *abd, uint_t datalen, boolean_t byteswap);
|
2018-05-03 01:36:20 +03:00
|
|
|
int 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);
|
Native Encryption for ZFS on Linux
This change incorporates three major pieces:
The first change is a keystore that manages wrapping
and encryption keys for encrypted datasets. These
commands mostly involve manipulating the new
DSL Crypto Key ZAP Objects that live in the MOS. Each
encrypted dataset has its own DSL Crypto Key that is
protected with a user's key. This level of indirection
allows users to change their keys without re-encrypting
their entire datasets. The change implements the new
subcommands "zfs load-key", "zfs unload-key" and
"zfs change-key" which allow the user to manage their
encryption keys and settings. In addition, several new
flags and properties have been added to allow dataset
creation and to make mounting and unmounting more
convenient.
The second piece of this patch provides the ability to
encrypt, decyrpt, and authenticate protected datasets.
Each object set maintains a Merkel tree of Message
Authentication Codes that protect the lower layers,
similarly to how checksums are maintained. This part
impacts the zio layer, which handles the actual
encryption and generation of MACs, as well as the ARC
and DMU, which need to be able to handle encrypted
buffers and protected data.
The last addition is the ability to do raw, encrypted
sends and receives. The idea here is to send raw
encrypted and compressed data and receive it exactly
as is on a backup system. This means that the dataset
on the receiving system is protected using the same
user key that is in use on the sending side. By doing
so, datasets can be efficiently backed up to an
untrusted system without fear of data being
compromised.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #494
Closes #5769
2017-08-14 20:36:48 +03:00
|
|
|
|
|
|
|
#endif
|