1 ext4 crypto: add padding to filenames before encrypting
3 This obscures the length of the filenames, to decrease the amount of
4 information leakage. By default, we pad the filenames to the next 4
5 byte boundaries. This costs nothing, since the directory entries are
6 aligned to 4 byte boundaries anyway. Filenames can also be padded to
7 8, 16, or 32 bytes, which will consume more directory space.
9 Change-Id: Ibb7a0fb76d2c48e2061240a709358ff40b14f322
10 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 fs/ext4/crypto_fname.c | 12 ++++++++++--
13 fs/ext4/crypto_key.c | 1 +
14 fs/ext4/crypto_policy.c | 14 +++++++++-----
16 fs/ext4/ext4_crypto.h | 11 ++++++++++-
17 5 files changed, 31 insertions(+), 8 deletions(-)
19 diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
20 index 7a877e6..fded02f 100644
21 --- a/fs/ext4/crypto_fname.c
22 +++ b/fs/ext4/crypto_fname.c
23 @@ -66,6 +66,7 @@ static int ext4_fname_encrypt(struct ext4_fname_crypto_ctx *ctx,
25 char iv[EXT4_CRYPTO_BLOCK_SIZE];
26 struct scatterlist sg[1];
27 + int padding = 4 << (ctx->flags & EXT4_POLICY_FLAGS_PAD_MASK);
30 if (iname->len <= 0 || iname->len > ctx->lim)
31 @@ -73,6 +74,7 @@ static int ext4_fname_encrypt(struct ext4_fname_crypto_ctx *ctx,
33 ciphertext_len = (iname->len < EXT4_CRYPTO_BLOCK_SIZE) ?
34 EXT4_CRYPTO_BLOCK_SIZE : iname->len;
35 + ciphertext_len = ext4_fname_crypto_round_up(ciphertext_len, padding);
36 ciphertext_len = (ciphertext_len > ctx->lim)
37 ? ctx->lim : ciphertext_len;
39 @@ -101,7 +103,7 @@ static int ext4_fname_encrypt(struct ext4_fname_crypto_ctx *ctx,
40 /* Create encryption request */
42 sg_set_page(sg, ctx->workpage, PAGE_SIZE, 0);
43 - ablkcipher_request_set_crypt(req, sg, sg, iname->len, iv);
44 + ablkcipher_request_set_crypt(req, sg, sg, ciphertext_len, iv);
45 res = crypto_ablkcipher_encrypt(req);
46 if (res == -EINPROGRESS || res == -EBUSY) {
47 BUG_ON(req->base.data != &ecr);
48 @@ -356,6 +358,7 @@ struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(
52 + ctx->flags = ei->i_crypt_policy_flags;
53 if (ctx->has_valid_key) {
54 if (ctx->key.mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) {
55 printk_once(KERN_WARNING
56 @@ -468,6 +471,7 @@ int ext4_fname_crypto_namelen_on_disk(struct ext4_fname_crypto_ctx *ctx,
60 + int padding = 4 << (ctx->flags & EXT4_POLICY_FLAGS_PAD_MASK);
64 @@ -475,6 +479,7 @@ int ext4_fname_crypto_namelen_on_disk(struct ext4_fname_crypto_ctx *ctx,
66 ciphertext_len = (namelen < EXT4_CRYPTO_BLOCK_SIZE) ?
67 EXT4_CRYPTO_BLOCK_SIZE : namelen;
68 + ciphertext_len = ext4_fname_crypto_round_up(ciphertext_len, padding);
69 ciphertext_len = (ciphertext_len > ctx->lim)
70 ? ctx->lim : ciphertext_len;
71 return (int) ciphertext_len;
72 @@ -490,10 +495,13 @@ int ext4_fname_crypto_alloc_buffer(struct ext4_fname_crypto_ctx *ctx,
73 u32 ilen, struct ext4_str *crypto_str)
76 + int padding = 4 << (ctx->flags & EXT4_POLICY_FLAGS_PAD_MASK);
80 - olen = ext4_fname_crypto_round_up(ilen, EXT4_CRYPTO_BLOCK_SIZE);
81 + if (padding < EXT4_CRYPTO_BLOCK_SIZE)
82 + padding = EXT4_CRYPTO_BLOCK_SIZE;
83 + olen = ext4_fname_crypto_round_up(ilen, padding);
84 crypto_str->len = olen;
85 if (olen < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2)
86 olen = EXT4_FNAME_CRYPTO_DIGEST_SIZE*2;
87 diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
88 index c8392af..52170d0 100644
89 --- a/fs/ext4/crypto_key.c
90 +++ b/fs/ext4/crypto_key.c
91 @@ -110,6 +110,7 @@ int ext4_generate_encryption_key(struct inode *inode)
95 + ei->i_crypt_policy_flags = ctx.flags;
96 if (S_ISREG(inode->i_mode))
97 crypt_key->mode = ctx.contents_encryption_mode;
98 else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
99 diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c
100 index 30eaf9e..a6d6291 100644
101 --- a/fs/ext4/crypto_policy.c
102 +++ b/fs/ext4/crypto_policy.c
103 @@ -37,6 +37,8 @@ static int ext4_is_encryption_context_consistent_with_policy(
105 return (memcmp(ctx.master_key_descriptor, policy->master_key_descriptor,
106 EXT4_KEY_DESCRIPTOR_SIZE) == 0 &&
109 (ctx.contents_encryption_mode ==
110 policy->contents_encryption_mode) &&
111 (ctx.filenames_encryption_mode ==
112 @@ -56,25 +58,25 @@ static int ext4_create_encryption_context_from_policy(
114 "%s: Invalid contents encryption mode %d\n", __func__,
115 policy->contents_encryption_mode);
120 if (!ext4_valid_filenames_enc_mode(policy->filenames_encryption_mode)) {
122 "%s: Invalid filenames encryption mode %d\n", __func__,
123 policy->filenames_encryption_mode);
128 + if (policy->flags & ~EXT4_POLICY_FLAGS_VALID)
130 ctx.contents_encryption_mode = policy->contents_encryption_mode;
131 ctx.filenames_encryption_mode = policy->filenames_encryption_mode;
132 + ctx.flags = policy->flags;
133 BUILD_BUG_ON(sizeof(ctx.nonce) != EXT4_KEY_DERIVATION_NONCE_SIZE);
134 get_random_bytes(ctx.nonce, EXT4_KEY_DERIVATION_NONCE_SIZE);
136 res = ext4_xattr_set(inode, EXT4_XATTR_INDEX_ENCRYPTION,
137 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx,
141 ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
143 @@ -115,6 +117,7 @@ int ext4_get_policy(struct inode *inode, struct ext4_encryption_policy *policy)
145 policy->contents_encryption_mode = ctx.contents_encryption_mode;
146 policy->filenames_encryption_mode = ctx.filenames_encryption_mode;
147 + policy->flags = ctx.flags;
148 memcpy(&policy->master_key_descriptor, ctx.master_key_descriptor,
149 EXT4_KEY_DESCRIPTOR_SIZE);
151 @@ -176,6 +179,7 @@ int ext4_inherit_context(struct inode *parent, struct inode *child)
152 EXT4_ENCRYPTION_MODE_AES_256_XTS;
153 ctx.filenames_encryption_mode =
154 EXT4_ENCRYPTION_MODE_AES_256_CTS;
156 memset(ctx.master_key_descriptor, 0x42,
157 EXT4_KEY_DESCRIPTOR_SIZE);
159 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
160 index dfb1138..bca1bdc 100644
163 @@ -911,6 +911,7 @@ struct ext4_inode_info {
165 /* on-disk additional length */
167 + char i_crypt_policy_flags;
169 /* Indicate the inline data space. */
171 diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h
172 index c2ba35a..d75159c 100644
173 --- a/fs/ext4/ext4_crypto.h
174 +++ b/fs/ext4/ext4_crypto.h
175 @@ -20,12 +20,20 @@ struct ext4_encryption_policy {
177 char contents_encryption_mode;
178 char filenames_encryption_mode;
180 char master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE];
181 } __attribute__((__packed__));
183 #define EXT4_ENCRYPTION_CONTEXT_FORMAT_V1 1
184 #define EXT4_KEY_DERIVATION_NONCE_SIZE 16
186 +#define EXT4_POLICY_FLAGS_PAD_4 0x00
187 +#define EXT4_POLICY_FLAGS_PAD_8 0x01
188 +#define EXT4_POLICY_FLAGS_PAD_16 0x02
189 +#define EXT4_POLICY_FLAGS_PAD_32 0x03
190 +#define EXT4_POLICY_FLAGS_PAD_MASK 0x03
191 +#define EXT4_POLICY_FLAGS_VALID 0x03
194 * Encryption context for inode
196 @@ -41,7 +49,7 @@ struct ext4_encryption_context {
198 char contents_encryption_mode;
199 char filenames_encryption_mode;
202 char master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE];
203 char nonce[EXT4_KEY_DERIVATION_NONCE_SIZE];
204 } __attribute__((__packed__));
205 @@ -120,6 +128,7 @@ struct ext4_fname_crypto_ctx {
206 struct crypto_hash *htfm;
207 struct page *workpage;
208 struct ext4_encryption_key key;
209 + unsigned flags : 8;
210 unsigned has_valid_key : 1;
211 unsigned ctfm_key_is_ready : 1;