Commit 8129bac6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt

Pull fscrypt updates from Eric Biggers:
 "This release adds SM4 encryption support, contributed by Tianjia
  Zhang. SM4 is a Chinese block cipher that is an alternative to AES.

  I recommend against using SM4, but (according to Tianjia) some people
  are being required to use it. Since SM4 has been turning up in many
  other places (crypto API, wireless, TLS, OpenSSL, ARMv8 CPUs, etc.),
  it hasn't been very controversial, and some people have to use it, I
  don't think it would be fair for me to reject this optional feature.

  Besides the above, there are a couple cleanups"

* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt:
  fscrypt: add additional documentation for SM4 support
  fscrypt: remove unused Speck definitions
  fscrypt: Add SM4 XTS/CTS symmetric algorithm support
  blk-crypto: Add support for SM4-XTS blk crypto mode
  fscrypt: add comment for fscrypt_valid_enc_modes_v1()
  fscrypt: pass super_block to fscrypt_put_master_key_activeref()
parents deb9acc1 41952551
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -338,6 +338,7 @@ Currently, the following pairs of encryption modes are supported:
- AES-128-CBC for contents and AES-128-CTS-CBC for filenames
- Adiantum for both contents and filenames
- AES-256-XTS for contents and AES-256-HCTR2 for filenames (v2 policies only)
- SM4-XTS for contents and SM4-CTS-CBC for filenames (v2 policies only)

If unsure, you should use the (AES-256-XTS, AES-256-CTS-CBC) pair.

@@ -369,6 +370,12 @@ CONFIG_CRYPTO_HCTR2 must be enabled. Also, fast implementations of XCTR and
POLYVAL should be enabled, e.g. CRYPTO_POLYVAL_ARM64_CE and
CRYPTO_AES_ARM64_CE_BLK for ARM64.

SM4 is a Chinese block cipher that is an alternative to AES.  It has
not seen as much security review as AES, and it only has a 128-bit key
size.  It may be useful in cases where its use is mandated.
Otherwise, it should not be used.  For SM4 support to be available, it
also needs to be enabled in the kernel crypto API.

New encryption modes can be added relatively easily, without changes
to individual filesystems.  However, authenticated encryption (AE)
modes are not currently supported because of the difficulty of dealing
+6 −0
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ const struct blk_crypto_mode blk_crypto_modes[] = {
		.keysize = 32,
		.ivsize = 32,
	},
	[BLK_ENCRYPTION_MODE_SM4_XTS] = {
		.name = "SM4-XTS",
		.cipher_str = "xts(sm4)",
		.keysize = 32,
		.ivsize = 16,
	},
};

/*
+4 −9
Original line number Diff line number Diff line
@@ -439,13 +439,7 @@ struct fscrypt_master_key_secret {
struct fscrypt_master_key {

	/*
	 * Back-pointer to the super_block of the filesystem to which this
	 * master key has been added.  Only valid if ->mk_active_refs > 0.
	 */
	struct super_block			*mk_sb;

	/*
	 * Link in ->mk_sb->s_master_keys->key_hashtable.
	 * Link in ->s_master_keys->key_hashtable.
	 * Only valid if ->mk_active_refs > 0.
	 */
	struct hlist_node			mk_node;
@@ -456,7 +450,7 @@ struct fscrypt_master_key {
	/*
	 * Active and structural reference counts.  An active ref guarantees
	 * that the struct continues to exist, continues to be in the keyring
	 * ->mk_sb->s_master_keys, and that any embedded subkeys (e.g.
	 * ->s_master_keys, and that any embedded subkeys (e.g.
	 * ->mk_direct_keys) that have been prepared continue to exist.
	 * A structural ref only guarantees that the struct continues to exist.
	 *
@@ -569,7 +563,8 @@ static inline int master_key_spec_len(const struct fscrypt_key_specifier *spec)

void fscrypt_put_master_key(struct fscrypt_master_key *mk);

void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk);
void fscrypt_put_master_key_activeref(struct super_block *sb,
				      struct fscrypt_master_key *mk);

struct fscrypt_master_key *
fscrypt_find_master_key(struct super_block *sb,
+6 −8
Original line number Diff line number Diff line
@@ -79,10 +79,9 @@ void fscrypt_put_master_key(struct fscrypt_master_key *mk)
	call_rcu(&mk->mk_rcu_head, fscrypt_free_master_key);
}

void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk)
void fscrypt_put_master_key_activeref(struct super_block *sb,
				      struct fscrypt_master_key *mk)
{
	struct super_block *sb = mk->mk_sb;
	struct fscrypt_keyring *keyring = sb->s_master_keys;
	size_t i;

	if (!refcount_dec_and_test(&mk->mk_active_refs))
@@ -93,9 +92,9 @@ void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk)
	 * destroying any subkeys embedded in it.
	 */

	spin_lock(&keyring->lock);
	spin_lock(&sb->s_master_keys->lock);
	hlist_del_rcu(&mk->mk_node);
	spin_unlock(&keyring->lock);
	spin_unlock(&sb->s_master_keys->lock);

	/*
	 * ->mk_active_refs == 0 implies that ->mk_secret is not present and
@@ -243,7 +242,7 @@ void fscrypt_destroy_keyring(struct super_block *sb)
			WARN_ON(refcount_read(&mk->mk_struct_refs) != 1);
			WARN_ON(!is_master_key_secret_present(&mk->mk_secret));
			wipe_master_key_secret(&mk->mk_secret);
			fscrypt_put_master_key_activeref(mk);
			fscrypt_put_master_key_activeref(sb, mk);
		}
	}
	kfree_sensitive(keyring);
@@ -424,7 +423,6 @@ static int add_new_master_key(struct super_block *sb,
	if (!mk)
		return -ENOMEM;

	mk->mk_sb = sb;
	init_rwsem(&mk->mk_sem);
	refcount_set(&mk->mk_struct_refs, 1);
	mk->mk_spec = *mk_spec;
@@ -1068,7 +1066,7 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
	err = -ENOKEY;
	if (is_master_key_secret_present(&mk->mk_secret)) {
		wipe_master_key_secret(&mk->mk_secret);
		fscrypt_put_master_key_activeref(mk);
		fscrypt_put_master_key_activeref(sb, mk);
		err = 0;
	}
	inodes_remain = refcount_read(&mk->mk_active_refs) > 0;
+16 −1
Original line number Diff line number Diff line
@@ -44,6 +44,21 @@ struct fscrypt_mode fscrypt_modes[] = {
		.security_strength = 16,
		.ivsize = 16,
	},
	[FSCRYPT_MODE_SM4_XTS] = {
		.friendly_name = "SM4-XTS",
		.cipher_str = "xts(sm4)",
		.keysize = 32,
		.security_strength = 16,
		.ivsize = 16,
		.blk_crypto_mode = BLK_ENCRYPTION_MODE_SM4_XTS,
	},
	[FSCRYPT_MODE_SM4_CTS] = {
		.friendly_name = "SM4-CTS-CBC",
		.cipher_str = "cts(cbc(sm4))",
		.keysize = 16,
		.security_strength = 16,
		.ivsize = 16,
	},
	[FSCRYPT_MODE_ADIANTUM] = {
		.friendly_name = "Adiantum",
		.cipher_str = "adiantum(xchacha12,aes)",
@@ -509,7 +524,7 @@ static void put_crypt_info(struct fscrypt_info *ci)
		spin_lock(&mk->mk_decrypted_inodes_lock);
		list_del(&ci->ci_master_key_link);
		spin_unlock(&mk->mk_decrypted_inodes_lock);
		fscrypt_put_master_key_activeref(mk);
		fscrypt_put_master_key_activeref(ci->ci_inode->i_sb, mk);
	}
	memzero_explicit(ci, sizeof(*ci));
	kmem_cache_free(fscrypt_info_cachep, ci);
Loading