diff --git a/include/zfeature_common.h b/include/zfeature_common.h index 1025c44738ba..cfde1c76d7c6 100644 --- a/include/zfeature_common.h +++ b/include/zfeature_common.h @@ -81,6 +81,7 @@ typedef enum spa_feature { SPA_FEATURE_BLOCK_CLONING, SPA_FEATURE_AVZ_V2, SPA_FEATURE_REDACTION_LIST_SPILL, + SPA_FEATURE_CHACHA20_POLY1305, SPA_FEATURES } spa_feature_t; diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index 0a8e9bcbd74d..af55f4fb91da 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -5810,7 +5810,8 @@ - + + diff --git a/man/man7/zpool-features.7 b/man/man7/zpool-features.7 index 3c7b0b345d96..af3dc5e8f490 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 . @@ -398,6 +398,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 2c74d10f43ff..0977006c990b 100644 --- a/module/zcommon/zfeature_common.c +++ b/module/zcommon/zfeature_common.c @@ -749,6 +749,19 @@ zpool_feature_init(void) redact_list_spill_deps, 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 4248578cde16..ba58aff8e899 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 @@ -87,6 +87,7 @@ typeset -a properties=( "feature@device_rebuild" "feature@draid" "feature@redaction_list_spill" + "feature@chacha20_poly1305" ) if is_linux || is_freebsd; then