linux/crypto/xts.c
<<
>>
Prefs
   1/* XTS: as defined in IEEE1619/D16
   2 *      http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
   3 *      (sector sizes which are not a multiple of 16 bytes are,
   4 *      however currently unsupported)
   5 *
   6 * Copyright (c) 2007 Rik Snel <rsnel@cube.dyndns.org>
   7 *
   8 * Based om ecb.c
   9 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
  10 *
  11 * This program is free software; you can redistribute it and/or modify it
  12 * under the terms of the GNU General Public License as published by the Free
  13 * Software Foundation; either version 2 of the License, or (at your option)
  14 * any later version.
  15 */
  16#include <crypto/algapi.h>
  17#include <linux/err.h>
  18#include <linux/init.h>
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/scatterlist.h>
  22#include <linux/slab.h>
  23
  24#include <crypto/xts.h>
  25#include <crypto/b128ops.h>
  26#include <crypto/gf128mul.h>
  27
  28struct priv {
  29        struct crypto_cipher *child;
  30        struct crypto_cipher *tweak;
  31};
  32
  33static int setkey(struct crypto_tfm *parent, const u8 *key,
  34                  unsigned int keylen)
  35{
  36        struct priv *ctx = crypto_tfm_ctx(parent);
  37        struct crypto_cipher *child = ctx->tweak;
  38        int err;
  39
  40        err = xts_check_key(parent, key, keylen);
  41        if (err)
  42                return err;
  43
  44        /* we need two cipher instances: one to compute the initial 'tweak'
  45         * by encrypting the IV (usually the 'plain' iv) and the other
  46         * one to encrypt and decrypt the data */
  47
  48        /* tweak cipher, uses Key2 i.e. the second half of *key */
  49        crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
  50        crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
  51                                       CRYPTO_TFM_REQ_MASK);
  52        err = crypto_cipher_setkey(child, key + keylen/2, keylen/2);
  53        if (err)
  54                return err;
  55
  56        crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
  57                                     CRYPTO_TFM_RES_MASK);
  58
  59        child = ctx->child;
  60
  61        /* data cipher, uses Key1 i.e. the first half of *key */
  62        crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
  63        crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
  64                                       CRYPTO_TFM_REQ_MASK);
  65        err = crypto_cipher_setkey(child, key, keylen/2);
  66        if (err)
  67                return err;
  68
  69        crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
  70                                     CRYPTO_TFM_RES_MASK);
  71
  72        return 0;
  73}
  74
  75struct sinfo {
  76        be128 *t;
  77        struct crypto_tfm *tfm;
  78        void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
  79};
  80
  81static inline void xts_round(struct sinfo *s, void *dst, const void *src)
  82{
  83        be128_xor(dst, s->t, src);              /* PP <- T xor P */
  84        s->fn(s->tfm, dst, dst);                /* CC <- E(Key1,PP) */
  85        be128_xor(dst, dst, s->t);              /* C <- T xor CC */
  86}
  87
  88static int crypt(struct blkcipher_desc *d,
  89                 struct blkcipher_walk *w, struct priv *ctx,
  90                 void (*tw)(struct crypto_tfm *, u8 *, const u8 *),
  91                 void (*fn)(struct crypto_tfm *, u8 *, const u8 *))
  92{
  93        int err;
  94        unsigned int avail;
  95        const int bs = XTS_BLOCK_SIZE;
  96        struct sinfo s = {
  97                .tfm = crypto_cipher_tfm(ctx->child),
  98                .fn = fn
  99        };
 100        u8 *wsrc;
 101        u8 *wdst;
 102
 103        err = blkcipher_walk_virt(d, w);
 104        if (!w->nbytes)
 105                return err;
 106
 107        s.t = (be128 *)w->iv;
 108        avail = w->nbytes;
 109
 110        wsrc = w->src.virt.addr;
 111        wdst = w->dst.virt.addr;
 112
 113        /* calculate first value of T */
 114        tw(crypto_cipher_tfm(ctx->tweak), w->iv, w->iv);
 115
 116        goto first;
 117
 118        for (;;) {
 119                do {
 120                        gf128mul_x_ble(s.t, s.t);
 121
 122first:
 123                        xts_round(&s, wdst, wsrc);
 124
 125                        wsrc += bs;
 126                        wdst += bs;
 127                } while ((avail -= bs) >= bs);
 128
 129                err = blkcipher_walk_done(d, w, avail);
 130                if (!w->nbytes)
 131                        break;
 132
 133                avail = w->nbytes;
 134
 135                wsrc = w->src.virt.addr;
 136                wdst = w->dst.virt.addr;
 137        }
 138
 139        return err;
 140}
 141
 142static int encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 143                   struct scatterlist *src, unsigned int nbytes)
 144{
 145        struct priv *ctx = crypto_blkcipher_ctx(desc->tfm);
 146        struct blkcipher_walk w;
 147
 148        blkcipher_walk_init(&w, dst, src, nbytes);
 149        return crypt(desc, &w, ctx, crypto_cipher_alg(ctx->tweak)->cia_encrypt,
 150                     crypto_cipher_alg(ctx->child)->cia_encrypt);
 151}
 152
 153static int decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 154                   struct scatterlist *src, unsigned int nbytes)
 155{
 156        struct priv *ctx = crypto_blkcipher_ctx(desc->tfm);
 157        struct blkcipher_walk w;
 158
 159        blkcipher_walk_init(&w, dst, src, nbytes);
 160        return crypt(desc, &w, ctx, crypto_cipher_alg(ctx->tweak)->cia_encrypt,
 161                     crypto_cipher_alg(ctx->child)->cia_decrypt);
 162}
 163
 164int xts_crypt(struct blkcipher_desc *desc, struct scatterlist *sdst,
 165              struct scatterlist *ssrc, unsigned int nbytes,
 166              struct xts_crypt_req *req)
 167{
 168        const unsigned int bsize = XTS_BLOCK_SIZE;
 169        const unsigned int max_blks = req->tbuflen / bsize;
 170        struct blkcipher_walk walk;
 171        unsigned int nblocks;
 172        be128 *src, *dst, *t;
 173        be128 *t_buf = req->tbuf;
 174        int err, i;
 175
 176        BUG_ON(max_blks < 1);
 177
 178        blkcipher_walk_init(&walk, sdst, ssrc, nbytes);
 179
 180        err = blkcipher_walk_virt(desc, &walk);
 181        nbytes = walk.nbytes;
 182        if (!nbytes)
 183                return err;
 184
 185        nblocks = min(nbytes / bsize, max_blks);
 186        src = (be128 *)walk.src.virt.addr;
 187        dst = (be128 *)walk.dst.virt.addr;
 188
 189        /* calculate first value of T */
 190        req->tweak_fn(req->tweak_ctx, (u8 *)&t_buf[0], walk.iv);
 191
 192        i = 0;
 193        goto first;
 194
 195        for (;;) {
 196                do {
 197                        for (i = 0; i < nblocks; i++) {
 198                                gf128mul_x_ble(&t_buf[i], t);
 199first:
 200                                t = &t_buf[i];
 201
 202                                /* PP <- T xor P */
 203                                be128_xor(dst + i, t, src + i);
 204                        }
 205
 206                        /* CC <- E(Key2,PP) */
 207                        req->crypt_fn(req->crypt_ctx, (u8 *)dst,
 208                                      nblocks * bsize);
 209
 210                        /* C <- T xor CC */
 211                        for (i = 0; i < nblocks; i++)
 212                                be128_xor(dst + i, dst + i, &t_buf[i]);
 213
 214                        src += nblocks;
 215                        dst += nblocks;
 216                        nbytes -= nblocks * bsize;
 217                        nblocks = min(nbytes / bsize, max_blks);
 218                } while (nblocks > 0);
 219
 220                *(be128 *)walk.iv = *t;
 221
 222                err = blkcipher_walk_done(desc, &walk, nbytes);
 223                nbytes = walk.nbytes;
 224                if (!nbytes)
 225                        break;
 226
 227                nblocks = min(nbytes / bsize, max_blks);
 228                src = (be128 *)walk.src.virt.addr;
 229                dst = (be128 *)walk.dst.virt.addr;
 230        }
 231
 232        return err;
 233}
 234EXPORT_SYMBOL_GPL(xts_crypt);
 235
 236static int init_tfm(struct crypto_tfm *tfm)
 237{
 238        struct crypto_cipher *cipher;
 239        struct crypto_instance *inst = (void *)tfm->__crt_alg;
 240        struct crypto_spawn *spawn = crypto_instance_ctx(inst);
 241        struct priv *ctx = crypto_tfm_ctx(tfm);
 242        u32 *flags = &tfm->crt_flags;
 243
 244        cipher = crypto_spawn_cipher(spawn);
 245        if (IS_ERR(cipher))
 246                return PTR_ERR(cipher);
 247
 248        if (crypto_cipher_blocksize(cipher) != XTS_BLOCK_SIZE) {
 249                *flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
 250                crypto_free_cipher(cipher);
 251                return -EINVAL;
 252        }
 253
 254        ctx->child = cipher;
 255
 256        cipher = crypto_spawn_cipher(spawn);
 257        if (IS_ERR(cipher)) {
 258                crypto_free_cipher(ctx->child);
 259                return PTR_ERR(cipher);
 260        }
 261
 262        /* this check isn't really needed, leave it here just in case */
 263        if (crypto_cipher_blocksize(cipher) != XTS_BLOCK_SIZE) {
 264                crypto_free_cipher(cipher);
 265                crypto_free_cipher(ctx->child);
 266                *flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
 267                return -EINVAL;
 268        }
 269
 270        ctx->tweak = cipher;
 271
 272        return 0;
 273}
 274
 275static void exit_tfm(struct crypto_tfm *tfm)
 276{
 277        struct priv *ctx = crypto_tfm_ctx(tfm);
 278        crypto_free_cipher(ctx->child);
 279        crypto_free_cipher(ctx->tweak);
 280}
 281
 282static struct crypto_instance *alloc(struct rtattr **tb)
 283{
 284        struct crypto_instance *inst;
 285        struct crypto_alg *alg;
 286        int err;
 287
 288        err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
 289        if (err)
 290                return ERR_PTR(err);
 291
 292        alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
 293                                  CRYPTO_ALG_TYPE_MASK);
 294        if (IS_ERR(alg))
 295                return ERR_CAST(alg);
 296
 297        inst = crypto_alloc_instance("xts", alg);
 298        if (IS_ERR(inst))
 299                goto out_put_alg;
 300
 301        inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
 302        inst->alg.cra_priority = alg->cra_priority;
 303        inst->alg.cra_blocksize = alg->cra_blocksize;
 304
 305        if (alg->cra_alignmask < 7)
 306                inst->alg.cra_alignmask = 7;
 307        else
 308                inst->alg.cra_alignmask = alg->cra_alignmask;
 309
 310        inst->alg.cra_type = &crypto_blkcipher_type;
 311
 312        inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
 313        inst->alg.cra_blkcipher.min_keysize =
 314                2 * alg->cra_cipher.cia_min_keysize;
 315        inst->alg.cra_blkcipher.max_keysize =
 316                2 * alg->cra_cipher.cia_max_keysize;
 317
 318        inst->alg.cra_ctxsize = sizeof(struct priv);
 319
 320        inst->alg.cra_init = init_tfm;
 321        inst->alg.cra_exit = exit_tfm;
 322
 323        inst->alg.cra_blkcipher.setkey = setkey;
 324        inst->alg.cra_blkcipher.encrypt = encrypt;
 325        inst->alg.cra_blkcipher.decrypt = decrypt;
 326
 327out_put_alg:
 328        crypto_mod_put(alg);
 329        return inst;
 330}
 331
 332static void free(struct crypto_instance *inst)
 333{
 334        crypto_drop_spawn(crypto_instance_ctx(inst));
 335        kfree(inst);
 336}
 337
 338static struct crypto_template crypto_tmpl = {
 339        .name = "xts",
 340        .alloc = alloc,
 341        .free = free,
 342        .module = THIS_MODULE,
 343};
 344
 345static int __init crypto_module_init(void)
 346{
 347        return crypto_register_template(&crypto_tmpl);
 348}
 349
 350static void __exit crypto_module_exit(void)
 351{
 352        crypto_unregister_template(&crypto_tmpl);
 353}
 354
 355module_init(crypto_module_init);
 356module_exit(crypto_module_exit);
 357
 358MODULE_LICENSE("GPL");
 359MODULE_DESCRIPTION("XTS block cipher mode");
 360MODULE_ALIAS_CRYPTO("xts");
 361