diff --git a/include/os/freebsd/zfs/sys/freebsd_crypto.h b/include/os/freebsd/zfs/sys/freebsd_crypto.h index a61a6cd88c13..de8f35b5ca3d 100644 --- a/include/os/freebsd/zfs/sys/freebsd_crypto.h +++ b/include/os/freebsd/zfs/sys/freebsd_crypto.h @@ -41,6 +41,7 @@ #define SUN_CKM_AES_CCM "CKM_AES_CCM" #define SUN_CKM_AES_GCM "CKM_AES_GCM" #define SUN_CKM_SHA512_HMAC "CKM_SHA512_HMAC" +#define SUN_CKM_CHACHA20_POLY1305 "CKM_CHACHA20_POLY1305" #define CRYPTO_BITS2BYTES(n) ((n) == 0 ? 0 : (((n) - 1) >> 3) + 1) #define CRYPTO_BYTES2BITS(n) ((n) << 3) diff --git a/module/os/freebsd/zfs/crypto_os.c b/module/os/freebsd/zfs/crypto_os.c index 1f139ea5b807..19174d837be5 100644 --- a/module/os/freebsd/zfs/crypto_os.c +++ b/module/os/freebsd/zfs/crypto_os.c @@ -305,6 +305,17 @@ freebsd_crypt_newsession(freebsd_crypt_session_t *sessp, break; } break; + case ZC_TYPE_CHACHA20_POLY1305: + csp.csp_cipher_alg = CRYPTO_CHACHA20_POLY1305; + csp.csp_ivlen = CHACHA20_POLY1305_IV_LEN; + switch (key->ck_length/8) { + case CHACHA20_POLY1305_KEY: + break; + default: + error = EINVAL; + goto bad; + } + break; default: error = ENOTSUP; goto bad; @@ -453,6 +464,10 @@ freebsd_crypt_newsession(freebsd_crypt_session_t *sessp, break; } break; + case ZC_TYPE_CHACHA20_POLY1305: + xform = &enc_xform_chacha20_poly1305; + xauth = &auth_hash_poly1305; + break; default: error = ENOTSUP; goto bad; @@ -555,6 +570,10 @@ freebsd_crypt_uio(boolean_t encrypt, break; } break; + case ZC_TYPE_CHACHA20_POLY1305: + xform = &enc_xform_chacha20_poly1305; + xauth = &auth_hash_poly1305; + break; default: error = ENOTSUP; goto bad; diff --git a/module/os/freebsd/zfs/zio_crypt.c b/module/os/freebsd/zfs/zio_crypt.c index fdbe13dbb5e9..ca8237aa20ac 100644 --- a/module/os/freebsd/zfs/zio_crypt.c +++ b/module/os/freebsd/zfs/zio_crypt.c @@ -194,15 +194,26 @@ typedef struct blkptr_auth_buf { } blkptr_auth_buf_t; const zio_crypt_info_t zio_crypt_table[ZIO_CRYPT_FUNCTIONS] = { - {"", ZC_TYPE_NONE, 0, "inherit"}, - {"", ZC_TYPE_NONE, 0, "on"}, - {"", ZC_TYPE_NONE, 0, "off"}, - {SUN_CKM_AES_CCM, ZC_TYPE_CCM, 16, "aes-128-ccm"}, - {SUN_CKM_AES_CCM, ZC_TYPE_CCM, 24, "aes-192-ccm"}, - {SUN_CKM_AES_CCM, ZC_TYPE_CCM, 32, "aes-256-ccm"}, - {SUN_CKM_AES_GCM, ZC_TYPE_GCM, 16, "aes-128-gcm"}, - {SUN_CKM_AES_GCM, ZC_TYPE_GCM, 24, "aes-192-gcm"}, - {SUN_CKM_AES_GCM, ZC_TYPE_GCM, 32, "aes-256-gcm"} + {"", ZC_TYPE_NONE, + 0, "inherit"}, + {"", ZC_TYPE_NONE, + 0, "on"}, + {"", ZC_TYPE_NONE, + 0, "off"}, + {SUN_CKM_AES_CCM, ZC_TYPE_CCM, + 16, "aes-128-ccm"}, + {SUN_CKM_AES_CCM, ZC_TYPE_CCM, + 24, "aes-192-ccm"}, + {SUN_CKM_AES_CCM, ZC_TYPE_CCM, + 32, "aes-256-ccm"}, + {SUN_CKM_AES_GCM, ZC_TYPE_GCM, + 16, "aes-128-gcm"}, + {SUN_CKM_AES_GCM, ZC_TYPE_GCM, + 24, "aes-192-gcm"}, + {SUN_CKM_AES_GCM, ZC_TYPE_GCM, + 32, "aes-256-gcm"}, + {SUN_CKM_CHACHA20_POLY1305, ZC_TYPE_CHACHA20_POLY1305, + 32, "chacha20-poly1305"}, }; static void @@ -238,7 +249,8 @@ zio_crypt_key_init(uint64_t crypt, zio_crypt_key_t *key) ci = &zio_crypt_table[crypt]; if (ci->ci_crypt_type != ZC_TYPE_GCM && - ci->ci_crypt_type != ZC_TYPE_CCM) + ci->ci_crypt_type != ZC_TYPE_CCM && + ci->ci_crypt_type != ZC_TYPE_CHACHA20_POLY1305) return (ENOTSUP); keydata_len = zio_crypt_table[crypt].ci_keylen; @@ -278,7 +290,8 @@ zio_crypt_key_init(uint64_t crypt, zio_crypt_key_t *key) ci = &zio_crypt_table[crypt]; if (ci->ci_crypt_type != ZC_TYPE_GCM && - ci->ci_crypt_type != ZC_TYPE_CCM) + ci->ci_crypt_type != ZC_TYPE_CCM && + ci->ci_crypt_type != ZC_TYPE_CHACHA20_POLY1305) return (ENOTSUP); ret = freebsd_crypt_newsession(&key->zk_session, ci, @@ -400,7 +413,8 @@ zio_do_crypt_uio_opencrypto(boolean_t encrypt, freebsd_crypt_session_t *sess, { const zio_crypt_info_t *ci = &zio_crypt_table[crypt]; if (ci->ci_crypt_type != ZC_TYPE_GCM && - ci->ci_crypt_type != ZC_TYPE_CCM) + ci->ci_crypt_type != ZC_TYPE_CCM && + ci->ci_crypt_type != ZC_TYPE_CHACHA20_POLY1305) return (ENOTSUP);