linux/fs/ext4/crypto_fname.c
<<
>>
Prefs
   1/*
   2 * linux/fs/ext4/crypto_fname.c
   3 *
   4 * Copyright (C) 2015, Google, Inc.
   5 *
   6 * This contains functions for filename crypto management in ext4
   7 *
   8 * Written by Uday Savagaonkar, 2014.
   9 *
  10 * This has not yet undergone a rigorous security audit.
  11 *
  12 */
  13
  14#include <crypto/skcipher.h>
  15#include <keys/encrypted-type.h>
  16#include <keys/user-type.h>
  17#include <linux/gfp.h>
  18#include <linux/kernel.h>
  19#include <linux/key.h>
  20#include <linux/list.h>
  21#include <linux/mempool.h>
  22#include <linux/random.h>
  23#include <linux/scatterlist.h>
  24#include <linux/spinlock_types.h>
  25
  26#include "ext4.h"
  27#include "ext4_crypto.h"
  28#include "xattr.h"
  29
  30/**
  31 * ext4_dir_crypt_complete() -
  32 */
  33static void ext4_dir_crypt_complete(struct crypto_async_request *req, int res)
  34{
  35        struct ext4_completion_result *ecr = req->data;
  36
  37        if (res == -EINPROGRESS)
  38                return;
  39        ecr->res = res;
  40        complete(&ecr->completion);
  41}
  42
  43bool ext4_valid_filenames_enc_mode(uint32_t mode)
  44{
  45        return (mode == EXT4_ENCRYPTION_MODE_AES_256_CTS);
  46}
  47
  48static unsigned max_name_len(struct inode *inode)
  49{
  50        return S_ISLNK(inode->i_mode) ? inode->i_sb->s_blocksize :
  51                EXT4_NAME_LEN;
  52}
  53
  54/**
  55 * ext4_fname_encrypt() -
  56 *
  57 * This function encrypts the input filename, and returns the length of the
  58 * ciphertext. Errors are returned as negative numbers.  We trust the caller to
  59 * allocate sufficient memory to oname string.
  60 */
  61static int ext4_fname_encrypt(struct inode *inode,
  62                              const struct qstr *iname,
  63                              struct ext4_str *oname)
  64{
  65        u32 ciphertext_len;
  66        struct skcipher_request *req = NULL;
  67        DECLARE_EXT4_COMPLETION_RESULT(ecr);
  68        struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
  69        struct crypto_skcipher *tfm = ci->ci_ctfm;
  70        int res = 0;
  71        char iv[EXT4_CRYPTO_BLOCK_SIZE];
  72        struct scatterlist src_sg, dst_sg;
  73        int padding = 4 << (ci->ci_flags & EXT4_POLICY_FLAGS_PAD_MASK);
  74        char *workbuf, buf[32], *alloc_buf = NULL;
  75        unsigned lim = max_name_len(inode);
  76
  77        if (iname->len <= 0 || iname->len > lim)
  78                return -EIO;
  79
  80        ciphertext_len = (iname->len < EXT4_CRYPTO_BLOCK_SIZE) ?
  81                EXT4_CRYPTO_BLOCK_SIZE : iname->len;
  82        ciphertext_len = ext4_fname_crypto_round_up(ciphertext_len, padding);
  83        ciphertext_len = (ciphertext_len > lim)
  84                        ? lim : ciphertext_len;
  85
  86        if (ciphertext_len <= sizeof(buf)) {
  87                workbuf = buf;
  88        } else {
  89                alloc_buf = kmalloc(ciphertext_len, GFP_NOFS);
  90                if (!alloc_buf)
  91                        return -ENOMEM;
  92                workbuf = alloc_buf;
  93        }
  94
  95        /* Allocate request */
  96        req = skcipher_request_alloc(tfm, GFP_NOFS);
  97        if (!req) {
  98                printk_ratelimited(
  99                    KERN_ERR "%s: crypto_request_alloc() failed\n", __func__);
 100                kfree(alloc_buf);
 101                return -ENOMEM;
 102        }
 103        skcipher_request_set_callback(req,
 104                CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
 105                ext4_dir_crypt_complete, &ecr);
 106
 107        /* Copy the input */
 108        memcpy(workbuf, iname->name, iname->len);
 109        if (iname->len < ciphertext_len)
 110                memset(workbuf + iname->len, 0, ciphertext_len - iname->len);
 111
 112        /* Initialize IV */
 113        memset(iv, 0, EXT4_CRYPTO_BLOCK_SIZE);
 114
 115        /* Create encryption request */
 116        sg_init_one(&src_sg, workbuf, ciphertext_len);
 117        sg_init_one(&dst_sg, oname->name, ciphertext_len);
 118        skcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv);
 119        res = crypto_skcipher_encrypt(req);
 120        if (res == -EINPROGRESS || res == -EBUSY) {
 121                wait_for_completion(&ecr.completion);
 122                res = ecr.res;
 123        }
 124        kfree(alloc_buf);
 125        skcipher_request_free(req);
 126        if (res < 0) {
 127                printk_ratelimited(
 128                    KERN_ERR "%s: Error (error code %d)\n", __func__, res);
 129        }
 130        oname->len = ciphertext_len;
 131        return res;
 132}
 133
 134/*
 135 * ext4_fname_decrypt()
 136 *      This function decrypts the input filename, and returns
 137 *      the length of the plaintext.
 138 *      Errors are returned as negative numbers.
 139 *      We trust the caller to allocate sufficient memory to oname string.
 140 */
 141static int ext4_fname_decrypt(struct inode *inode,
 142                              const struct ext4_str *iname,
 143                              struct ext4_str *oname)
 144{
 145        struct ext4_str tmp_in[2], tmp_out[1];
 146        struct skcipher_request *req = NULL;
 147        DECLARE_EXT4_COMPLETION_RESULT(ecr);
 148        struct scatterlist src_sg, dst_sg;
 149        struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
 150        struct crypto_skcipher *tfm = ci->ci_ctfm;
 151        int res = 0;
 152        char iv[EXT4_CRYPTO_BLOCK_SIZE];
 153        unsigned lim = max_name_len(inode);
 154
 155        if (iname->len <= 0 || iname->len > lim)
 156                return -EIO;
 157
 158        tmp_in[0].name = iname->name;
 159        tmp_in[0].len = iname->len;
 160        tmp_out[0].name = oname->name;
 161
 162        /* Allocate request */
 163        req = skcipher_request_alloc(tfm, GFP_NOFS);
 164        if (!req) {
 165                printk_ratelimited(
 166                    KERN_ERR "%s: crypto_request_alloc() failed\n",  __func__);
 167                return -ENOMEM;
 168        }
 169        skcipher_request_set_callback(req,
 170                CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
 171                ext4_dir_crypt_complete, &ecr);
 172
 173        /* Initialize IV */
 174        memset(iv, 0, EXT4_CRYPTO_BLOCK_SIZE);
 175
 176        /* Create encryption request */
 177        sg_init_one(&src_sg, iname->name, iname->len);
 178        sg_init_one(&dst_sg, oname->name, oname->len);
 179        skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
 180        res = crypto_skcipher_decrypt(req);
 181        if (res == -EINPROGRESS || res == -EBUSY) {
 182                wait_for_completion(&ecr.completion);
 183                res = ecr.res;
 184        }
 185        skcipher_request_free(req);
 186        if (res < 0) {
 187                printk_ratelimited(
 188                    KERN_ERR "%s: Error in ext4_fname_encrypt (error code %d)\n",
 189                    __func__, res);
 190                return res;
 191        }
 192
 193        oname->len = strnlen(oname->name, iname->len);
 194        return oname->len;
 195}
 196
 197static const char *lookup_table =
 198        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
 199
 200/**
 201 * ext4_fname_encode_digest() -
 202 *
 203 * Encodes the input digest using characters from the set [a-zA-Z0-9_+].
 204 * The encoded string is roughly 4/3 times the size of the input string.
 205 */
 206static int digest_encode(const char *src, int len, char *dst)
 207{
 208        int i = 0, bits = 0, ac = 0;
 209        char *cp = dst;
 210
 211        while (i < len) {
 212                ac += (((unsigned char) src[i]) << bits);
 213                bits += 8;
 214                do {
 215                        *cp++ = lookup_table[ac & 0x3f];
 216                        ac >>= 6;
 217                        bits -= 6;
 218                } while (bits >= 6);
 219                i++;
 220        }
 221        if (bits)
 222                *cp++ = lookup_table[ac & 0x3f];
 223        return cp - dst;
 224}
 225
 226static int digest_decode(const char *src, int len, char *dst)
 227{
 228        int i = 0, bits = 0, ac = 0;
 229        const char *p;
 230        char *cp = dst;
 231
 232        while (i < len) {
 233                p = strchr(lookup_table, src[i]);
 234                if (p == NULL || src[i] == 0)
 235                        return -2;
 236                ac += (p - lookup_table) << bits;
 237                bits += 6;
 238                if (bits >= 8) {
 239                        *cp++ = ac & 0xff;
 240                        ac >>= 8;
 241                        bits -= 8;
 242                }
 243                i++;
 244        }
 245        if (ac)
 246                return -1;
 247        return cp - dst;
 248}
 249
 250/**
 251 * ext4_fname_crypto_round_up() -
 252 *
 253 * Return: The next multiple of block size
 254 */
 255u32 ext4_fname_crypto_round_up(u32 size, u32 blksize)
 256{
 257        return ((size+blksize-1)/blksize)*blksize;
 258}
 259
 260unsigned ext4_fname_encrypted_size(struct inode *inode, u32 ilen)
 261{
 262        struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
 263        int padding = 32;
 264
 265        if (ci)
 266                padding = 4 << (ci->ci_flags & EXT4_POLICY_FLAGS_PAD_MASK);
 267        if (ilen < EXT4_CRYPTO_BLOCK_SIZE)
 268                ilen = EXT4_CRYPTO_BLOCK_SIZE;
 269        return ext4_fname_crypto_round_up(ilen, padding);
 270}
 271
 272/*
 273 * ext4_fname_crypto_alloc_buffer() -
 274 *
 275 * Allocates an output buffer that is sufficient for the crypto operation
 276 * specified by the context and the direction.
 277 */
 278int ext4_fname_crypto_alloc_buffer(struct inode *inode,
 279                                   u32 ilen, struct ext4_str *crypto_str)
 280{
 281        unsigned int olen = ext4_fname_encrypted_size(inode, ilen);
 282
 283        crypto_str->len = olen;
 284        if (olen < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2)
 285                olen = EXT4_FNAME_CRYPTO_DIGEST_SIZE*2;
 286        /* Allocated buffer can hold one more character to null-terminate the
 287         * string */
 288        crypto_str->name = kmalloc(olen+1, GFP_NOFS);
 289        if (!(crypto_str->name))
 290                return -ENOMEM;
 291        return 0;
 292}
 293
 294/**
 295 * ext4_fname_crypto_free_buffer() -
 296 *
 297 * Frees the buffer allocated for crypto operation.
 298 */
 299void ext4_fname_crypto_free_buffer(struct ext4_str *crypto_str)
 300{
 301        if (!crypto_str)
 302                return;
 303        kfree(crypto_str->name);
 304        crypto_str->name = NULL;
 305}
 306
 307/**
 308 * ext4_fname_disk_to_usr() - converts a filename from disk space to user space
 309 */
 310int _ext4_fname_disk_to_usr(struct inode *inode,
 311                            struct dx_hash_info *hinfo,
 312                            const struct ext4_str *iname,
 313                            struct ext4_str *oname)
 314{
 315        char buf[24];
 316        int ret;
 317
 318        if (iname->len < 3) {
 319                /*Check for . and .. */
 320                if (iname->name[0] == '.' && iname->name[iname->len-1] == '.') {
 321                        oname->name[0] = '.';
 322                        oname->name[iname->len-1] = '.';
 323                        oname->len = iname->len;
 324                        return oname->len;
 325                }
 326        }
 327        if (iname->len < EXT4_CRYPTO_BLOCK_SIZE) {
 328                EXT4_ERROR_INODE(inode, "encrypted inode too small");
 329                return -EUCLEAN;
 330        }
 331        if (EXT4_I(inode)->i_crypt_info)
 332                return ext4_fname_decrypt(inode, iname, oname);
 333
 334        if (iname->len <= EXT4_FNAME_CRYPTO_DIGEST_SIZE) {
 335                ret = digest_encode(iname->name, iname->len, oname->name);
 336                oname->len = ret;
 337                return ret;
 338        }
 339        if (hinfo) {
 340                memcpy(buf, &hinfo->hash, 4);
 341                memcpy(buf+4, &hinfo->minor_hash, 4);
 342        } else
 343                memset(buf, 0, 8);
 344        memcpy(buf + 8, iname->name + iname->len - 16, 16);
 345        oname->name[0] = '_';
 346        ret = digest_encode(buf, 24, oname->name+1);
 347        oname->len = ret + 1;
 348        return ret + 1;
 349}
 350
 351int ext4_fname_disk_to_usr(struct inode *inode,
 352                           struct dx_hash_info *hinfo,
 353                           const struct ext4_dir_entry_2 *de,
 354                           struct ext4_str *oname)
 355{
 356        struct ext4_str iname = {.name = (unsigned char *) de->name,
 357                                 .len = de->name_len };
 358
 359        return _ext4_fname_disk_to_usr(inode, hinfo, &iname, oname);
 360}
 361
 362
 363/**
 364 * ext4_fname_usr_to_disk() - converts a filename from user space to disk space
 365 */
 366int ext4_fname_usr_to_disk(struct inode *inode,
 367                           const struct qstr *iname,
 368                           struct ext4_str *oname)
 369{
 370        int res;
 371        struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
 372
 373        if (iname->len < 3) {
 374                /*Check for . and .. */
 375                if (iname->name[0] == '.' &&
 376                                iname->name[iname->len-1] == '.') {
 377                        oname->name[0] = '.';
 378                        oname->name[iname->len-1] = '.';
 379                        oname->len = iname->len;
 380                        return oname->len;
 381                }
 382        }
 383        if (ci) {
 384                res = ext4_fname_encrypt(inode, iname, oname);
 385                return res;
 386        }
 387        /* Without a proper key, a user is not allowed to modify the filenames
 388         * in a directory. Consequently, a user space name cannot be mapped to
 389         * a disk-space name */
 390        return -EACCES;
 391}
 392
 393int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
 394                              int lookup, struct ext4_filename *fname)
 395{
 396        struct ext4_crypt_info *ci;
 397        int ret = 0, bigname = 0;
 398
 399        memset(fname, 0, sizeof(struct ext4_filename));
 400        fname->usr_fname = iname;
 401
 402        if (!ext4_encrypted_inode(dir) ||
 403            ((iname->name[0] == '.') &&
 404             ((iname->len == 1) ||
 405              ((iname->name[1] == '.') && (iname->len == 2))))) {
 406                fname->disk_name.name = (unsigned char *) iname->name;
 407                fname->disk_name.len = iname->len;
 408                return 0;
 409        }
 410        ret = ext4_get_encryption_info(dir);
 411        if (ret)
 412                return ret;
 413        ci = EXT4_I(dir)->i_crypt_info;
 414        if (ci) {
 415                ret = ext4_fname_crypto_alloc_buffer(dir, iname->len,
 416                                                     &fname->crypto_buf);
 417                if (ret < 0)
 418                        return ret;
 419                ret = ext4_fname_encrypt(dir, iname, &fname->crypto_buf);
 420                if (ret < 0)
 421                        goto errout;
 422                fname->disk_name.name = fname->crypto_buf.name;
 423                fname->disk_name.len = fname->crypto_buf.len;
 424                return 0;
 425        }
 426        if (!lookup)
 427                return -EACCES;
 428
 429        /* We don't have the key and we are doing a lookup; decode the
 430         * user-supplied name
 431         */
 432        if (iname->name[0] == '_')
 433                bigname = 1;
 434        if ((bigname && (iname->len != 33)) ||
 435            (!bigname && (iname->len > 43)))
 436                return -ENOENT;
 437
 438        fname->crypto_buf.name = kmalloc(32, GFP_KERNEL);
 439        if (fname->crypto_buf.name == NULL)
 440                return -ENOMEM;
 441        ret = digest_decode(iname->name + bigname, iname->len - bigname,
 442                            fname->crypto_buf.name);
 443        if (ret < 0) {
 444                ret = -ENOENT;
 445                goto errout;
 446        }
 447        fname->crypto_buf.len = ret;
 448        if (bigname) {
 449                memcpy(&fname->hinfo.hash, fname->crypto_buf.name, 4);
 450                memcpy(&fname->hinfo.minor_hash, fname->crypto_buf.name + 4, 4);
 451        } else {
 452                fname->disk_name.name = fname->crypto_buf.name;
 453                fname->disk_name.len = fname->crypto_buf.len;
 454        }
 455        return 0;
 456errout:
 457        kfree(fname->crypto_buf.name);
 458        fname->crypto_buf.name = NULL;
 459        return ret;
 460}
 461
 462void ext4_fname_free_filename(struct ext4_filename *fname)
 463{
 464        kfree(fname->crypto_buf.name);
 465        fname->crypto_buf.name = NULL;
 466        fname->usr_fname = NULL;
 467        fname->disk_name.name = NULL;
 468}
 469