From 5c735461b3ad60893ab3f130d940fe1e9e16c408 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 21 May 2023 19:42:52 +1000 Subject: [PATCH] chapoly: add chacha20_poly1305 feature Signed-off-by: Rob Norris --- include/zfeature_common.h | 1 + lib/libzfs/libzfs.abi | 9 ++++---- man/man7/zpool-features.7 | 17 ++++++++++++++- module/zcommon/zfeature_common.c | 13 ++++++++++++ module/zfs/dsl_crypt.c | 21 +++++++++++++++++++ module/zfs/dsl_pool.c | 6 +++++- .../cli_root/zpool_get/zpool_get.cfg | 1 + 7 files changed, 62 insertions(+), 6 deletions(-) diff --git a/include/zfeature_common.h b/include/zfeature_common.h index 7066c699e203..fa186bb90bf9 100644 --- a/include/zfeature_common.h +++ b/include/zfeature_common.h @@ -80,6 +80,7 @@ typedef enum spa_feature { SPA_FEATURE_BLAKE3, SPA_FEATURE_BLOCK_CLONING, SPA_FEATURE_AVZ_V2, + SPA_FEATURE_CHACHA20_POLY1305, SPA_FEATURES } spa_feature_t; diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index 6e53bcb41a87..b87516d23daf 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -596,7 +596,7 @@ - + @@ -5809,7 +5809,8 @@ - + + @@ -8706,8 +8707,8 @@ - - + + diff --git a/man/man7/zpool-features.7 b/man/man7/zpool-features.7 index 2b7dcb63829c..8f52cb8ade3f 100644 --- a/man/man7/zpool-features.7 +++ b/man/man7/zpool-features.7 @@ -18,7 +18,7 @@ .\" Copyright (c) 2019, Allan Jude .\" Copyright (c) 2021, Colm Buckley .\" -.Dd June 23, 2022 +.Dd May 21, 2023 .Dt ZPOOL-FEATURES 7 .Os . @@ -396,6 +396,21 @@ returned to the .Sy enabled state when all bookmarks with these fields are destroyed. . +.feature org.openzfs chacha20_poly1305 no encryption extensible_dataset +This feature enables the use of the ChaCha20-Poly1305 cipher suite for encrypted +datasets. +On systems lackng hardware-accelerated AES (many non-x86 boards), this suite +will usually offer better performance than AES suites without compromising +security. +.Pp +This feature becomes +.Sy active +when an encrypted dataset is created with +.Nm encryption Ns = Ns Sy chacha20-poly1305 +and will be returned to the +.Sy enabled +state when all datasets that use this feature are destroyed. +. .feature org.openzfs device_rebuild yes This feature enables the ability for the .Nm zpool Cm attach diff --git a/module/zcommon/zfeature_common.c b/module/zcommon/zfeature_common.c index 4c9b7ed72a0f..7266261e3f69 100644 --- a/module/zcommon/zfeature_common.c +++ b/module/zcommon/zfeature_common.c @@ -737,6 +737,19 @@ zpool_feature_init(void) ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures); + { + static const spa_feature_t chapoly_deps[] = { + SPA_FEATURE_EXTENSIBLE_DATASET, + SPA_FEATURE_ENCRYPTION, + SPA_FEATURE_NONE + }; + zfeature_register(SPA_FEATURE_CHACHA20_POLY1305, + "org.openzfs:chacha20_poly1305", "chacha20_poly1305", + "Chacha20-Poly1305 encryption suite.", + ZFEATURE_FLAG_PER_DATASET, ZFEATURE_TYPE_BOOLEAN, + chapoly_deps, sfeatures); + } + zfs_mod_list_supported_free(sfeatures); } diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index 5e6e4e3d6c39..9393bd4f45ea 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -1819,6 +1819,12 @@ dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp, return (SET_ERROR(EOPNOTSUPP)); } + if (crypt == ZIO_CRYPT_CHACHA20_POLY1305 && parentdd != NULL && + !spa_feature_is_enabled(parentdd->dd_pool->dp_spa, + SPA_FEATURE_CHACHA20_POLY1305)) { + return (SET_ERROR(EOPNOTSUPP)); + } + /* handle inheritance */ if (dcp->cp_wkey == NULL) { ASSERT3P(parentdd, !=, NULL); @@ -1937,6 +1943,9 @@ dsl_dataset_create_crypt_sync(uint64_t dsobj, dsl_dir_t *dd, tx)); dsl_dataset_activate_feature(dsobj, SPA_FEATURE_ENCRYPTION, (void *)B_TRUE, tx); + if (crypt == ZIO_CRYPT_CHACHA20_POLY1305) + dsl_dataset_activate_feature(dsobj, + SPA_FEATURE_CHACHA20_POLY1305, (void *)B_TRUE, tx); /* * If we inherited the wrapping key we release our reference now. @@ -2157,6 +2166,11 @@ dsl_crypto_recv_raw_key_check(dsl_dataset_t *ds, nvlist_t *nvl, dmu_tx_t *tx) if (intval >= ZIO_CRYPT_FUNCTIONS) return (SET_ERROR(ZFS_ERR_CRYPTO_NOTSUP)); + if (intval == ZIO_CRYPT_CHACHA20_POLY1305 && + !spa_feature_is_enabled(ds->ds_dir->dd_pool->dp_spa, + SPA_FEATURE_CHACHA20_POLY1305)) + return (SET_ERROR(EOPNOTSUPP)); + ret = nvlist_lookup_uint64(nvl, DSL_CRYPTO_KEY_GUID, &intval); if (ret != 0) return (SET_ERROR(EINVAL)); @@ -2276,6 +2290,13 @@ dsl_crypto_recv_raw_key_sync(dsl_dataset_t *ds, nvlist_t *nvl, dmu_tx_t *tx) SPA_FEATURE_ENCRYPTION, (void *)B_TRUE, tx); ds->ds_feature[SPA_FEATURE_ENCRYPTION] = (void *)B_TRUE; + if (crypt == ZIO_CRYPT_CHACHA20_POLY1305) { + dsl_dataset_activate_feature(ds->ds_object, + SPA_FEATURE_CHACHA20_POLY1305, (void *)B_TRUE, tx); + ds->ds_feature[SPA_FEATURE_CHACHA20_POLY1305] = + (void *)B_TRUE; + } + /* save the dd_crypto_obj on disk */ VERIFY0(zap_add(mos, dd->dd_object, DD_FIELD_CRYPTO_KEY_OBJ, sizeof (uint64_t), 1, &dd->dd_crypto_obj, tx)); diff --git a/module/zfs/dsl_pool.c b/module/zfs/dsl_pool.c index 9120fef93c74..0ef2ad30f17d 100644 --- a/module/zfs/dsl_pool.c +++ b/module/zfs/dsl_pool.c @@ -537,8 +537,12 @@ dsl_pool_create(spa_t *spa, nvlist_t *zplprops __attribute__((unused)), spa_feature_create_zap_objects(spa, tx); if (dcp != NULL && dcp->cp_crypt != ZIO_CRYPT_OFF && - dcp->cp_crypt != ZIO_CRYPT_INHERIT) + dcp->cp_crypt != ZIO_CRYPT_INHERIT) { spa_feature_enable(spa, SPA_FEATURE_ENCRYPTION, tx); + if (dcp->cp_crypt == ZIO_CRYPT_CHACHA20_POLY1305) + spa_feature_enable(spa, + SPA_FEATURE_CHACHA20_POLY1305, tx); + } /* create the root dataset */ obj = dsl_dataset_create_sync_dd(dp->dp_root_dir, NULL, dcp, 0, tx); 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 160a0ca2e6db..ecf2be8f12ed 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 @@ -86,6 +86,7 @@ typeset -a properties=( "feature@log_spacemap" "feature@device_rebuild" "feature@draid" + "feature@chacha20_poly1305" ) if is_linux || is_freebsd; then