Whamcloud - gitweb
LU-16374 enc: align Base64 encoding with RFC 4648 base64url
[fs/lustre-release.git] / libcfs / libcfs / crypto / fname.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * This contains functions for filename crypto management
4  *
5  * Copyright (C) 2015, Google, Inc.
6  * Copyright (C) 2015, Motorola Mobility
7  *
8  * Written by Uday Savagaonkar, 2014.
9  * Modified by Jaegeuk Kim, 2015.
10  *
11  * This has not yet undergone a rigorous security audit.
12  */
13 /*
14  * Linux commit 219d54332a09
15  * tags/v5.4
16  */
17
18 #include <linux/scatterlist.h>
19 #include <crypto/skcipher.h>
20 #include "llcrypt_private.h"
21
22 static inline bool llcrypt_is_dot_dotdot(const struct qstr *str)
23 {
24         if (str->len == 1 && str->name[0] == '.')
25                 return true;
26
27         if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
28                 return true;
29
30         return false;
31 }
32
33 /**
34  * fname_encrypt() - encrypt a filename
35  *
36  * The output buffer must be at least as large as the input buffer.
37  * Any extra space is filled with NUL padding before encryption.
38  *
39  * Return: 0 on success, -errno on failure
40  */
41 int fname_encrypt(struct inode *inode, const struct qstr *iname,
42                   u8 *out, unsigned int olen)
43 {
44         struct skcipher_request *req = NULL;
45         DECLARE_CRYPTO_WAIT(wait);
46         struct llcrypt_info *ci = llcrypt_info(inode);
47         struct crypto_skcipher *tfm = ci->ci_ctfm;
48         union llcrypt_iv iv;
49         struct scatterlist sg;
50         int res;
51
52         /*
53          * Copy the filename to the output buffer for encrypting in-place and
54          * pad it with the needed number of NUL bytes.
55          */
56         if (WARN_ON(olen < iname->len))
57                 return -ENOBUFS;
58         memcpy(out, iname->name, iname->len);
59         memset(out + iname->len, 0, olen - iname->len);
60
61         if (tfm == NULL)
62                 return 0;
63
64         /* Initialize the IV */
65         llcrypt_generate_iv(&iv, 0, ci);
66
67         /* Set up the encryption request */
68         req = skcipher_request_alloc(tfm, GFP_NOFS);
69         if (!req)
70                 return -ENOMEM;
71         skcipher_request_set_callback(req,
72                         CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
73                         crypto_req_done, &wait);
74         sg_init_one(&sg, out, olen);
75         skcipher_request_set_crypt(req, &sg, &sg, olen, &iv);
76
77         /* Do the encryption */
78         res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
79         skcipher_request_free(req);
80         if (res < 0) {
81                 llcrypt_err(inode, "Filename encryption failed: %d", res);
82                 return res;
83         }
84
85         return 0;
86 }
87
88 /**
89  * fname_decrypt() - decrypt a filename
90  *
91  * The caller must have allocated sufficient memory for the @oname string.
92  *
93  * Return: 0 on success, -errno on failure
94  */
95 static int fname_decrypt(struct inode *inode,
96                                 const struct llcrypt_str *iname,
97                                 struct llcrypt_str *oname)
98 {
99         struct skcipher_request *req = NULL;
100         DECLARE_CRYPTO_WAIT(wait);
101         struct scatterlist src_sg, dst_sg;
102         struct llcrypt_info *ci = llcrypt_info(inode);
103         struct crypto_skcipher *tfm = ci->ci_ctfm;
104         union llcrypt_iv iv;
105         int res;
106
107         if (tfm == NULL) {
108                 memcpy(oname->name, iname->name, iname->len);
109                 oname->name[iname->len] = '\0';
110                 oname->len = iname->len;
111                 return 0;
112         }
113
114         /* Allocate request */
115         req = skcipher_request_alloc(tfm, GFP_NOFS);
116         if (!req)
117                 return -ENOMEM;
118         skcipher_request_set_callback(req,
119                 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
120                 crypto_req_done, &wait);
121
122         /* Initialize IV */
123         llcrypt_generate_iv(&iv, 0, ci);
124
125         /* Create decryption request */
126         sg_init_one(&src_sg, iname->name, iname->len);
127         sg_init_one(&dst_sg, oname->name, oname->len);
128         skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, &iv);
129         res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
130         skcipher_request_free(req);
131         if (res < 0) {
132                 llcrypt_err(inode, "Filename decryption failed: %d", res);
133                 return res;
134         }
135
136         oname->len = strnlen(oname->name, iname->len);
137         return 0;
138 }
139
140 /*
141  * Old fashion base64 encoding, taken from Linux 5.4.
142  *
143  * This base64 encoding is specific to fscrypt and has been replaced since then
144  * with an RFC 4648 compliant base64-url encoding, see llcrypt_base64url_*
145  * below.
146  * The old fashion base64 encoding is kept for compatibility with older clients.
147  */
148
149 static const char lookup_table[65] =
150         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
151
152 #define LLCRYPT_BASE64_CHARS(nbytes)    DIV_ROUND_UP((nbytes) * 4, 3)
153
154 /**
155  * base64_encode() -
156  *
157  * Encodes the input string using characters from the set [A-Za-z0-9+,].
158  * The encoded string is roughly 4/3 times the size of the input string.
159  *
160  * Return: length of the encoded string
161  */
162 static inline int llcrypt_base64_encode(const u8 *src, int len, char *dst)
163 {
164         int i, bits = 0, ac = 0;
165         char *cp = dst;
166
167         for (i = 0; i < len; i++) {
168                 ac += src[i] << bits;
169                 bits += 8;
170                 do {
171                         *cp++ = lookup_table[ac & 0x3f];
172                         ac >>= 6;
173                         bits -= 6;
174                 } while (bits >= 6);
175         }
176         if (bits)
177                 *cp++ = lookup_table[ac & 0x3f];
178         return cp - dst;
179 }
180
181 static inline int llcrypt_base64_decode(const char *src, int len, u8 *dst)
182 {
183         int i, bits = 0, ac = 0;
184         const char *p;
185         u8 *cp = dst;
186
187         for (i = 0; i < len; i++) {
188                 p = strchr(lookup_table, src[i]);
189                 if (p == NULL || src[i] == 0)
190                         return -2;
191                 ac += (p - lookup_table) << bits;
192                 bits += 6;
193                 if (bits >= 8) {
194                         *cp++ = ac & 0xff;
195                         ac >>= 8;
196                         bits -= 8;
197                 }
198         }
199         if (ac)
200                 return -1;
201         return cp - dst;
202 }
203
204 /*
205  * New fashion base64 encoding, taken from Linux 5.14.
206  *
207  * This base64 encoding is RFC 4648 compliant base64-url encoding.
208  */
209
210 static const char base64url_table[] =
211         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
212
213 #define LLCRYPT_BASE64URL_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)
214
215 /**
216  * llcrypt_base64url_encode() - base64url-encode some binary data
217  * @src: the binary data to encode
218  * @srclen: the length of @src in bytes
219  * @dst: (output) the base64url-encoded string.  Not NUL-terminated.
220  *
221  * Encodes data using base64url encoding, i.e. the "Base 64 Encoding with URL
222  * and Filename Safe Alphabet" specified by RFC 4648.  '='-padding isn't used,
223  * as it's unneeded and not required by the RFC.  base64url is used instead of
224  * base64 to avoid the '/' character, which isn't allowed in filenames.
225  *
226  * Return: the length of the resulting base64url-encoded string in bytes.
227  *         This will be equal to LLCRYPT_BASE64URL_CHARS(srclen).
228  */
229 static inline int llcrypt_base64url_encode(const u8 *src, int srclen, char *dst)
230 {
231         u32 ac = 0;
232         int bits = 0;
233         int i;
234         char *cp = dst;
235
236         for (i = 0; i < srclen; i++) {
237                 ac = (ac << 8) | src[i];
238                 bits += 8;
239                 do {
240                         bits -= 6;
241                         *cp++ = base64url_table[(ac >> bits) & 0x3f];
242                 } while (bits >= 6);
243         }
244         if (bits)
245                 *cp++ = base64url_table[(ac << (6 - bits)) & 0x3f];
246         return cp - dst;
247 }
248
249 /**
250  * llcrypt_base64url_decode() - base64url-decode a string
251  * @src: the string to decode.  Doesn't need to be NUL-terminated.
252  * @srclen: the length of @src in bytes
253  * @dst: (output) the decoded binary data
254  *
255  * Decodes a string using base64url encoding, i.e. the "Base 64 Encoding with
256  * URL and Filename Safe Alphabet" specified by RFC 4648.  '='-padding isn't
257  * accepted, nor are non-encoding characters such as whitespace.
258  *
259  * This implementation hasn't been optimized for performance.
260  *
261  * Return: the length of the resulting decoded binary data in bytes,
262  *         or -1 if the string isn't a valid base64url string.
263  */
264 static inline int llcrypt_base64url_decode(const char *src, int srclen, u8 *dst)
265 {
266         u32 ac = 0;
267         int bits = 0;
268         int i;
269         u8 *bp = dst;
270
271         for (i = 0; i < srclen; i++) {
272                 const char *p = strchr(base64url_table, src[i]);
273
274                 if (p == NULL || src[i] == 0)
275                         return -1;
276                 ac = (ac << 6) | (p - base64url_table);
277                 bits += 6;
278                 if (bits >= 8) {
279                         bits -= 8;
280                         *bp++ = (u8)(ac >> bits);
281                 }
282         }
283         if (ac & ((1 << bits) - 1))
284                 return -1;
285         return bp - dst;
286 }
287
288 static inline int base64_chars(struct lustre_sb_info *lsi, int nbytes)
289 {
290         if (!(lsi->lsi_flags & LSI_FILENAME_ENC_B64_OLD_CLI))
291                 return LLCRYPT_BASE64URL_CHARS(nbytes);
292         else
293                 return LLCRYPT_BASE64_CHARS(nbytes);
294 }
295
296 bool llcrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
297                                   u32 max_len, u32 *encrypted_len_ret)
298 {
299         const struct llcrypt_info *ci = llcrypt_info(inode);
300         struct crypto_skcipher *tfm = ci->ci_ctfm;
301         int padding = 4 << (llcrypt_policy_flags(&ci->ci_policy) &
302                             LLCRYPT_POLICY_FLAGS_PAD_MASK);
303         u32 encrypted_len;
304
305         if (orig_len > max_len)
306                 return false;
307         if (tfm == NULL) {
308                 *encrypted_len_ret = orig_len;
309         } else {
310                 encrypted_len = max(orig_len, (u32)LL_CRYPTO_BLOCK_SIZE);
311                 encrypted_len = round_up(encrypted_len, padding);
312                 *encrypted_len_ret = min(encrypted_len, max_len);
313         }
314         return true;
315 }
316
317 /**
318  * llcrypt_fname_alloc_buffer - allocate a buffer for presented filenames
319  *
320  * Allocate a buffer that is large enough to hold any decrypted or encoded
321  * filename (null-terminated), for the given maximum encrypted filename length.
322  *
323  * Return: 0 on success, -errno on failure
324  */
325 int llcrypt_fname_alloc_buffer(const struct inode *inode,
326                                u32 max_encrypted_len,
327                                struct llcrypt_str *crypto_str)
328 {
329         struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
330         const u32 max_encoded_len =
331                 max_t(u32,
332                    base64_chars(lsi, LLCRYPT_FNAME_MAX_UNDIGESTED_SIZE),
333                    1 + base64_chars(lsi, sizeof(struct llcrypt_digested_name)));
334         u32 max_presented_len;
335
336         max_presented_len = max(max_encoded_len, max_encrypted_len);
337
338         crypto_str->name = kmalloc(max_presented_len + 1, GFP_NOFS);
339         if (!crypto_str->name)
340                 return -ENOMEM;
341         crypto_str->len = max_presented_len;
342         return 0;
343 }
344 EXPORT_SYMBOL(llcrypt_fname_alloc_buffer);
345
346 /**
347  * llcrypt_fname_free_buffer - free the buffer for presented filenames
348  *
349  * Free the buffer allocated by llcrypt_fname_alloc_buffer().
350  */
351 void llcrypt_fname_free_buffer(struct llcrypt_str *crypto_str)
352 {
353         if (!crypto_str)
354                 return;
355         kfree(crypto_str->name);
356         crypto_str->name = NULL;
357 }
358 EXPORT_SYMBOL(llcrypt_fname_free_buffer);
359
360 /**
361  * llcrypt_fname_disk_to_usr() - converts a filename from disk space to user
362  * space
363  *
364  * The caller must have allocated sufficient memory for the @oname string.
365  *
366  * If the key is available, we'll decrypt the disk name; otherwise, we'll encode
367  * it for presentation.  Short names are directly base64-encoded, while long
368  * names are encoded in llcrypt_digested_name format.
369  *
370  * Return: 0 on success, -errno on failure
371  */
372 int llcrypt_fname_disk_to_usr(struct inode *inode,
373                         u32 hash, u32 minor_hash,
374                         const struct llcrypt_str *iname,
375                         struct llcrypt_str *oname)
376 {
377         int (*b64_encode)(const u8 *src, int srclen, char *dst);
378         struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
379         const struct qstr qname = LLTR_TO_QSTR(iname);
380         struct llcrypt_digested_name digested_name;
381
382         if (llcrypt_is_dot_dotdot(&qname)) {
383                 oname->name[0] = '.';
384                 oname->name[iname->len - 1] = '.';
385                 oname->len = iname->len;
386                 return 0;
387         }
388
389         if (llcrypt_has_encryption_key(inode)) {
390                 struct llcrypt_info *ci = llcrypt_info(inode);
391                 struct crypto_skcipher *tfm = ci->ci_ctfm;
392
393                 if (tfm && iname->len < LL_CRYPTO_BLOCK_SIZE)
394                         return -EUCLEAN;
395
396                 return fname_decrypt(inode, iname, oname);
397         }
398
399         if (!llcrypt_policy_has_filename_enc(inode)) {
400                 memcpy(oname->name, iname->name, iname->len);
401                 oname->name[iname->len] = '\0';
402                 oname->len = iname->len;
403                 return 0;
404         }
405
406         if (!(lsi->lsi_flags & LSI_FILENAME_ENC_B64_OLD_CLI))
407                 b64_encode = llcrypt_base64url_encode;
408         else
409                 b64_encode = llcrypt_base64_encode;
410
411         if (iname->len <= LLCRYPT_FNAME_MAX_UNDIGESTED_SIZE) {
412                 oname->len = b64_encode(iname->name, iname->len, oname->name);
413                 return 0;
414         }
415         if (hash) {
416                 digested_name.hash = hash;
417                 digested_name.minor_hash = minor_hash;
418         } else {
419                 digested_name.hash = 0;
420                 digested_name.minor_hash = 0;
421         }
422         memcpy(digested_name.digest,
423                LLCRYPT_FNAME_DIGEST(iname->name, iname->len),
424                LLCRYPT_FNAME_DIGEST_SIZE);
425         if (!(lsi->lsi_flags & LSI_FILENAME_ENC_B64_OLD_CLI))
426                 oname->name[0] = LLCRYPT_DIGESTED_CHAR;
427         else
428                 oname->name[0] = LLCRYPT_DIGESTED_CHAR_OLD;
429         oname->len = 1 + b64_encode((const u8 *)&digested_name,
430                                     sizeof(digested_name), oname->name + 1);
431         return 0;
432 }
433 EXPORT_SYMBOL(llcrypt_fname_disk_to_usr);
434
435 /**
436  * llcrypt_setup_filename() - prepare to search a possibly encrypted directory
437  * @dir: the directory that will be searched
438  * @iname: the user-provided filename being searched for
439  * @lookup: 1 if we're allowed to proceed without the key because it's
440  *      ->lookup() or we're finding the dir_entry for deletion; 0 if we cannot
441  *      proceed without the key because we're going to create the dir_entry.
442  * @fname: the filename information to be filled in
443  *
444  * Given a user-provided filename @iname, this function sets @fname->disk_name
445  * to the name that would be stored in the on-disk directory entry, if possible.
446  * If the directory is unencrypted this is simply @iname.  Else, if we have the
447  * directory's encryption key, then @iname is the plaintext, so we encrypt it to
448  * get the disk_name.
449  *
450  * Else, for keyless @lookup operations, @iname is the presented ciphertext, so
451  * we decode it to get either the ciphertext disk_name (for short names) or the
452  * llcrypt_digested_name (for long names).  Non-@lookup operations will be
453  * impossible in this case, so we fail them with ENOKEY.
454  *
455  * If successful, llcrypt_free_filename() must be called later to clean up.
456  *
457  * Return: 0 on success, -errno on failure
458  */
459 int llcrypt_setup_filename(struct inode *dir, const struct qstr *iname,
460                               int lookup, struct llcrypt_name *fname)
461 {
462         struct lustre_sb_info *lsi = s2lsi(dir->i_sb);
463         int ret;
464         int digested;
465
466         memset(fname, 0, sizeof(struct llcrypt_name));
467         fname->usr_fname = iname;
468
469         if (!IS_ENCRYPTED(dir) || llcrypt_is_dot_dotdot(iname)) {
470                 fname->disk_name.name = (unsigned char *)iname->name;
471                 fname->disk_name.len = iname->len;
472                 return 0;
473         }
474         ret = llcrypt_get_encryption_info(dir);
475         if (ret)
476                 return ret;
477
478         if (llcrypt_has_encryption_key(dir)) {
479                 struct lustre_sb_info *lsi = s2lsi(dir->i_sb);
480
481                 if (!llcrypt_fname_encrypted_size(dir, iname->len,
482                                                   lsi ?
483                                                     lsi->lsi_cop->max_namelen :
484                                                     NAME_MAX,
485                                                   &fname->crypto_buf.len))
486                         return -ENAMETOOLONG;
487                 fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,
488                                                  GFP_NOFS);
489                 if (!fname->crypto_buf.name)
490                         return -ENOMEM;
491
492                 ret = fname_encrypt(dir, iname, fname->crypto_buf.name,
493                                     fname->crypto_buf.len);
494                 if (ret)
495                         goto errout;
496                 fname->disk_name.name = fname->crypto_buf.name;
497                 fname->disk_name.len = fname->crypto_buf.len;
498                 return 0;
499         }
500         if (!lookup)
501                 return -ENOKEY;
502
503         if (!llcrypt_policy_has_filename_enc(dir)) {
504                 fname->disk_name.name = (unsigned char *)iname->name;
505                 fname->disk_name.len = iname->len;
506                 return 0;
507         }
508
509         fname->is_ciphertext_name = true;
510
511         /*
512          * We don't have the key and we are doing a lookup; decode the
513          * user-supplied name
514          */
515         if ((!(lsi->lsi_flags & LSI_FILENAME_ENC_B64_OLD_CLI) &&
516              iname->name[0] == LLCRYPT_DIGESTED_CHAR) ||
517             ((lsi->lsi_flags & LSI_FILENAME_ENC_B64_OLD_CLI) &&
518              iname->name[0] == LLCRYPT_DIGESTED_CHAR_OLD)) {
519                 if (iname->len != 1 + base64_chars(lsi,
520                                         sizeof(struct llcrypt_digested_name))) {
521                         return -ENOENT;
522                 }
523                 digested = 1;
524         } else {
525                 if (iname->len >
526                     base64_chars(lsi, LLCRYPT_FNAME_MAX_UNDIGESTED_SIZE))
527                         return -ENOENT;
528                 digested = 0;
529         }
530
531         fname->crypto_buf.name =
532                 kmalloc(max_t(size_t, LLCRYPT_FNAME_MAX_UNDIGESTED_SIZE,
533                               sizeof(struct llcrypt_digested_name)),
534                         GFP_KERNEL);
535         if (fname->crypto_buf.name == NULL)
536                 return -ENOMEM;
537
538         if (!(lsi->lsi_flags & LSI_FILENAME_ENC_B64_OLD_CLI))
539                 ret = llcrypt_base64url_decode(iname->name + digested,
540                                                iname->len - digested,
541                                                fname->crypto_buf.name);
542         else
543                 ret = llcrypt_base64_decode(iname->name + digested,
544                                             iname->len - digested,
545                                             fname->crypto_buf.name);
546
547         if (ret < 0) {
548                 ret = -ENOENT;
549                 goto errout;
550         }
551         fname->crypto_buf.len = ret;
552         if (digested) {
553                 const struct llcrypt_digested_name *n =
554                         (const void *)fname->crypto_buf.name;
555                 fname->hash = n->hash;
556                 fname->minor_hash = n->minor_hash;
557         } else {
558                 fname->disk_name.name = fname->crypto_buf.name;
559                 fname->disk_name.len = fname->crypto_buf.len;
560         }
561         return 0;
562
563 errout:
564         kfree(fname->crypto_buf.name);
565         return ret;
566 }
567 EXPORT_SYMBOL(llcrypt_setup_filename);