Fix commit descrption
[ext4-patch-queue.git] / crypto-add-filename-padding
blob154762daf2a519c1817803eb93f2d58d61abbe51
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>
11 ---
12  fs/ext4/crypto_fname.c  | 12 ++++++++++--
13  fs/ext4/crypto_key.c    |  1 +
14  fs/ext4/crypto_policy.c | 14 +++++++++-----
15  fs/ext4/ext4.h          |  1 +
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,
24         int res = 0;
25         char iv[EXT4_CRYPTO_BLOCK_SIZE];
26         struct scatterlist sg[1];
27 +       int padding = 4 << (ctx->flags & EXT4_POLICY_FLAGS_PAD_MASK);
28         char *workbuf;
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 */
41         sg_init_table(sg, 1);
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(
49         if (IS_ERR(ctx))
50                 return 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,
57                                       u32 namelen)
58  {
59         u32 ciphertext_len;
60 +       int padding = 4 << (ctx->flags & EXT4_POLICY_FLAGS_PAD_MASK);
62         if (ctx == NULL)
63                 return -EIO;
64 @@ -475,6 +479,7 @@ int ext4_fname_crypto_namelen_on_disk(struct ext4_fname_crypto_ctx *ctx,
65                 return -EACCES;
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)
74  {
75         unsigned int olen;
76 +       int padding = 4 << (ctx->flags & EXT4_POLICY_FLAGS_PAD_MASK);
78         if (!ctx)
79                 return -EIO;
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)
92         }
93         res = 0;
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(
104                 return 0;
105         return (memcmp(ctx.master_key_descriptor, policy->master_key_descriptor,
106                         EXT4_KEY_DESCRIPTOR_SIZE) == 0 &&
107 +               (ctx.flags ==
108 +                policy->flags) &&
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(
113                 printk(KERN_WARNING
114                        "%s: Invalid contents encryption mode %d\n", __func__,
115                         policy->contents_encryption_mode);
116 -               res = -EINVAL;
117 -               goto out;
118 +               return -EINVAL;
119         }
120         if (!ext4_valid_filenames_enc_mode(policy->filenames_encryption_mode)) {
121                 printk(KERN_WARNING
122                        "%s: Invalid filenames encryption mode %d\n", __func__,
123                         policy->filenames_encryption_mode);
124 -               res = -EINVAL;
125 -               goto out;
126 +               return -EINVAL;
127         }
128 +       if (policy->flags & ~EXT4_POLICY_FLAGS_VALID)
129 +               return -EINVAL;
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,
138                              sizeof(ctx), 0);
139 -out:
140         if (!res)
141                 ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
142         return res;
143 @@ -115,6 +117,7 @@ int ext4_get_policy(struct inode *inode, struct ext4_encryption_policy *policy)
144         policy->version = 0;
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);
150         return 0;
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;
155 +                       ctx.flags = 0;
156                         memset(ctx.master_key_descriptor, 0x42,
157                                EXT4_KEY_DESCRIPTOR_SIZE);
158                         res = 0;
159 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
160 index dfb1138..bca1bdc 100644
161 --- a/fs/ext4/ext4.h
162 +++ b/fs/ext4/ext4.h
163 @@ -911,6 +911,7 @@ struct ext4_inode_info {
165         /* on-disk additional length */
166         __u16 i_extra_isize;
167 +       char i_crypt_policy_flags;
169         /* Indicate the inline data space. */
170         u16 i_inline_off;
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 {
176         char version;
177         char contents_encryption_mode;
178         char filenames_encryption_mode;
179 +       char flags;
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
193  /**
194   * Encryption context for inode
195   *
196 @@ -41,7 +49,7 @@ struct ext4_encryption_context {
197         char format;
198         char contents_encryption_mode;
199         char filenames_encryption_mode;
200 -       char reserved;
201 +       char flags;
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;
212  };