diff --git a/module/zfs/zcp_get.c b/module/zfs/zcp_get.c
index 2d4d6c040..1ae3a058d 100644
--- a/module/zfs/zcp_get.c
+++ b/module/zfs/zcp_get.c
@@ -378,14 +378,17 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname,
 		break;
 	}
 
+	case ZFS_PROP_ENCRYPTION:
 	case ZFS_PROP_KEYSTATUS:
 	case ZFS_PROP_KEYFORMAT: {
 		/* provide defaults in case no crypto obj exists */
 		setpoint[0] = '\0';
-		if (zfs_prop == ZFS_PROP_KEYSTATUS)
-			numval = ZFS_KEYSTATUS_NONE;
-		else
+		if (zfs_prop == ZFS_PROP_ENCRYPTION)
+			numval = ZIO_CRYPT_OFF;
+		else if (zfs_prop == ZFS_PROP_KEYFORMAT)
 			numval = ZFS_KEYFORMAT_NONE;
+		else if (zfs_prop == ZFS_PROP_KEYSTATUS)
+			numval = ZFS_KEYSTATUS_NONE;
 
 		nvlist_t *nvl, *propval;
 		nvl = fnvlist_alloc();
@@ -404,6 +407,29 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname,
 		break;
 	}
 
+	case ZFS_PROP_ENCRYPTION_ROOT: {
+		setpoint[0] = '\0';
+		strval[0] = '\0';
+
+		nvlist_t *nvl, *propval;
+		nvl = fnvlist_alloc();
+		dsl_dataset_crypt_stats(ds, nvl);
+		if (nvlist_lookup_nvlist(nvl, zfs_prop_to_name(zfs_prop),
+		    &propval) == 0) {
+			const char *dsname;
+			const char *source;
+
+			if (nvlist_lookup_string(propval, ZPROP_VALUE,
+			    &dsname) == 0)
+				strlcpy(strval, dsname, ZAP_MAXVALUELEN);
+			if (nvlist_lookup_string(propval, ZPROP_SOURCE,
+			    &source) == 0)
+				strlcpy(setpoint, source, sizeof (setpoint));
+		}
+		nvlist_free(nvl);
+		break;
+	}
+
 	case ZFS_PROP_SNAPSHOTS_CHANGED:
 		numval = dsl_dir_snap_cmtime(ds->ds_dir).tv_sec;
 		break;
diff --git a/tests/runfiles/common.run b/tests/runfiles/common.run
index 1711ecd41..fd7885d51 100644
--- a/tests/runfiles/common.run
+++ b/tests/runfiles/common.run
@@ -120,7 +120,7 @@ tests = ['case_all_values', 'norm_all_values', 'mixed_create_failure',
 tags = ['functional', 'casenorm']
 
 [tests/functional/channel_program/lua_core]
-tests = ['tst.args_to_lua', 'tst.divide_by_zero', 'tst.exists',
+tests = ['tst.args_to_lua', 'tst.divide_by_zero', 'tst.exists', 'tst.encryption',
     'tst.integer_illegal', 'tst.integer_overflow', 'tst.language_functions_neg',
     'tst.language_functions_pos', 'tst.large_prog', 'tst.libraries',
     'tst.memory_limit', 'tst.nested_neg', 'tst.nested_pos', 'tst.nvlist_to_lua',
diff --git a/tests/runfiles/sanity.run b/tests/runfiles/sanity.run
index 9483eac40..1dbdc4d4e 100644
--- a/tests/runfiles/sanity.run
+++ b/tests/runfiles/sanity.run
@@ -64,7 +64,7 @@ tests = ['case_all_values', 'norm_all_values', 'sensitive_none_lookup',
 tags = ['functional', 'casenorm']
 
 [tests/functional/channel_program/lua_core]
-tests = ['tst.args_to_lua', 'tst.divide_by_zero', 'tst.exists',
+tests = ['tst.args_to_lua', 'tst.divide_by_zero', 'tst.exists', 'tst.encryption',
     'tst.integer_illegal', 'tst.integer_overflow', 'tst.language_functions_neg',
     'tst.language_functions_pos', 'tst.large_prog', 'tst.libraries',
     'tst.memory_limit', 'tst.nested_neg', 'tst.nested_pos', 'tst.nvlist_to_lua',
diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am
index 5f52fd49a..ee9d3b1d7 100644
--- a/tests/zfs-tests/tests/Makefile.am
+++ b/tests/zfs-tests/tests/Makefile.am
@@ -106,6 +106,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
 	functional/channel_program/lua_core/tst.args_to_lua.zcp \
 	functional/channel_program/lua_core/tst.divide_by_zero.err \
 	functional/channel_program/lua_core/tst.divide_by_zero.zcp \
+	functional/channel_program/lua_core/tst.encryption.zcp \
 	functional/channel_program/lua_core/tst.exists.zcp \
 	functional/channel_program/lua_core/tst.large_prog.out \
 	functional/channel_program/lua_core/tst.large_prog.zcp \
@@ -544,6 +545,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
 	functional/channel_program/lua_core/setup.ksh \
 	functional/channel_program/lua_core/tst.args_to_lua.ksh \
 	functional/channel_program/lua_core/tst.divide_by_zero.ksh \
+	functional/channel_program/lua_core/tst.encryption.ksh \
 	functional/channel_program/lua_core/tst.exists.ksh \
 	functional/channel_program/lua_core/tst.integer_illegal.ksh \
 	functional/channel_program/lua_core/tst.integer_overflow.ksh \
diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.encryption.ksh b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.encryption.ksh
new file mode 100755
index 000000000..448f91a70
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.encryption.ksh
@@ -0,0 +1,43 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# 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.
+#
+
+#
+# Copyright (c) 2021 by Determinate Systems. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
+
+#
+# DESCRIPTION:
+#       zfs.exists should accurately report whether a dataset exists, and
+#       report an error if a dataset is in another pool.
+
+verify_runnable "global"
+
+function cleanup
+{
+	datasetexists $TESTPOOL/$TESTDATASET && \
+	    log_must zfs destroy -R $TESTPOOL/$TESTDATASET
+}
+log_onexit cleanup
+
+TESTDATASET="channelprogramencryption"
+
+passphrase="password"
+log_must eval "echo "$passphrase" | zfs create -o encryption=aes-256-ccm " \
+        "-o keyformat=passphrase $TESTPOOL/$TESTDATASET"
+
+log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.encryption.zcp \
+    $TESTPOOL/$TESTDATASET
+
+log_pass "zfs.get_prop(dataset, ...)  on \"encryption\" and \"encryptionroot\" gives correct results"
diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.encryption.zcp b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.encryption.zcp
new file mode 100644
index 000000000..5b9896b2a
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.encryption.zcp
@@ -0,0 +1,23 @@
+-- SPDX-License-Identifier: CDDL-1.0
+--
+-- 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.
+--
+
+--
+-- Copyright (c) 2021 by Determinate Systems. All rights reserved.
+--
+
+-- ensure zfs.get_prop returns the correct values for "encryption"
+-- and "encryptionroot"
+
+args = ...
+argv = args['argv']
+assert(zfs.get_prop(argv[1], "encryption") == "aes-256-ccm")
+assert(zfs.get_prop(argv[1], "encryptionroot") == argv[1])
diff --git a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.ksh b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.ksh
index 6f2c7dc8d..8f56ffab6 100755
--- a/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.ksh
+++ b/tests/zfs-tests/tests/functional/channel_program/lua_core/tst.exists.ksh
@@ -24,15 +24,16 @@
 
 verify_runnable "global"
 
-# create $TESTSNAP and $TESTCLONE
-create_snapshot
-create_clone
-
 function cleanup
 {
 	datasetexists $TESTPOOL/$TESTFS@$TESTSNAP && \
 	    destroy_dataset $TESTPOOL/$TESTFS@$TESTSNAP -R
 }
+log_onexit cleanup
+
+# create $TESTSNAP and $TESTCLONE
+create_snapshot
+create_clone
 
 log_must_program $TESTPOOL $ZCP_ROOT/lua_core/tst.exists.zcp \
     $TESTPOOL $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS@$TESTSNAP \