#define LLCRYPT_POLICY_FLAGS_VALID 0x07
/* Encryption algorithms */
+#define LLCRYPT_MODE_NULL 0
#define LLCRYPT_MODE_AES_256_XTS 1
#define LLCRYPT_MODE_AES_256_CTS 4
#define LLCRYPT_MODE_AES_128_CBC 5
struct crypto_skcipher *tfm = ci->ci_ctfm;
int res = 0;
+ if (tfm == NULL) {
+ if (dest_page != src_page)
+ memcpy(page_address(dest_page), page_address(src_page),
+ PAGE_SIZE);
+ return 0;
+ }
+
if (WARN_ON_ONCE(len <= 0))
return -EINVAL;
if (WARN_ON_ONCE(len % LL_CRYPTO_BLOCK_SIZE != 0))
memcpy(out, iname->name, iname->len);
memset(out + iname->len, 0, olen - iname->len);
+ if (tfm == NULL)
+ return 0;
+
/* Initialize the IV */
llcrypt_generate_iv(&iv, 0, ci);
union llcrypt_iv iv;
int res;
+ if (tfm == NULL) {
+ memcpy(oname->name, iname->name, iname->len);
+ oname->name[iname->len] = '\0';
+ oname->len = iname->len;
+ return 0;
+ }
+
/* Allocate request */
req = skcipher_request_alloc(tfm, GFP_NOFS);
if (!req)
static struct crypto_shash *essiv_hash_tfm;
static struct llcrypt_mode available_modes[] = {
+ [LLCRYPT_MODE_NULL] = {
+ .friendly_name = "NULL",
+ .cipher_str = "null",
+ .keysize = 0,
+ .ivsize = 0,
+ },
[LLCRYPT_MODE_AES_256_XTS] = {
.friendly_name = "AES-256-XTS",
.cipher_str = "xts(aes)",
struct crypto_skcipher *tfm;
int err;
+ if (!strcmp(mode->cipher_str, "null"))
+ return NULL;
+
tfm = crypto_alloc_skcipher(mode->cipher_str, 0, 0);
if (IS_ERR(tfm)) {
if (PTR_ERR(tfm) == -ENOENT) {
llcrypt_put_direct_key(ci->ci_direct_key);
} else if ((ci->ci_ctfm != NULL || ci->ci_essiv_tfm != NULL) &&
!llcrypt_is_direct_key_policy(&ci->ci_policy)) {
- crypto_free_skcipher(ci->ci_ctfm);
+ if (ci->ci_ctfm)
+ crypto_free_skcipher(ci->ci_ctfm);
crypto_free_cipher(ci->ci_essiv_tfm);
}
u32 filenames_mode)
{
if (contents_mode == LLCRYPT_MODE_AES_128_CBC &&
- filenames_mode == LLCRYPT_MODE_AES_128_CTS)
+ (filenames_mode == LLCRYPT_MODE_AES_128_CTS ||
+ filenames_mode == LLCRYPT_MODE_NULL))
return true;
if (contents_mode == LLCRYPT_MODE_AES_256_XTS &&
- filenames_mode == LLCRYPT_MODE_AES_256_CTS)
+ (filenames_mode == LLCRYPT_MODE_AES_256_CTS ||
+ filenames_mode == LLCRYPT_MODE_NULL))
return true;
if (contents_mode == LLCRYPT_MODE_ADIANTUM &&
- filenames_mode == LLCRYPT_MODE_ADIANTUM)
+ (filenames_mode == LLCRYPT_MODE_ADIANTUM ||
+ filenames_mode == LLCRYPT_MODE_NULL))
return true;
return false;
}
EXPORT_SYMBOL(llcrypt_ioctl_get_policy);
+/* Valid filenames_encryption_mode associated with contents_encryption_mode,
+ * as imposed by llcrypt_valid_enc_modes()
+ */
+static inline u8 contents2filenames_encmode(u8 contents_encryption_mode)
+{
+ if (contents_encryption_mode == LLCRYPT_MODE_AES_128_CBC)
+ return LLCRYPT_MODE_AES_128_CTS;
+ if (contents_encryption_mode == LLCRYPT_MODE_AES_256_XTS)
+ return LLCRYPT_MODE_AES_256_CTS;
+ if (contents_encryption_mode == LLCRYPT_MODE_ADIANTUM)
+ return LLCRYPT_MODE_ADIANTUM;
+ return LLCRYPT_MODE_NULL;
+}
+
/* Extended ioctl version; can get policies of any version */
int llcrypt_ioctl_get_policy_ex(struct file *filp, void __user *uarg)
{
struct llcrypt_get_policy_ex_arg arg;
union llcrypt_policy *policy = (union llcrypt_policy *)&arg.policy;
size_t policy_size;
+ struct inode *inode = file_inode(filp);
int err;
/* arg is policy_size, then policy */
return -EOVERFLOW;
arg.policy_size = policy_size;
+ /* Do not return null filenames_encryption_mode to userspace, as it is
+ * unknown. Instead, return valid mode associated with
+ * contents_encryption_mode, as imposed by llcrypt_valid_enc_modes().
+ */
+ switch (policy->version) {
+ case LLCRYPT_POLICY_V1:
+ if (policy->v1.filenames_encryption_mode == LLCRYPT_MODE_NULL) {
+ policy->v1.filenames_encryption_mode =
+ contents2filenames_encmode(
+ policy->v1.contents_encryption_mode);
+ CWARN("inode %lu: returning policy filenames_encryption_mode as %d, but is in fact null\n",
+ inode->i_ino,
+ policy->v1.filenames_encryption_mode);
+ }
+ break;
+ case LLCRYPT_POLICY_V2:
+ if (policy->v2.filenames_encryption_mode == LLCRYPT_MODE_NULL) {
+ policy->v2.filenames_encryption_mode =
+ contents2filenames_encmode(
+ policy->v2.contents_encryption_mode);
+ CWARN("inode %lu: returning policy filenames_encryption_mode as %d, but is in fact null\n",
+ inode->i_ino,
+ policy->v2.filenames_encryption_mode);
+ }
+ break;
+ }
+
if (copy_to_user(uarg, &arg, sizeof(arg.policy_size) + policy_size))
return -EFAULT;
return 0;