aboutsummaryrefslogtreecommitdiffstats
path: root/tests/zfs-tests
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2017-08-14 13:36:48 -0400
committerBrian Behlendorf <[email protected]>2017-08-14 10:36:48 -0700
commitb52563034230b35f0562b6f40ad1a00f02bd9a05 (patch)
tree794ccc5160e997e280cb6e36c7778ce9f7a96548 /tests/zfs-tests
parent376994828fd3753aba75d492859727ca76f6a293 (diff)
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 <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Jorgen Lundman <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Closes #494 Closes #5769
Diffstat (limited to 'tests/zfs-tests')
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/Makefile.am3
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile.am11
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh30
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh32
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh62
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh86
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh71
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh78
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh58
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh65
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh75
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_clone/Makefile.am3
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh83
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_create/Makefile.am4
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh98
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh134
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am12
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh30
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh32
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg26
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh85
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh77
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib102
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh58
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh73
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh54
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh66
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_mount/Makefile.am1
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh62
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_promote/Makefile.am3
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh80
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_receive/Makefile.am6
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh1
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh83
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh93
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh75
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh75
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_rename/Makefile.am4
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh78
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh51
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am4
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh76
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh59
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh79
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_set/Makefile.am3
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh1
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh93
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile.am7
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh30
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh32
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh69
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh76
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh72
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am2
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh89
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh95
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg1
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am4
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh59
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh59
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zpool_scrub/Makefile.am3
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh71
-rw-r--r--tests/zfs-tests/tests/functional/rsend/Makefile.am1
-rw-r--r--tests/zfs-tests/tests/functional/rsend/rsend.kshlib2
-rwxr-xr-xtests/zfs-tests/tests/functional/rsend/send_encrypted_heirarchy.ksh96
65 files changed, 3193 insertions, 10 deletions
diff --git a/tests/zfs-tests/tests/functional/cli_root/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/Makefile.am
index ff0951485..9abaa8f4f 100644
--- a/tests/zfs-tests/tests/functional/cli_root/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/Makefile.am
@@ -5,12 +5,14 @@ dist_pkgdata_SCRIPTS = \
SUBDIRS = \
zdb \
zfs \
+ zfs_change-key \
zfs_clone \
zfs_copies \
zfs_create \
zfs_destroy \
zfs_get \
zfs_inherit \
+ zfs_load-key \
zfs_mount \
zfs_promote \
zfs_property \
@@ -22,6 +24,7 @@ SUBDIRS = \
zfs_set \
zfs_share \
zfs_snapshot \
+ zfs_unload-key \
zfs_unmount \
zfs_unshare \
zfs_upgrade \
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile.am
new file mode 100644
index 000000000..7c67e7239
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/Makefile.am
@@ -0,0 +1,11 @@
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zfs_change-key
+dist_pkgdata_SCRIPTS = \
+ setup.ksh \
+ cleanup.ksh \
+ zfs_change-key.ksh \
+ zfs_change-key_child.ksh \
+ zfs_change-key_inherit.ksh \
+ zfs_change-key_format.ksh \
+ zfs_change-key_load.ksh \
+ zfs_change-key_location.ksh \
+ zfs_change-key_pbkdf2iters.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh
new file mode 100755
index 000000000..79cd6e9f9
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/cleanup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh
new file mode 100755
index 000000000..6a9af3bc2
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/setup.ksh
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+DISK=${DISKS%% *}
+
+default_setup $DISK
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh
new file mode 100755
index 000000000..781caae5b
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key.ksh
@@ -0,0 +1,62 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key' should change the key material.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Attempt to change the key
+# 3. Unmount the dataset and unload its key
+# 4. Attempt to load the old key
+# 5. Verify the key is not loaded
+# 6. Attempt to load the new key
+# 7. Verify the key is loaded
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key' should change the key material"
+
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must eval "echo $PASSPHRASE2 | zfs change-key $TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_mustnot eval "echo $PASSPHRASE1 | zfs load-key $TESTPOOL/$TESTFS1"
+log_must key_unavailable $TESTPOOL/$TESTFS1
+
+log_must eval "echo $PASSPHRASE2 | zfs load-key $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key' changes the key material"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh
new file mode 100755
index 000000000..dda7c1df4
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_child.ksh
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key' should promote an encrypted child to an encryption root.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create an encrypted child dataset
+# 3. Attempt to change the key without any flags
+# 4. Attempt to change the key specifying keylocation
+# 5. Attempt to change the key specifying keyformat
+# 6. Verify the new encryption root can unload and load its key
+# 7. Recreate the child dataset
+# 8. Attempt to change the key specifying both the keylocation and keyformat
+# 9. Verify the new encryption root can unload and load its key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "'zfs change-key' should promote an encrypted child to an" \
+ "encryption root"
+
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must zfs create $TESTPOOL/$TESTFS1/child
+
+log_mustnot eval "echo $PASSPHRASE2 | zfs change-key" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_mustnot eval "echo $PASSPHRASE2 | zfs change-key -o keylocation=prompt" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must eval "echo $PASSPHRASE2 | zfs change-key -o keyformat=passphrase" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1/child
+log_must zfs unload-key $TESTPOOL/$TESTFS1/child
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE2 | zfs load-key $TESTPOOL/$TESTFS1/child"
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_must zfs destroy $TESTPOOL/$TESTFS1/child
+log_must zfs create $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE2 | zfs change-key -o keyformat=passphrase" \
+ "-o keylocation=prompt $TESTPOOL/$TESTFS1/child"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1/child
+log_must zfs unload-key $TESTPOOL/$TESTFS1/child
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE2 | zfs load-key $TESTPOOL/$TESTFS1/child"
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_pass "'zfs change-key' promotes an encrypted child to an encryption root"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh
new file mode 100755
index 000000000..af5e145f9
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_format.ksh
@@ -0,0 +1,71 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -o' should change the key format.
+#
+# STRATEGY:
+# 1. Create an encryption dataset with a passphrase key format
+# 2. Unmount the dataset
+# 3. Verify the key format is passphrase
+# 4. Change the key format to hex
+# 5. Verify the key format is hex
+# 6. Attempt to reload the dataset's key
+# 7. Change the key format to raw
+# 8. Verify the key format is raw
+# 9. Attempt to reload the dataset's key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -o' should change the key format"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must zfs unmount $TESTPOOL/$TESTFS1
+
+log_must verify_keyformat $TESTPOOL/$TESTFS1 "passphrase"
+
+log_must eval "echo $HEXKEY | zfs change-key -o keyformat=hex" \
+ "$TESTPOOL/$TESTFS1"
+log_must verify_keyformat $TESTPOOL/$TESTFS1 "hex"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo $HEXKEY | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_must eval "echo -n $RAWKEY | zfs change-key -o keyformat=raw" \
+ "$TESTPOOL/$TESTFS1"
+log_must verify_keyformat $TESTPOOL/$TESTFS1 "raw"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo -n $RAWKEY | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_pass "'zfs change-key -o' changes the key format"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh
new file mode 100755
index 000000000..94820c37e
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh
@@ -0,0 +1,78 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -i' should cause a dataset to inherit its parent key
+#
+# STRATEGY:
+# 1. Create a parent encrypted dataset
+# 2. Create a child dataset as an encryption root
+# 3. Attempt to inherit the parent key
+# 4. Verify the key is inherited
+# 5. Unmount the parent and unload its key
+# 6. Verify the key is unavailable for parent and child
+# 7. Load the parent key
+# 8. Verify the key is available for parent and child
+# 9. Attempt to mount the datasets
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -i' should cause a dataset to inherit its" \
+ "parent key"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt" \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must verify_encryption_root $TESTPOOL/$TESTFS1/child \
+ "$TESTPOOL/$TESTFS1/child"
+
+log_must zfs change-key -i $TESTPOOL/$TESTFS1/child
+log_must verify_encryption_root $TESTPOOL/$TESTFS1/child "$TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must key_unavailable $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_must key_available $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_must zfs mount $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1/child
+
+log_pass "'zfs change-key -i' causes a dataset to inherit its parent key"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh
new file mode 100755
index 000000000..4ed4aadfe
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_load.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -l' should load a dataset's key to change it.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Unload dataset and unload its key
+# 3. Attempt to change the key
+# 4. Verify the dataset key is loaded
+# 3. Attempt to change the key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -l' should load a dataset's key to change it"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs change-key -l $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_must zfs change-key -l $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key -l' loads a dataset's key to change it"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh
new file mode 100755
index 000000000..5cbe34b26
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_location.ksh
@@ -0,0 +1,65 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -o' should change the keylocation.
+#
+# STRATEGY:
+# 1. Create an encryption dataset with a file key location
+# 2. Change the key location to 'prompt'
+# 3. Verify the key location
+# 4. Unmount the dataset and unload its key
+# 5. Attempt to load the dataset's key
+# 6. Attempt to change the key location to 'none'
+# 7. Attempt to change the key location to an invalid value
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -o' should change the keylocation"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file:///$TESTPOOL/pkey"
+
+log_must eval "echo $PASSPHRASE1 | zfs change-key -o keylocation=prompt" \
+ "$TESTPOOL/$TESTFS1"
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "prompt"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo $PASSPHRASE1 | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_mustnot zfs change-key -o keylocation=none $TESTPOOL/$TESTFS1
+log_mustnot zfs change-key -o keylocation=foobar $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key -o' changes the keylocation"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh
new file mode 100755
index 000000000..b1672248b
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_change-key/zfs_change-key_pbkdf2iters.ksh
@@ -0,0 +1,75 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs change-key -o' should change the pbkdf2 iterations.
+#
+# STRATEGY:
+# 1. Create an encryption dataset with 200k PBKDF2 iterations
+# 2. Unmount the dataset
+# 3. Change the PBKDF2 iterations to 150k
+# 4. Verify the PBKDF2 iterations
+# 5. Unload the dataset's key
+# 6. Attempt to load the dataset's key
+#
+
+verify_runnable "both"
+
+function verify_pbkdf2iters
+{
+ typeset ds=$1
+ typeset iterations=$2
+ typeset iters=$(get_prop pbkdf2iters $ds)
+
+ if [[ "$iters" != "$iterations" ]]; then
+ log_fail "Expected $iterations iterations, got $iters"
+ fi
+
+ return 0
+}
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs change-key -o' should change the pbkdf2 iterations"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey -o pbkdf2iters=200000 \
+ $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must verify_pbkdf2iters $TESTPOOL/$TESTFS1 "200000"
+
+log_must zfs change-key -o pbkdf2iters=150000 $TESTPOOL/$TESTFS1
+log_must verify_pbkdf2iters $TESTPOOL/$TESTFS1 "150000"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must zfs load-key $TESTPOOL/$TESTFS1
+
+log_pass "'zfs change-key -o' changes the pbkdf2 iterations"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_clone/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_clone/Makefile.am
index 7c7728c71..78009d504 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_clone/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_clone/Makefile.am
@@ -11,4 +11,5 @@ dist_pkgdata_SCRIPTS = \
zfs_clone_007_pos.ksh \
zfs_clone_008_neg.ksh \
zfs_clone_009_neg.ksh \
- zfs_clone_010_pos.ksh
+ zfs_clone_010_pos.ksh \
+ zfs_clone_encrypted.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh
new file mode 100755
index 000000000..86f335bde
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_clone/zfs_clone_encrypted.ksh
@@ -0,0 +1,83 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs clone' should create encrypted clones of encrypted datasets
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create a snapshot of the dataset
+# 3. Attempt to clone the snapshot as an unencrypted dataset
+# 4. Attempt to clone the snapshot with a new key
+# 5. Attempt to clone the snapshot as a child of an unencrypted dataset
+# 6. Attempt to clone the snapshot as a child of an encrypted dataset
+# 7. Verify the encryption root of the datasets
+# 8. Unmount all datasets and unload their keys
+# 9. Attempt to load the encryption root's key
+# 10. Verify each dataset's key is loaded
+# 11. Attempt to mount each dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs clone' should create encrypted clones of encrypted datasets"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_must zfs snapshot $TESTPOOL/$TESTFS1@now
+
+log_mustnot zfs clone -o encryption=off $TESTPOOL/$TESTFS1@now \
+ $TESTPOOL/$TESTFS2
+log_mustnot eval "echo $PASSPHRASE1 | zfs clone -o keyformat=passphrase" \
+ "$TESTPOOL/$TESTFS1@now $TESTPOOL/$TESTFS2"
+log_must zfs clone $TESTPOOL/$TESTFS1@now $TESTPOOL/$TESTFS2
+log_must zfs clone $TESTPOOL/$TESTFS1@now $TESTPOOL/$TESTFS1/child
+
+log_must verify_encryption_root $TESTPOOL/$TESTFS2 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/$TESTFS1/child $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL/$TESTFS2
+log_must zfs unload-key -a
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+
+log_must key_available $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1/child
+log_must key_available $TESTPOOL/$TESTFS2
+
+log_must zfs mount $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1/child
+log_must zfs mount $TESTPOOL/$TESTFS2
+
+log_pass "'zfs clone' creates encrypted clones of encrypted datasets"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_create/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_create/Makefile.am
index 998c7dca5..dd6dde317 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_create/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_create/Makefile.am
@@ -18,4 +18,6 @@ dist_pkgdata_SCRIPTS = \
zfs_create_011_pos.ksh \
zfs_create_012_pos.ksh \
zfs_create_013_pos.ksh \
- zfs_create_014_pos.ksh
+ zfs_create_014_pos.ksh \
+ zfs_create_encrypted.ksh \
+ zfs_create_crypt_combos.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh
new file mode 100755
index 000000000..d915c5f57
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_crypt_combos.ksh
@@ -0,0 +1,98 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create_common.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/properties.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs create' should create an encrypted dataset with a valid encryption
+# algorithm, key format, key location, and key.
+#
+# STRATEGY:
+# 1. Create a filesystem for each combination of encryption type and key format
+# 2. Verify that each filesystem has the correct properties set
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+set -A ENCRYPTION_ALGS \
+ "encryption=on" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A ENCRYPTION_PROPS \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A KEYFORMATS "keyformat=raw" \
+ "keyformat=hex" \
+ "keyformat=passphrase"
+
+set -A USER_KEYS "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" \
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
+ "abcdefgh"
+
+log_assert "'zfs create' should create encrypted datasets using all" \
+ "combinations of supported properties"
+
+typeset -i i=0
+while (( i < ${#ENCRYPTION_ALGS[*]} )); do
+ typeset -i j=0
+ while (( j < ${#KEYFORMATS[*]} )); do
+ log_must eval "echo -n ${USER_KEYS[j]} | zfs create" \
+ "-o ${ENCRYPTION_ALGS[i]} -o ${KEYFORMATS[j]}" \
+ "$TESTPOOL/$TESTFS1"
+
+ datasetexists $TESTPOOL/$TESTFS1 || \
+ log_fail "Failed to create dataset using" \
+ "${ENCRYPTION_ALGS[i]} and ${KEYFORMATS[j]}"
+
+ propertycheck $TESTPOOL/$TESTFS1 ${ENCRYPTION_PROPS[i]} || \
+ log_fail "failed to set ${ENCRYPTION_ALGS[i]}"
+ propertycheck $TESTPOOL/$TESTFS1 ${KEYFORMATS[j]} || \
+ log_fail "failed to set ${KEYFORMATS[j]}"
+
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+ (( j = j + 1 ))
+ done
+ (( i = i + 1 ))
+done
+
+log_pass "'zfs create' creates encrypted datasets using all combinations of" \
+ "supported properties"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh
new file mode 100755
index 000000000..9d5ecab0d
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh
@@ -0,0 +1,134 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create_common.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/properties.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# ZFS should create datasets only if they have a valid combination of
+# encryption properties set.
+#
+# penc = parent encrypted
+# enc = encryption
+# loc = keylocation provided
+# fmt = keyformat provided
+#
+# penc enc fmt loc valid notes
+# -------------------------------------------
+# no unspec 0 0 yes inherit no encryption (not tested here)
+# no unspec 0 1 no no crypt specified
+# no unspec 1 0 no no crypt specified
+# no unspec 1 1 no no crypt specified
+# no off 0 0 yes explicit no encryption
+# no off 0 1 no keylocation given, but crypt off
+# no off 1 0 no keyformat given, but crypt off
+# no off 1 1 no keyformat given, but crypt off
+# no on 0 0 no no keyformat specified for new key
+# no on 0 1 no no keyformat specified for new key
+# no on 1 0 yes new encryption root
+# no on 1 1 yes new encryption root
+# yes unspec 0 0 yes inherit encryption
+# yes unspec 0 1 no no keyformat specified
+# yes unspec 1 0 yes new encryption root, crypt inherited
+# yes unspec 1 1 yes new encryption root, crypt inherited
+# yes off 0 0 no unencrypted child of encrypted parent
+# yes off 0 1 no unencrypted child of encrypted parent
+# yes off 1 0 no unencrypted child of encrypted parent
+# yes off 1 1 no unencrypted child of encrypted parent
+# yes on 0 0 yes inherited encryption, local crypt
+# yes on 0 1 no no keyformat specified for new key
+# yes on 1 0 yes new encryption root
+# yes on 1 1 yes new encryption root
+#
+# STRATEGY:
+# 1. Attempt to create a dataset using all combinations of encryption
+# properties
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+}
+log_onexit cleanup
+
+log_assert "ZFS should create datasets only if they have a valid" \
+ "combination of encryption properties set."
+
+# Unencrypted parent
+log_must zfs create $TESTPOOL/$TESTFS1
+log_mustnot zfs create -o keyformat=passphrase $TESTPOOL/$TESTFS1/c1
+log_mustnot zfs create -o keylocation=prompt $TESTPOOL/$TESTFS1/c1
+log_mustnot zfs create -o keyformat=passphrase -o keylocation=prompt \
+ $TESTPOOL/$TESTFS1/c1
+
+log_must zfs create -o encryption=off $TESTPOOL/$TESTFS1/c1
+log_mustnot zfs create -o encryption=off -o keylocation=prompt \
+ $TESTPOOL/$TESTFS1/c2
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ $TESTPOOL/$TESTFS1/c2
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ -o keylocation=prompt $TESTPOOL/$TESTFS1/c2
+
+log_mustnot zfs create -o encryption=on $TESTPOOL/$TESTFS1/c2
+log_mustnot zfs create -o encryption=on -o keylocation=prompt \
+ $TESTPOOL/$TESTFS1/c2
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1/c3"
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1/c4"
+
+# Encrypted parent
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2"
+
+log_must zfs create $TESTPOOL/$TESTFS2/c1
+log_mustnot zfs create -o keylocation=prompt $TESTPOOL/$TESTFS2/c2
+log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \
+ "$TESTPOOL/$TESTFS2/c3"
+log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \
+ "-o keylocation=prompt $TESTPOOL/$TESTFS2/c4"
+
+log_mustnot zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5
+log_mustnot zfs create -o encryption=off -o keylocation=prompt \
+ $TESTPOOL/$TESTFS2/c5
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ $TESTPOOL/$TESTFS2/c5
+log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
+ -o keylocation=prompt $TESTPOOL/$TESTFS2/c5
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "$TESTPOOL/$TESTFS2/c5"
+log_mustnot zfs create -o encryption=on -o keylocation=prompt \
+ $TESTPOOL/$TESTFS2/c6
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c6"
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c7"
+
+log_pass "ZFS creates datasets only if they have a valid combination of" \
+ "encryption properties set."
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am
new file mode 100644
index 000000000..1de907168
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/Makefile.am
@@ -0,0 +1,12 @@
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zfs_load-key
+dist_pkgdata_SCRIPTS = \
+ zfs_load-key.cfg \
+ setup.ksh \
+ cleanup.ksh \
+ zfs_load-key_common.kshlib \
+ zfs_load-key.ksh \
+ zfs_load-key_all.ksh \
+ zfs_load-key_file.ksh \
+ zfs_load-key_location.ksh \
+ zfs_load-key_noop.ksh \
+ zfs_load-key_recursive.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh
new file mode 100755
index 000000000..79cd6e9f9
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/cleanup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh
new file mode 100755
index 000000000..6a9af3bc2
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/setup.ksh
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+DISK=${DISKS%% *}
+
+default_setup $DISK
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg
new file mode 100644
index 000000000..90d9f63f1
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+
+export PASSPHRASE="password"
+export PASSPHRASE1="password1"
+export PASSPHRASE2="password2"
+export HEXKEY="000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"
+export HEXKEY1="201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A090807060504030201"
+export RAWKEY="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+export RAWKEY1="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh
new file mode 100755
index 000000000..847a6aabd
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key.ksh
@@ -0,0 +1,85 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key' should only load a key for an unloaded encrypted dataset.
+#
+# STRATEGY:
+# 1. Attempt to load the default dataset's key
+# 2. Unmount the dataset
+# 3. Attempt to load the default dataset's key
+# 4. Create an encrypted dataset
+# 5. Unmount the dataset and unload its key
+# 6. Attempt to load the dataset's key
+# 7. Verify the dataset's key is loaded
+# 8. Attempt to load the dataset's key again
+# 9. Create an encrypted pool
+# 10. Unmount the pool and unload its key
+# 11. Attempt to load the pool's key
+# 12. Verify the pool's key is loaded
+# 13. Attempt to load the pool's key again
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+ poolexists $TESTPOOL1 && log_must destroy_pool $TESTPOOL1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key' should only load the key for an" \
+ "unloaded encrypted dataset"
+
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS"
+
+log_must zfs unmount $TESTPOOL/$TESTFS
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+
+typeset DISK2="$(echo $DISKS | awk '{ print $2 }')"
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL1 $DISK2"
+
+log_must zfs unmount $TESTPOOL1
+log_must zfs unload-key $TESTPOOL1
+
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL1"
+log_must key_available $TESTPOOL1
+
+log_mustnot eval "echo $PASSPHRASE | zfs load-key $TESTPOOL1"
+
+log_pass "'zfs load-key' only loads the key for an unloaded encrypted dataset"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh
new file mode 100755
index 000000000..5e331fd12
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_all.ksh
@@ -0,0 +1,77 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -a' should load keys for all datasets.
+#
+# STRATEGY:
+# 1. Create an encrypted filesystem, encrypted zvol, and an encrypted pool
+# 2. Unmount all datasets and unload their keys
+# 3. Attempt to load all dataset keys
+# 4. Verify each dataset has its key loaded
+# 5. Attempt to mount the pool and filesystem
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/zvol && log_must zfs destroy $TESTPOOL/zvol
+ poolexists $TESTPOOL1 && log_must destroy_pool $TESTPOOL1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -a' should load keys for all datasets"
+
+log_must eval "echo $PASSPHRASE1 > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs create -V 64M -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/zvol
+
+typeset DISK2="$(echo $DISKS | awk '{ print $2}')"
+log_must zpool create -O encryption=on -O keyformat=passphrase \
+ -O keylocation=file:///$TESTPOOL/pkey $TESTPOOL1 $DISK2
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs unload-key $TESTPOOL/zvol
+
+log_must zfs unmount $TESTPOOL1
+log_must zfs unload-key $TESTPOOL1
+
+log_must zfs load-key -a
+
+log_must key_available $TESTPOOL1
+log_must key_available $TESTPOOL/zvol
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_must zfs mount $TESTPOOL1
+log_must zfs mount $TESTPOOL/$TESTFS1
+
+log_pass "'zfs load-key -a' loads keys for all datasets"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
new file mode 100644
index 000000000..627b68267
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
@@ -0,0 +1,102 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key.cfg
+
+# Return 0 is a dataset key is available, 1 otherwise
+#
+# $1 - dataset
+#
+function key_available
+{
+ typeset ds=$1
+
+ datasetexists $ds || return 1
+
+ typeset val=$(get_prop keystatus $ds)
+ if [[ "$val" == "none" ]]; then
+ log_note "Dataset $ds is not encrypted"
+ elif [[ "$val" == "available" ]]; then
+ return 0
+ fi
+
+ return 1
+}
+
+function key_unavailable
+{
+ key_available $1 && return 1
+ return 0
+}
+
+function verify_keyformat
+{
+ typeset ds=$1
+ typeset format=$2
+ typeset fmt=$(get_prop keyformat $ds)
+
+ if [[ "$fmt" != "$format" ]]; then
+ log_fail "Expected keyformat $format, got $fmt"
+ fi
+
+ return 0
+}
+
+function verify_keylocation
+{
+ typeset ds=$1
+ typeset location=$2
+ typeset keyloc=$(get_prop keylocation $ds)
+
+ if [[ "$keyloc" != "$location" ]]; then
+ log_fail "Expected keylocation $location, got $keyloc"
+ fi
+
+ return 0
+}
+
+function verify_encryption_root
+{
+ typeset ds=$1
+ typeset val=$2
+ typeset eroot=$(get_prop encryptionroot $ds)
+
+ if [[ "$eroot" != "$val" ]]; then
+ log_note "Expected encryption root '$val', got '$eroot'"
+ return 1
+ fi
+
+ return 0
+}
+
+function verify_origin
+{
+ typeset ds=$1
+ typeset val=$2
+ typeset orig=$(get_prop origin $ds)
+
+ if [[ "$orig" != "$val" ]]; then
+ log_note "Expected origin '$val', got '$orig'"
+ return 1
+ fi
+
+ return 0
+}
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh
new file mode 100755
index 000000000..7cbda43ff
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_file.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key' should load a dataset's key from a file.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset with a key file
+# 2. Unmount the dataset and unload the key
+# 3. Attempt to load the dataset's key
+# 4. Verify the key is loaded
+# 5. Attempt to mount the dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key' should load a key from a file"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs load-key $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1
+
+log_pass "'zfs load-key' loads a key from a file"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh
new file mode 100755
index 000000000..d0b1cdb20
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_location.ksh
@@ -0,0 +1,73 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -L' should override keylocation with provided value.
+#
+# STRATEGY:
+# 1. Create a key file
+# 2. Copy the key file to another location
+# 3. Create an encrypted dataset using the keyfile
+# 4. Unmount the dataset and unload its key
+# 5. Attempt to load the dataset specifying a keylocation of file
+# 6. Verify the key is loaded
+# 7. Verify the keylocation is the original key file
+# 8. Unload the dataset's key
+# 9. Attempt to load the dataset specifying a keylocation of prompt
+# 10. Verify the key is loaded
+# 11. Verify the keylocation is the original key file
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -L' should override keylocation with provided value"
+
+typeset key_location="/$TESTPOOL/pkey1"
+
+log_must eval "echo $PASSPHRASE > $key_location"
+log_must cp $key_location /$TESTPOOL/pkey2
+
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file://$key_location $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs load-key -L file:///$TESTPOOL/pkey2 $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file://$key_location"
+
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "echo $PASSPHRASE | zfs load-key -L prompt $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file://$key_location"
+
+log_pass "'zfs load-key -L' overrides keylocation with provided value"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh
new file mode 100755
index 000000000..bfce78644
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_noop.ksh
@@ -0,0 +1,54 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -n' should load the key for an already loaded dataset.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Attempt to load the dataset's key
+# 3. Verify the key is loaded
+# 4. Attempt to load the dataset's key with an invalid key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -n' should load the key for a loaded dataset"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+
+log_must eval "echo $PASSPHRASE | zfs load-key -n $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_mustnot eval "echo $PASSPHRASE1 | zfs load-key -n $TESTPOOL/$TESTFS1"
+
+log_pass "'zfs load-key -n' loads the key for a loaded dataset"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh
new file mode 100755
index 000000000..7385b69cf
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_load-key/zfs_load-key_recursive.ksh
@@ -0,0 +1,66 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs load-key -r' should recursively load keys.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create a child dataset as an encryption root
+# 3. Unmount all datasets and unload their keys
+# 4. Attempt to load all dataset keys
+# 5. Verify each dataset has its key loaded
+# 6. Attempt to mount each dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs load-key -r' should recursively load keys"
+
+log_must eval "echo $PASSPHRASE1 > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs create -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1/child
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must zfs load-key -r $TESTPOOL
+log_must key_available $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1/child
+
+log_must zfs mount $TESTPOOL/$TESTFS1
+log_must zfs mount $TESTPOOL/$TESTFS1/child
+
+log_pass "'zfs load-key -r' recursively loads keys"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/Makefile.am
index f26120e2f..5b9bb937c 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/Makefile.am
@@ -16,4 +16,5 @@ dist_pkgdata_SCRIPTS = \
zfs_mount_010_neg.ksh \
zfs_mount_011_neg.ksh \
zfs_mount_012_neg.ksh \
+ zfs_mount_encrypted.ksh \
zfs_mount_all_001_pos.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh
new file mode 100755
index 000000000..e81d6f2a5
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_encrypted.ksh
@@ -0,0 +1,62 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs mount -l' should accept a valid key as it mounts the filesystem.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Unmount and unload the dataset's key
+# 3. Verify the key is unloaded
+# 4. Attempt to load the key while mounting the dataset
+# 5. Verify the key is loaded
+# 6. Verify the dataset is mounted
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -f $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "'zfs mount -l' should properly load a valid wrapping key"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1
+
+log_must eval "echo $PASSPHRASE | zfs mount -l $TESTPOOL/$TESTFS1"
+log_must key_available $TESTPOOL/$TESTFS1
+
+mounted $TESTPOOL/$TESTFS1 || \
+ log_fail "Filesystem $TESTPOOL/$TESTFS1 is unmounted"
+
+log_pass "'zfs mount -l' properly loads a valid wrapping key"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_promote/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_promote/Makefile.am
index fa0eae744..d51f222fe 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_promote/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_promote/Makefile.am
@@ -10,4 +10,5 @@ dist_pkgdata_SCRIPTS = \
zfs_promote_005_pos.ksh \
zfs_promote_006_neg.ksh \
zfs_promote_007_neg.ksh \
- zfs_promote_008_pos.ksh
+ zfs_promote_008_pos.ksh \
+ zfs_promote_encryptionroot.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh
new file mode 100755
index 000000000..336c7b253
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_promote/zfs_promote_encryptionroot.ksh
@@ -0,0 +1,80 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# ZFS must promote clones of an encryption root.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Clone the encryption root
+# 3. Clone the clone
+# 4. Verify the encryption root of all three datasets is the origin
+# 5. Promote the clone of the clone
+# 6. Verify the encryption root of all three datasets is still the origin
+# 7. Promote the clone of the original encryption root
+# 8. Verify the encryption root of all three datasets is the promoted dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -Rf $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/clone1 && \
+ log_must zfs destroy -Rf $TESTPOOL/clone1
+ datasetexists $TESTPOOL/clone2 && \
+ log_must zfs destroy -Rf $TESTPOOL/clone2
+}
+log_onexit cleanup
+
+log_assert "ZFS must promote clones of an encryption root"
+
+passphrase="password"
+snaproot="$TESTPOOL/$TESTFS1@snap1"
+snapclone="$TESTPOOL/clone1@snap2"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs snap $snaproot
+log_must zfs clone $snaproot $TESTPOOL/clone1
+log_must zfs snap $snapclone
+log_must zfs clone $snapclone $TESTPOOL/clone2
+
+log_must verify_encryption_root $TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone2 $TESTPOOL/$TESTFS1
+
+log_must zfs promote $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone1 $TESTPOOL/$TESTFS1
+log_must verify_encryption_root $TESTPOOL/clone2 $TESTPOOL/$TESTFS1
+
+log_must zfs promote $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/$TESTFS1 $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/clone1 $TESTPOOL/clone2
+log_must verify_encryption_root $TESTPOOL/clone2 $TESTPOOL/clone2
+
+log_pass "ZFS promotes clones of an encryption root"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/Makefile.am
index 87e543b00..2d9f0e5ff 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/Makefile.am
@@ -17,4 +17,8 @@ dist_pkgdata_SCRIPTS = \
zfs_receive_013_pos.ksh \
zfs_receive_014_pos.ksh \
zfs_receive_015_pos.ksh \
- receive-o-x_props_override.ksh
+ receive-o-x_props_override.ksh \
+ zfs_receive_from_encrypted.ksh \
+ zfs_receive_to_encrypted.ksh \
+ zfs_receive_raw.ksh \
+ zfs_receive_raw_incremental.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh
index aee38d254..878189baf 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/setup.ksh
@@ -28,6 +28,7 @@
. $STF_SUITE/include/libtest.shlib
DISK=${DISKS%% *}
+
if is_global_zone; then
default_volume_setup $DISK
else
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh
new file mode 100755
index 000000000..5eee9eecf
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_from_encrypted.ksh
@@ -0,0 +1,83 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive an unencrypted stream from an encrypted dataset
+#
+# STRATEGY:
+# 1. Create an unencrypted dataset
+# 2. Create an encrypted dataset
+# 3. Create and checksum a file on the encrypted dataset
+# 4. Snapshot the encrypted dataset
+# 5. Attempt to receive the snapshot into an unencrypted child
+# 6. Verify encryption is not enabled
+# 7. Verify the cheksum of the file is the same as the original
+# 8. Attempt to receive the snapshot into an encrypted child
+# 9. Verify the cheksum of the file is the same as the original
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive an unencrypted stream from an encrypted dataset"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS2@snap"
+
+log_must zfs create $TESTPOOL/$TESTFS1
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2"
+
+log_must mkfile 1M /$TESTPOOL/$TESTFS2/$TESTFILE0
+typeset checksum=$(md5sum /$TESTPOOL/$TESTFS2/$TESTFILE0 | awk '{ print $1 }')
+
+log_must zfs snapshot $snap
+
+log_note "Verify ZFS can receive into an unencrypted child"
+log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
+
+crypt=$(get_prop encryption $TESTPOOL/$TESTFS1/c1)
+[[ "$crypt" == "off" ]] || log_fail "Received unencrypted stream as encrypted"
+
+typeset cksum1=$(md5sum /$TESTPOOL/$TESTFS1/c1/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum1" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum1 != $checksum)"
+
+log_note "Verify ZFS can receive into an encrypted child"
+log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS2/c1"
+
+typeset cksum2=$(md5sum /$TESTPOOL/$TESTFS2/c1/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum2" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum2 != $checksum)"
+
+log_pass "ZFS can receive an unencrypted stream from an encrypted dataset"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh
new file mode 100755
index 000000000..2042b37a9
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw.ksh
@@ -0,0 +1,93 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive streams from raw sends.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Create a file and get its checksum
+# 3. Snapshot the dataset
+# 4. Attempt to receive a raw send stream as a child of an unencrypted dataset
+# 5. Verify the key is unavailable
+# 6. Attempt to load the key and mount the dataset
+# 7. Verify the cheksum of the file is the same as the original
+# 8. Attempt to receive a raw send stream as a child of an encrypted dataset
+# 9. Verify the key is unavailable
+# 10. Attempt to load the key and mount the dataset
+# 11. Verify the cheksum of the file is the same as the original
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive streams from raw sends"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must mkfile 1M /$TESTPOOL/$TESTFS1/$TESTFILE0
+typeset checksum=$(md5sum /$TESTPOOL/$TESTFS1/$TESTFILE0 | \
+ awk '{ print $1 }')
+
+log_must zfs snapshot $snap
+
+log_note "Verify ZFS can receive a raw send stream from an encrypted dataset"
+log_must eval "zfs send -w $snap | zfs receive $TESTPOOL/$TESTFS2"
+
+keystatus=$(get_prop keystatus $TESTPOOL/$TESTFS2)
+[[ "$keystatus" == "unavailable" ]] || \
+ log_fail "Expected keystatus unavailable, got $keystatus"
+
+log_must eval "echo $passphrase | zfs mount -l $TESTPOOL/$TESTFS2"
+
+typeset cksum1=$(md5sum /$TESTPOOL/$TESTFS2/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum1" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum1 != $checksum)"
+
+log_must eval "zfs send -w $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
+
+keystatus=$(get_prop keystatus $TESTPOOL/$TESTFS1/c1)
+[[ "$keystatus" == "unavailable" ]] || \
+ log_fail "Expected keystatus unavailable, got $keystatus"
+
+log_must eval "echo $passphrase | zfs mount -l $TESTPOOL/$TESTFS1/c1"
+typeset cksum2=$(md5sum /$TESTPOOL/$TESTFS1/c1/$TESTFILE0 | \
+ awk '{ print $1 }')
+[[ "$cksum2" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum2 != $checksum)"
+
+log_pass "ZFS can receive streams from raw sends"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh
new file mode 100755
index 000000000..c813809a0
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_raw_incremental.ksh
@@ -0,0 +1,75 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive streams from raw incremental sends.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Snapshot the dataset
+# 3. Create a file and get its checksum
+# 4. Snapshot the dataset
+# 5. Attempt to receive a raw send stream of the first snapshot
+# 6. Attempt to receive a raw incremental send stream of the second snapshot
+# 7. Attempt load the key and mount the dataset
+# 8. Verify the cheksum of the file is the same as the original
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive streams from raw incremental sends"
+
+typeset passphrase="password"
+typeset snap1="$TESTPOOL/$TESTFS1@snap1"
+typeset snap2="$TESTPOOL/$TESTFS1@snap2"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs snapshot $snap1
+
+log_must mkfile 1M /$TESTPOOL/$TESTFS1/$TESTFILE0
+typeset checksum=$(md5sum /$TESTPOOL/$TESTFS1/$TESTFILE0 | awk '{ print $1 }')
+
+log_must zfs snapshot $snap2
+
+log_must eval "zfs send -w $snap1 | zfs receive $TESTPOOL/$TESTFS2"
+log_must eval "zfs send -w -i $snap1 $snap2 | zfs receive $TESTPOOL/$TESTFS2"
+log_must eval "echo $passphrase | zfs mount -l $TESTPOOL/$TESTFS2"
+
+typeset cksum1=$(md5sum /$TESTPOOL/$TESTFS2/$TESTFILE0 | awk '{ print $1 }')
+[[ "$cksum1" == "$checksum" ]] || \
+ log_fail "Checksums differ ($cksum1 != $checksum)"
+
+log_pass "ZFS can receive streams from raw incremental sends"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
new file mode 100755
index 000000000..57896c6fd
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
@@ -0,0 +1,75 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should receive to an encrypted child dataset.
+#
+# STRATEGY:
+# 1. Snapshot the default dataset
+# 2. Create an encrypted dataset
+# 3. Attempt to receive a stream to an encrypted child
+# 4. Attempt to receive a stream with properties to an encrypted child
+# 5. Attempt to receive a replication stream to an encrypted child
+# 6. Unmount and unload the encrypted dataset keys
+# 7. Attempt to receive a snapshot stream to an encrypted child
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ snapexists $snap && log_must_busy zfs destroy -f $snap
+
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should receive to an encrypted child dataset"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS@snap"
+typeset testfile="testfile"
+
+log_must zfs snapshot $snap
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_note "Verifying ZFS will receive to an encrypted child"
+log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
+
+log_note "Verifying 'send -p' will not receive to an encrypted child"
+log_mustnot eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2"
+
+log_note "Verifying 'send -R' will not receive to an encrypted child"
+log_mustnot eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3"
+
+log_note "Verifying ZFS will not receive to an encrypted child when the" \
+ "parent key is unloaded"
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_mustnot eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c4"
+
+log_pass "ZFS can receive to an encrypted child dataset"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_rename/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_rename/Makefile.am
index fec9560c5..dfef661b7 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_rename/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_rename/Makefile.am
@@ -16,4 +16,6 @@ dist_pkgdata_SCRIPTS = \
zfs_rename_010_neg.ksh \
zfs_rename_011_pos.ksh \
zfs_rename_012_neg.ksh \
- zfs_rename_013_pos.ksh
+ zfs_rename_013_pos.ksh \
+ zfs_rename_encrypted_child.ksh \
+ zfs_rename_to_encrypted.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh
new file mode 100755
index 000000000..fa57658f1
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_encrypted_child.ksh
@@ -0,0 +1,78 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs rename' should not move an encrypted child dataset outside of its
+# encryption root.
+#
+# STRATEGY:
+# 1. Create two encryption roots, and a child and grandchild of the first
+# encryption root
+# 2. Attempt to rename the grandchild under an unencrypted parent
+# 3. Attempt to rename the grandchild under a different encrypted parent
+# 4. Attempt to rename the grandchild under the current parent
+# 5. Verify the encryption root of the dataset
+# 6. Attempt to rename the grandchild to a child
+# 7. Verify the encryption root of the dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
+ datasetexists $TESTPOOL/$TESTFS3 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS3
+}
+log_onexit cleanup
+
+log_assert "'zfs rename' should not move an encrypted child outside of its" \
+ "encryption root"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2"
+log_must zfs create $TESTPOOL/$TESTFS2/child
+log_must zfs create $TESTPOOL/$TESTFS2/child/grandchild
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS3"
+
+log_mustnot zfs rename $TESTPOOL/$TESTFS2/child/grandchild \
+ $TESTPOOL/grandchild
+
+log_mustnot zfs rename $TESTPOOL/$TESTFS2/child/grandchild \
+ $TESTPOOL/$TESTFS3/grandchild
+
+log_must zfs rename $TESTPOOL/$TESTFS2/child/grandchild \
+ $TESTPOOL/$TESTFS2/child/grandchild2
+log_must verify_encryption_root $TESTPOOL/$TESTFS2/child/grandchild2 \
+ $TESTPOOL/$TESTFS2
+
+log_must zfs rename $TESTPOOL/$TESTFS2/child/grandchild2 \
+ $TESTPOOL/$TESTFS2/grandchild2
+log_must verify_encryption_root $TESTPOOL/$TESTFS2/grandchild2 \
+ $TESTPOOL/$TESTFS2
+
+log_pass "'zfs rename' does not move an encrypted child outside of its" \
+ "encryption root"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh
new file mode 100755
index 000000000..400592aac
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh
@@ -0,0 +1,51 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs rename' should not rename an unencrypted dataset to a child
+# of an encrypted dataset
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Attempt to rename the default dataset to a child of the encrypted dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS2
+}
+log_onexit cleanup
+
+log_assert "'zfs rename' should not rename an unencrypted dataset to a" \
+ "child of an encrypted dataset"
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2"
+log_mustnot zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS
+
+log_pass "'zfs rename' does not rename an unencrypted dataset to a child" \
+ "of an encrypted dataset"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am
index 13faeab1d..08ab72a3d 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_send/Makefile.am
@@ -9,4 +9,6 @@ dist_pkgdata_SCRIPTS = \
zfs_send_004_neg.ksh \
zfs_send_005_pos.ksh \
zfs_send_006_pos.ksh \
- zfs_send_007_pos.ksh
+ zfs_send_007_pos.ksh \
+ zfs_send_encrypted.ksh \
+ zfs_send_raw.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh
new file mode 100755
index 000000000..490e146ba
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted.ksh
@@ -0,0 +1,76 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should perform unencrypted sends of encrypted datasets, unless the '-p'
+# or '-R' options are specified.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 6. Create a child encryption root
+# 2. Snapshot the dataset
+# 3. Attempt a send
+# 4. Attempt a send with properties
+# 5. Attempt a replication send
+# 7. Unmount the parent and unload its key
+# 8. Attempt a send of the parent dataset
+# 9. Attempt a send of the child encryption root
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should perform unencrypted sends of encrypted datasets, " \
+ "unless the '-p' or '-R' options are specified"
+
+typeset passphrase="password"
+typeset passphrase1="password1"
+typeset snap="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must eval "echo $passphrase1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1/child"
+
+log_must zfs snapshot -r $snap
+
+log_must eval "zfs send $snap > /dev/null"
+log_mustnot eval "zfs send -p $snap > /dev/null"
+log_mustnot eval "zfs send -R $snap > /dev/null"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_mustnot eval "zfs send $snap > /dev/null"
+log_must eval "zfs send $TESTPOOL/$TESTFS1/child@snap > /dev/null"
+
+log_pass "ZFS performs unencrypted sends of encrypted datasets, unless the" \
+ "'-p' or '-R' options are specified"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh
new file mode 100755
index 000000000..112ee1143
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_encrypted_unloaded.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should not perform unencrypted sends from encrypted datasets
+# with unloaded keys.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Snapshot the dataset
+# 3. Unload the dataset key
+# 4. Verify sending the stream fails
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should not perform unencrypted sends from encrypted datasets" \
+ "with unloaded keys."
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+log_must zfs snapshot $snap
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_mustnot eval "zfs send $snap > /dev/null"
+
+log_pass "ZFS does not perform unencrypted sends from encrypted datasets" \
+ "with unloaded keys."
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh
new file mode 100755
index 000000000..85cc7407e
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_raw.ksh
@@ -0,0 +1,79 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# ZFS should perform raw sends of datasets.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Snapshot the default dataset and the encrypted dataset
+# 3. Attempt a raw send of both datasets
+# 4. Attempt a raw send with properties of both datasets
+# 5. Attempt a raw replication send of both datasets
+# 6. Unmount and unload the encrypted dataset key
+# 7. Attempt a raw send of the encrypted dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ snapexists $snap && \
+ log_must zfs destroy $snap
+
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+
+log_onexit cleanup
+
+log_assert "ZFS should perform raw sends of datasets"
+
+typeset passphrase="password"
+typeset snap="$TESTPOOL/$TESTFS@snap"
+typeset snap1="$TESTPOOL/$TESTFS1@snap"
+
+log_must eval "echo $passphrase | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+
+log_must zfs snapshot $snap
+log_must zfs snapshot $snap1
+
+log_must eval "zfs send -w $snap > /dev/null"
+log_must eval "zfs send -w $snap1 > /dev/null"
+
+log_note "Verify ZFS can perform raw sends with properties"
+log_must eval "zfs send -wp $snap > /dev/null"
+log_must eval "zfs send -wp $snap1 > /dev/null"
+
+log_note "Verify ZFS can perform raw replication sends"
+log_must eval "zfs send -wR $snap > /dev/null"
+log_must eval "zfs send -wR $snap1 > /dev/null"
+
+log_note "Verify ZFS can perform a raw send of an encrypted datasets with" \
+ "its key unloaded"
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must eval "zfs send -w $snap1 > /dev/null"
+
+log_pass "ZFS performs raw sends of datasets"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_set/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_set/Makefile.am
index f47ff1094..2a9e858e0 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_set/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_set/Makefile.am
@@ -28,4 +28,5 @@ dist_pkgdata_SCRIPTS = \
version_001_neg.ksh \
zfs_set_001_neg.ksh \
zfs_set_002_neg.ksh \
- zfs_set_003_neg.ksh
+ zfs_set_003_neg.ksh \
+ zfs_set_keylocation.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh
index 312638d62..969238599 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_set/setup.ksh
@@ -28,4 +28,5 @@
. $STF_SUITE/include/libtest.shlib
DISK=${DISKS%% *}
+
default_container_volume_setup $DISK
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh
new file mode 100755
index 000000000..313fa4e4d
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_keylocation.ksh
@@ -0,0 +1,93 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# Unencrypted datasets should only allow keylocation of 'none', encryption
+# roots should only allow keylocation of 'prompt' and file URI, and encrypted
+# child datasets should not be able to change their keylocation.
+#
+# STRATEGY:
+# 1. Verify the key location of the default dataset is 'none'
+# 2. Attempt to change the key location of the default dataset
+# 3. Create an encrypted dataset using a key file
+# 4. Attempt to change the key location of the encrypted dataset to 'none',
+# an invalid location, its current location, and 'prompt'
+# 5. Attempt to reload the encrypted dataset key using the new key location
+# 6. Create a encrypted child dataset
+# 7. Verify the key location of the child dataset is 'none'
+# 8. Attempt to change the key location of the child dataset
+# 9. Verify the key location of the child dataset has not changed
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "Key location can only be 'prompt' or a file path for encryption" \
+ "roots, and 'none' for unencrypted volumes"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+
+log_must verify_keylocation $TESTPOOL/$TESTFS "none"
+log_must zfs set keylocation=none $TESTPOOL/$TESTFS
+log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS
+log_mustnot zfs set keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS
+log_must verify_keylocation $TESTPOOL/$TESTFS "none"
+
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_mustnot zfs set keylocation=none $TESTPOOL/$TESTFS1
+log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+
+log_must zfs set keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "file:///$TESTPOOL/pkey"
+
+log_must zfs set keylocation=prompt $TESTPOOL/$TESTFS1
+log_must verify_keylocation $TESTPOOL/$TESTFS1 "prompt"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+
+log_must rm /$TESTPOOL/pkey
+log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS1"
+log_must zfs mount $TESTPOOL/$TESTFS1
+
+log_must zfs create $TESTPOOL/$TESTFS1/child
+log_must verify_keylocation $TESTPOOL/$TESTFS1/child "none"
+
+log_mustnot zfs set keylocation=none $TESTPOOL/$TESTFS1/child
+log_mustnot zfs set keylocation=prompt $TESTPOOL/$TESTFS1/child
+log_mustnot zfs set keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+log_mustnot zfs set keylocation=/$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+
+log_must verify_keylocation $TESTPOOL/$TESTFS1/child "none"
+
+log_pass "Key location can only be 'prompt' or a file path for encryption" \
+ "roots, and 'none' for unencrypted volumes"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile.am
new file mode 100644
index 000000000..74cdf5c2b
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/Makefile.am
@@ -0,0 +1,7 @@
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zfs_unload-key
+dist_pkgdata_SCRIPTS = \
+ setup.ksh \
+ cleanup.ksh \
+ zfs_unload-key.ksh \
+ zfs_unload-key_all.ksh \
+ zfs_unload-key_recursive.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh
new file mode 100755
index 000000000..79cd6e9f9
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/cleanup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh
new file mode 100755
index 000000000..6a9af3bc2
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/setup.ksh
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+DISK=${DISKS%% *}
+
+default_setup $DISK
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh
new file mode 100755
index 000000000..9e08ac69d
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key.ksh
@@ -0,0 +1,69 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs unload-key' should only unload the key of an unmounted dataset.
+#
+# STRATEGY:
+# 1. Attempt to unload the default dataset's key
+# 2. Unmount the dataset
+# 3. Attempt to unload the default dataset's key
+# 4. Create an encrypted dataset
+# 5. Attempt to unload the dataset's key
+# 6. Verify the key is loaded
+# 7. Unmount the dataset
+# 8. Attempt to unload the dataset's key
+# 9. Verify the key is not loaded
+# 10. Attempt to unload the dataset's key
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs unload-key' should unload the key for an unmounted" \
+ "encrypted dataset"
+
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS
+
+log_must zfs unmount $TESTPOOL/$TESTFS
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS
+
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS1
+log_must key_available $TESTPOOL/$TESTFS1
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1
+
+log_mustnot zfs unload-key $TESTPOOL/$TESTFS1
+
+log_pass "'zfs unload-key' unloads the key for an unmounted encrypted dataset"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh
new file mode 100755
index 000000000..ecb98d189
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_all.ksh
@@ -0,0 +1,76 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs unload-key -a' should unload keys for all datasets.
+#
+# STRATEGY:
+# 1. Create an encrypted filesystem, encrypted child dataset, an encrypted
+# zvol, and an encrypted pool
+# 2. Unmount all datasets
+# 3. Attempt to unload all dataset keys
+# 4. Verify each dataset has its key unloaded
+# 5. Attempt to mount each dataset
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+ datasetexists $TESTPOOL/zvol && log_must zfs destroy $TESTPOOL/zvol
+ poolexists $TESTPOOL1 && log_must destroy_pool $TESTPOOL1
+}
+log_onexit cleanup
+
+log_assert "'zfs unload-key -a' should unload keys for all datasets"
+
+log_must eval "echo $PASSPHRASE1 > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must zfs create $TESTPOOL/$TESTFS1/child
+
+log_must zfs create -V 64M -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/zvol
+
+typeset DISK2="$(echo $DISKS | awk '{ print $2}')"
+log_must zpool create -O encryption=on -O keyformat=passphrase \
+ -O keylocation=file:///$TESTPOOL/pkey $TESTPOOL1 $DISK2
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL1
+
+log_must zfs unload-key -a
+
+log_must key_unavailable $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+log_must key_unavailable $TESTPOOL/zvol
+log_must key_unavailable $TESTPOOL1
+
+log_mustnot zfs mount $TESTPOOL
+log_mustnot zfs mount $TESTPOOL/zvol
+log_mustnot zfs mount $TESTPOOL/$TESTFS1
+
+log_pass "'zfs unload-key -a' unloads keys for all datasets"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh
new file mode 100755
index 000000000..9766b5905
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unload-key/zfs_unload-key_recursive.ksh
@@ -0,0 +1,72 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zfs unload-key -r' should recursively unload keys.
+#
+# STRATEGY:
+# 1. Create a parent encrypted dataset
+# 2. Create a sibling encrypted dataset
+# 3. Create a child dataset as an encryption root
+# 4. Unmount all datasets
+# 5. Attempt to unload all dataset keys under parent
+# 6. Verify parent and child have their keys unloaded
+# 7. Verify sibling has its key loaded
+# 8. Attempt to mount all datasets
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS1 && \
+ log_must zfs destroy -r $TESTPOOL/$TESTFS1
+}
+log_onexit cleanup
+
+log_assert "'zfs unload-key -r' should recursively unload keys"
+
+log_must eval "echo $PASSPHRASE > /$TESTPOOL/pkey"
+log_must zfs create -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1
+log_must zfs create -o keyformat=passphrase \
+ -o keylocation=file:///$TESTPOOL/pkey $TESTPOOL/$TESTFS1/child
+log_must eval "echo $PASSPHRASE1 | zfs create -o encryption=on" \
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2"
+
+log_must zfs unmount $TESTPOOL/$TESTFS1
+log_must zfs unmount $TESTPOOL/$TESTFS2
+
+log_must zfs unload-key -r $TESTPOOL/$TESTFS1
+
+log_must key_unavailable $TESTPOOL/$TESTFS1
+log_must key_unavailable $TESTPOOL/$TESTFS1/child
+
+log_must key_available $TESTPOOL/$TESTFS2
+
+log_mustnot zfs mount $TESTPOOL/$TESTFS1
+log_mustnot zfs mount $TESTPOOL/$TESTFS1/child
+log_must zfs mount $TESTPOOL/$TESTFS2
+
+log_pass "'zfs unload-key -r' recursively unloads keys"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am
index 5af41e6a3..e2b84bca5 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/Makefile.am
@@ -27,6 +27,8 @@ dist_pkgdata_SCRIPTS = \
zpool_create_022_pos.ksh \
zpool_create_023_neg.ksh \
zpool_create_024_pos.ksh \
+ zpool_create_encrypted.ksh \
+ zpool_create_crypt_combos.ksh \
zpool_create_features_001_pos.ksh \
zpool_create_features_002_pos.ksh \
zpool_create_features_003_pos.ksh \
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh
new file mode 100755
index 000000000..8b7ca4799
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_crypt_combos.ksh
@@ -0,0 +1,89 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool create' should create encrypted pools when using a valid encryption
+# algorithm, key format, key location, and key.
+#
+# STRATEGY:
+# 1. Create a pool for each combination of encryption type and key format
+# 2. Verify that each filesystem has the correct properties set
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+log_onexit cleanup
+
+set -A ENCRYPTION_ALGS "encryption=on" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A ENCRYPTION_PROPS "encryption=aes-256-ccm" \
+ "encryption=aes-128-ccm" \
+ "encryption=aes-192-ccm" \
+ "encryption=aes-256-ccm" \
+ "encryption=aes-128-gcm" \
+ "encryption=aes-192-gcm" \
+ "encryption=aes-256-gcm"
+
+set -A KEYFORMATS "keyformat=raw" \
+ "keyformat=hex" \
+ "keyformat=passphrase"
+
+set -A USER_KEYS "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" \
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
+ "abcdefgh"
+
+log_assert "'zpool create' should create encrypted pools when using a valid" \
+ "encryption algorithm, key format, key location, and key."
+
+typeset -i i=0
+while (( i < ${#ENCRYPTION_ALGS[*]} )); do
+ typeset -i j=0
+ while (( j < ${#KEYFORMATS[*]} )); do
+ log_must eval "echo -n ${USER_KEYS[j]} | zpool create" \
+ "-O ${ENCRYPTION_ALGS[i]} -O ${KEYFORMATS[j]}" \
+ "$TESTPOOL $DISKS"
+
+ propertycheck $TESTPOOL ${ENCRYPTION_PROPS[i]} || \
+ log_fail "failed to set ${ENCRYPTION_ALGS[i]}"
+ propertycheck $TESTPOOL ${KEY_FORMATS[j]} || \
+ log_fail "failed to set ${KEYFORMATS[j]}"
+
+ log_must zpool destroy $TESTPOOL
+ (( j = j + 1 ))
+ done
+ (( i = i + 1 ))
+done
+
+log_pass "'zpool create' creates encrypted pools when using a valid" \
+ "encryption algorithm, key format, key location, and key."
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh
new file mode 100755
index 000000000..aa154d5c6
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh
@@ -0,0 +1,95 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool create' should create an encrypted dataset only if it has a valid
+# combination of encryption properties set.
+#
+# enc = encryption
+# loc = keylocation provided
+# fmt = keyformat provided
+#
+# U = unspecified
+# N = off
+# Y = on
+#
+# enc fmt loc valid notes
+# -------------------------------------------
+# U 0 1 no no crypt specified
+# U 1 0 no no crypt specified
+# U 1 1 no no crypt specified
+# N 0 0 yes explicit no encryption
+# N 0 1 no keylocation given, but crypt off
+# N 1 0 no keyformat given, but crypt off
+# N 1 1 no keyformat given, but crypt off
+# Y 0 0 no no keyformat specified for new key
+# Y 0 1 no no keyformat specified for new key
+# Y 1 0 yes new encryption root
+# Y 1 1 yes new encryption root
+#
+# STRATEGY:
+# 1. Attempt to create a dataset using all combinations of encryption
+# properties
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+log_onexit cleanup
+
+log_assert "'zpool create' should create an encrypted dataset only if it" \
+ "has a valid combination of encryption properties set."
+
+log_mustnot zpool create -O keylocation=prompt $TESTPOOL $DISKS
+log_mustnot zpool create -O keyformat=passphrase $TESTPOOL $DISKS
+log_mustnot zpool create -O keyformat=passphrase -O keylocation=prompt \
+ $TESTPOOL $DISKS
+
+log_must zpool create -O encryption=off $TESTPOOL $DISKS
+log_must zpool destroy $TESTPOOL
+
+log_mustnot zpool create -O encryption=off -O keylocation=prompt \
+ $TESTPOOL $DISKS
+log_mustnot zpool create -O encryption=off -O keyformat=passphrase \
+ $TESTPOOL $DISKS
+log_mustnot zpool create -O encryption=off -O keyformat=passphrase \
+ -O keylocation=prompt $TESTPOOL $DISKS
+
+log_mustnot zpool create -O encryption=on $TESTPOOL $DISKS
+log_mustnot zpool create -O encryption=on -O keylocation=prompt \
+ $TESTPOOL $DISKS
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase $TESTPOOL $DISKS"
+log_must zpool destroy $TESTPOOL
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL $DISKS"
+log_must zpool destroy $TESTPOOL
+
+log_pass "'zpool create' creates an encrypted dataset only if it has a" \
+ "valid combination of encryption properties set."
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg b/tests/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg
index e1537806f..1e184db82 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg
@@ -78,5 +78,6 @@ if is_linux; then
"ashift"
"feature@large_dnode"
"feature@userobj_accounting"
+ "feature@encryption"
)
fi
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am
index c7e5c7590..fab6e7459 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_import/Makefile.am
@@ -24,7 +24,9 @@ dist_pkgdata_SCRIPTS = \
zpool_import_missing_001_pos.ksh \
zpool_import_missing_002_pos.ksh \
zpool_import_missing_003_pos.ksh \
- zpool_import_rename_001_pos.ksh
+ zpool_import_rename_001_pos.ksh \
+ zpool_import_encrypted.ksh \
+ zpool_import_encrypted_load.ksh
BLOCKFILES = \
unclean_export.dat.bz2
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh
new file mode 100755
index 000000000..4e9013afe
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool import' should import a pool with an encrypted dataset without
+# mounting it.
+#
+# STRATEGY:
+# 1. Create an encrypted pool
+# 2. Export the pool
+# 3. Attempt to import the pool
+# 4. Verify the pool exists and the key is not loaded
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ destroy_pool $TESTPOOL1
+ log_must rm $VDEV0
+ log_must mkfile $FILE_SIZE $VDEV0
+}
+log_onexit cleanup
+
+log_assert "'zpool import' should import a pool with an encrypted dataset" \
+ "without mounting it"
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL1 $VDEV0"
+log_must zpool export $TESTPOOL1
+log_must zpool import -d $DEVICE_DIR $TESTPOOL1
+log_must poolexists $TESTPOOL1
+log_must key_unavailable $TESTPOOL1
+log_must unmounted $TESTPOOL1
+
+log_pass "'zpool import' imports a pool with an encrypted dataset without" \
+ "mounting it"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh
new file mode 100755
index 000000000..d060e8a79
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_encrypted_load.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# 'zpool import -l' should import a pool with an encrypted dataset and load
+# its key.
+#
+# STRATEGY:
+# 1. Create an encrypted pool
+# 2. Export the pool
+# 3. Attempt to import the pool with the key
+# 4. Verify the pool exists and the key is loaded
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ destroy_pool $TESTPOOL1
+ log_must rm $VDEV0
+ log_must mkfile $FILE_SIZE $VDEV0
+}
+log_onexit cleanup
+
+log_assert "'zpool import -l' should import a pool with an encrypted dataset" \
+ "and load its key"
+
+log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+ "-O keyformat=passphrase -O keylocation=prompt $TESTPOOL1 $VDEV0"
+log_must zpool export $TESTPOOL1
+log_must eval "echo $PASSPHRASE | zpool import -l -d $DEVICE_DIR $TESTPOOL1"
+log_must poolexists $TESTPOOL1
+log_must key_available $TESTPOOL1
+log_must mounted $TESTPOOL1
+
+log_pass "'zpool import -l' imports a pool with an encrypted dataset and" \
+ "loads its key"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_scrub/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zpool_scrub/Makefile.am
index ee6a839fc..ccca437eb 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zpool_scrub/Makefile.am
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_scrub/Makefile.am
@@ -7,4 +7,5 @@ dist_pkgdata_SCRIPTS = \
zpool_scrub_002_pos.ksh \
zpool_scrub_003_pos.ksh \
zpool_scrub_004_pos.ksh \
- zpool_scrub_005_pos.ksh
+ zpool_scrub_005_pos.ksh \
+ zpool_scrub_encrypted_unloaded.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh
new file mode 100755
index 000000000..483a683bd
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_encrypted_unloaded.ksh
@@ -0,0 +1,71 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Scrubs must work on an encrypted dataset with an unloaded key.
+#
+# STRATEGY:
+# 1. Create an encrypted dataset
+# 2. Generate data on the dataset
+# 3. Unmount the encrypted dataset and unload its key
+# 4. Start a scrub
+# 5. Wait for the scrub to complete
+# 6. Verify the scrub had no errors
+# 7. Load the dataset key and mount it
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ datasetexists $TESTPOOL/$TESTFS2 && \
+ log_must zfs destroy $TESTPOOL/$TESTFS2
+}
+log_onexit cleanup
+
+log_assert "Scrubs must work on an encrypted dataset with an unloaded key"
+
+log_must eval "echo 'password' | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2"
+
+typeset mntpnt=$(get_prop mountpoint $TESTPOOL/$TESTFS2)
+log_must mkfile 10m $mntpnt/file1
+
+for i in 2..10; do
+ log_must mkfile 512b $mntpnt/file$i
+done
+
+log_must zfs unmount $TESTPOOL/$TESTFS2
+log_must zfs unload-key $TESTPOOL/$TESTFS2
+
+log_must zpool scrub $TESTPOOL
+
+while ! is_pool_scrubbed $TESTPOOL; do
+ sleep 1
+done
+
+log_must check_pool_status $TESTPOOL "scan" "with 0 errors"
+
+log_must eval "echo 'password' | zfs mount -l $TESTPOOL/$TESTFS2"
+
+log_pass "Scrubs work on an encrypted dataset with an unloaded key"
diff --git a/tests/zfs-tests/tests/functional/rsend/Makefile.am b/tests/zfs-tests/tests/functional/rsend/Makefile.am
index b9f8dba65..199acb68b 100644
--- a/tests/zfs-tests/tests/functional/rsend/Makefile.am
+++ b/tests/zfs-tests/tests/functional/rsend/Makefile.am
@@ -23,6 +23,7 @@ dist_pkgdata_SCRIPTS = \
rsend_021_pos.ksh \
rsend_022_pos.ksh \
rsend_024_pos.ksh \
+ send_encrypted_heirarchy.ksh \
send-cD.ksh \
send-c_embedded_blocks.ksh \
send-c_incremental.ksh \
diff --git a/tests/zfs-tests/tests/functional/rsend/rsend.kshlib b/tests/zfs-tests/tests/functional/rsend/rsend.kshlib
index 6e2f2ce6f..7c4b2f07f 100644
--- a/tests/zfs-tests/tests/functional/rsend/rsend.kshlib
+++ b/tests/zfs-tests/tests/functional/rsend/rsend.kshlib
@@ -601,7 +601,7 @@ function parse_dump
if ($1 == "OBJECT") print $1" "$4
if ($1 == "FREEOBJECTS") print $1" "$4" "$7
if ($1 == "FREE") print $1" "$7" "$10
- if ($1 == "WRITE") print $1" "$15" "$18" "$21" "$24" "$27}'
+ if ($1 == "WRITE") print $1" "$15" "$21" "$24" "$27" "$30}'
}
#
diff --git a/tests/zfs-tests/tests/functional/rsend/send_encrypted_heirarchy.ksh b/tests/zfs-tests/tests/functional/rsend/send_encrypted_heirarchy.ksh
new file mode 100755
index 000000000..5e19a6b6c
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/rsend/send_encrypted_heirarchy.ksh
@@ -0,0 +1,96 @@
+#!/bin/ksh -p
+#
+# 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 by Datto Inc. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
+
+#
+# DESCRIPTION:
+# Raw recursive sends preserve filesystem structure.
+#
+# STRATEGY:
+# 1. Create an encrypted filesystem with a clone and a child
+# 2. Snapshot and send the filesystem tree
+# 3. Verify that the filesystem structure was correctly received
+# 4. Change the child to an encryption root and promote the clone
+# 5. Snapshot and send the filesystem tree again
+# 6. Verify that the new structure is received correctly
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ log_must cleanup_pool $POOL
+ log_must cleanup_pool $POOL2
+ log_must setup_test_model $POOL
+}
+
+log_assert "Raw recursive sends preserve filesystem structure."
+log_onexit cleanup
+
+# Create the filesystem heirarchy
+log_must cleanup_pool $POOL
+log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
+ "-o keyformat=passphrase $POOL/$FS"
+log_must zfs snapshot $POOL/$FS@snap
+log_must zfs clone $POOL/$FS@snap $POOL/clone
+log_must zfs create $POOL/$FS/child
+
+# Back up the tree and verify the structure
+log_must zfs snapshot -r $POOL@before
+log_must eval "zfs send -wR $POOL@before > $BACKDIR/fs-before-R"
+log_must eval "zfs receive -d -F $POOL2 < $BACKDIR/fs-before-R"
+dstds=$(get_dst_ds $POOL/$FS $POOL2)
+log_must cmp_ds_subs $POOL/$FS $dstds
+
+log_must verify_encryption_root $POOL/$FS $POOL/$FS
+log_must verify_keylocation $POOL/$FS "prompt"
+log_must verify_origin $POOL/$FS "-"
+
+log_must verify_encryption_root $POOL/clone $POOL/$FS
+log_must verify_keylocation $POOL/clone "none"
+log_must verify_origin $POOL/clone "$POOL/$FS@snap"
+
+log_must verify_encryption_root $POOL/$FS/child $POOL/$FS
+log_must verify_keylocation $POOL/$FS/child "none"
+
+# Alter the heirarchy and re-send
+log_must eval "echo $PASSPHRASE1 | zfs change-key -o keyformat=passphrase" \
+ "$POOL/$FS/child"
+log_must zfs promote $POOL/clone
+log_must zfs snapshot -r $POOL@after
+log_must eval "zfs send -wR -i $POOL@before $POOL@after >" \
+ "$BACKDIR/fs-after-R"
+log_must eval "zfs receive -d -F $POOL2 < $BACKDIR/fs-after-R"
+log_must cmp_ds_subs $POOL/$FS $dstds
+
+log_must verify_encryption_root $POOL/$FS $POOL/clone
+log_must verify_keylocation $POOL/$FS "none"
+log_must verify_origin $POOL/$FS "$POOL/clone@snap"
+
+log_must verify_encryption_root $POOL/clone $POOL/clone
+log_must verify_keylocation $POOL/clone "prompt"
+log_must verify_origin $POOL/clone "-"
+
+log_must verify_encryption_root $POOL/$FS/child $POOL/$FS/child
+log_must verify_keylocation $POOL/$FS/child "prompt"
+
+log_pass "Raw recursive sends preserve filesystem structure."