linux/crypto/ccm.c
<<
>>
Prefs
   1/*
   2 * CCM: Counter with CBC-MAC
   3 *
   4 * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of the GNU General Public License as published by the Free
   8 * Software Foundation; either version 2 of the License, or (at your option)
   9 * any later version.
  10 *
  11 */
  12
  13#include <crypto/internal/aead.h>
  14#include <crypto/internal/skcipher.h>
  15#include <crypto/scatterwalk.h>
  16#include <linux/err.h>
  17#include <linux/init.h>
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/slab.h>
  21
  22#include "internal.h"
  23
  24struct ccm_instance_ctx {
  25        struct crypto_skcipher_spawn ctr;
  26        struct crypto_spawn cipher;
  27};
  28
  29struct crypto_ccm_ctx {
  30        struct crypto_cipher *cipher;
  31        struct crypto_ablkcipher *ctr;
  32};
  33
  34struct crypto_rfc4309_ctx {
  35        struct crypto_aead *child;
  36        u8 nonce[3];
  37};
  38
  39struct crypto_rfc4309_req_ctx {
  40        struct scatterlist src[3];
  41        struct scatterlist dst[3];
  42        struct aead_request subreq;
  43};
  44
  45struct crypto_ccm_req_priv_ctx {
  46        u8 odata[16];
  47        u8 idata[16];
  48        u8 auth_tag[16];
  49        u32 ilen;
  50        u32 flags;
  51        struct scatterlist src[3];
  52        struct scatterlist dst[3];
  53        struct ablkcipher_request abreq;
  54};
  55
  56static inline struct crypto_ccm_req_priv_ctx *crypto_ccm_reqctx(
  57        struct aead_request *req)
  58{
  59        unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));
  60
  61        return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
  62}
  63
  64static int set_msg_len(u8 *block, unsigned int msglen, int csize)
  65{
  66        __be32 data;
  67
  68        memset(block, 0, csize);
  69        block += csize;
  70
  71        if (csize >= 4)
  72                csize = 4;
  73        else if (msglen > (1 << (8 * csize)))
  74                return -EOVERFLOW;
  75
  76        data = cpu_to_be32(msglen);
  77        memcpy(block - csize, (u8 *)&data + 4 - csize, csize);
  78
  79        return 0;
  80}
  81
  82static int crypto_ccm_setkey(struct crypto_aead *aead, const u8 *key,
  83                             unsigned int keylen)
  84{
  85        struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
  86        struct crypto_ablkcipher *ctr = ctx->ctr;
  87        struct crypto_cipher *tfm = ctx->cipher;
  88        int err = 0;
  89
  90        crypto_ablkcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
  91        crypto_ablkcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
  92                                    CRYPTO_TFM_REQ_MASK);
  93        err = crypto_ablkcipher_setkey(ctr, key, keylen);
  94        crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctr) &
  95                              CRYPTO_TFM_RES_MASK);
  96        if (err)
  97                goto out;
  98
  99        crypto_cipher_clear_flags(tfm, CRYPTO_TFM_REQ_MASK);
 100        crypto_cipher_set_flags(tfm, crypto_aead_get_flags(aead) &
 101                                    CRYPTO_TFM_REQ_MASK);
 102        err = crypto_cipher_setkey(tfm, key, keylen);
 103        crypto_aead_set_flags(aead, crypto_cipher_get_flags(tfm) &
 104                              CRYPTO_TFM_RES_MASK);
 105
 106out:
 107        return err;
 108}
 109
 110static int crypto_ccm_setauthsize(struct crypto_aead *tfm,
 111                                  unsigned int authsize)
 112{
 113        switch (authsize) {
 114        case 4:
 115        case 6:
 116        case 8:
 117        case 10:
 118        case 12:
 119        case 14:
 120        case 16:
 121                break;
 122        default:
 123                return -EINVAL;
 124        }
 125
 126        return 0;
 127}
 128
 129static int format_input(u8 *info, struct aead_request *req,
 130                        unsigned int cryptlen)
 131{
 132        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 133        unsigned int lp = req->iv[0];
 134        unsigned int l = lp + 1;
 135        unsigned int m;
 136
 137        m = crypto_aead_authsize(aead);
 138
 139        memcpy(info, req->iv, 16);
 140
 141        /* format control info per RFC 3610 and
 142         * NIST Special Publication 800-38C
 143         */
 144        *info |= (8 * ((m - 2) / 2));
 145        if (req->assoclen)
 146                *info |= 64;
 147
 148        return set_msg_len(info + 16 - l, cryptlen, l);
 149}
 150
 151static int format_adata(u8 *adata, unsigned int a)
 152{
 153        int len = 0;
 154
 155        /* add control info for associated data
 156         * RFC 3610 and NIST Special Publication 800-38C
 157         */
 158        if (a < 65280) {
 159                *(__be16 *)adata = cpu_to_be16(a);
 160                len = 2;
 161        } else  {
 162                *(__be16 *)adata = cpu_to_be16(0xfffe);
 163                *(__be32 *)&adata[2] = cpu_to_be32(a);
 164                len = 6;
 165        }
 166
 167        return len;
 168}
 169
 170static void compute_mac(struct crypto_cipher *tfm, u8 *data, int n,
 171                       struct crypto_ccm_req_priv_ctx *pctx)
 172{
 173        unsigned int bs = 16;
 174        u8 *odata = pctx->odata;
 175        u8 *idata = pctx->idata;
 176        int datalen, getlen;
 177
 178        datalen = n;
 179
 180        /* first time in here, block may be partially filled. */
 181        getlen = bs - pctx->ilen;
 182        if (datalen >= getlen) {
 183                memcpy(idata + pctx->ilen, data, getlen);
 184                crypto_xor(odata, idata, bs);
 185                crypto_cipher_encrypt_one(tfm, odata, odata);
 186                datalen -= getlen;
 187                data += getlen;
 188                pctx->ilen = 0;
 189        }
 190
 191        /* now encrypt rest of data */
 192        while (datalen >= bs) {
 193                crypto_xor(odata, data, bs);
 194                crypto_cipher_encrypt_one(tfm, odata, odata);
 195
 196                datalen -= bs;
 197                data += bs;
 198        }
 199
 200        /* check and see if there's leftover data that wasn't
 201         * enough to fill a block.
 202         */
 203        if (datalen) {
 204                memcpy(idata + pctx->ilen, data, datalen);
 205                pctx->ilen += datalen;
 206        }
 207}
 208
 209static void get_data_to_compute(struct crypto_cipher *tfm,
 210                               struct crypto_ccm_req_priv_ctx *pctx,
 211                               struct scatterlist *sg, unsigned int len)
 212{
 213        struct scatter_walk walk;
 214        u8 *data_src;
 215        int n;
 216
 217        scatterwalk_start(&walk, sg);
 218
 219        while (len) {
 220                n = scatterwalk_clamp(&walk, len);
 221                if (!n) {
 222                        scatterwalk_start(&walk, sg_next(walk.sg));
 223                        n = scatterwalk_clamp(&walk, len);
 224                }
 225                data_src = scatterwalk_map(&walk);
 226
 227                compute_mac(tfm, data_src, n, pctx);
 228                len -= n;
 229
 230                scatterwalk_unmap(data_src);
 231                scatterwalk_advance(&walk, n);
 232                scatterwalk_done(&walk, 0, len);
 233                if (len)
 234                        crypto_yield(pctx->flags);
 235        }
 236
 237        /* any leftover needs padding and then encrypted */
 238        if (pctx->ilen) {
 239                int padlen;
 240                u8 *odata = pctx->odata;
 241                u8 *idata = pctx->idata;
 242
 243                padlen = 16 - pctx->ilen;
 244                memset(idata + pctx->ilen, 0, padlen);
 245                crypto_xor(odata, idata, 16);
 246                crypto_cipher_encrypt_one(tfm, odata, odata);
 247                pctx->ilen = 0;
 248        }
 249}
 250
 251static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain,
 252                           unsigned int cryptlen)
 253{
 254        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 255        struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
 256        struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
 257        struct crypto_cipher *cipher = ctx->cipher;
 258        unsigned int assoclen = req->assoclen;
 259        u8 *odata = pctx->odata;
 260        u8 *idata = pctx->idata;
 261        int err;
 262
 263        /* format control data for input */
 264        err = format_input(odata, req, cryptlen);
 265        if (err)
 266                goto out;
 267
 268        /* encrypt first block to use as start in computing mac  */
 269        crypto_cipher_encrypt_one(cipher, odata, odata);
 270
 271        /* format associated data and compute into mac */
 272        if (assoclen) {
 273                pctx->ilen = format_adata(idata, assoclen);
 274                get_data_to_compute(cipher, pctx, req->src, req->assoclen);
 275        } else {
 276                pctx->ilen = 0;
 277        }
 278
 279        /* compute plaintext into mac */
 280        if (cryptlen)
 281                get_data_to_compute(cipher, pctx, plain, cryptlen);
 282
 283out:
 284        return err;
 285}
 286
 287static void crypto_ccm_encrypt_done(struct crypto_async_request *areq, int err)
 288{
 289        struct aead_request *req = areq->data;
 290        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 291        struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
 292        u8 *odata = pctx->odata;
 293
 294        if (!err)
 295                scatterwalk_map_and_copy(odata, req->dst,
 296                                         req->assoclen + req->cryptlen,
 297                                         crypto_aead_authsize(aead), 1);
 298        aead_request_complete(req, err);
 299}
 300
 301static inline int crypto_ccm_check_iv(const u8 *iv)
 302{
 303        /* 2 <= L <= 8, so 1 <= L' <= 7. */
 304        if (1 > iv[0] || iv[0] > 7)
 305                return -EINVAL;
 306
 307        return 0;
 308}
 309
 310static int crypto_ccm_init_crypt(struct aead_request *req, u8 *tag)
 311{
 312        struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
 313        struct scatterlist *sg;
 314        u8 *iv = req->iv;
 315        int err;
 316
 317        err = crypto_ccm_check_iv(iv);
 318        if (err)
 319                return err;
 320
 321        pctx->flags = aead_request_flags(req);
 322
 323         /* Note: rfc 3610 and NIST 800-38C require counter of
 324         * zero to encrypt auth tag.
 325         */
 326        memset(iv + 15 - iv[0], 0, iv[0] + 1);
 327
 328        sg_init_table(pctx->src, 3);
 329        sg_set_buf(pctx->src, tag, 16);
 330        sg = scatterwalk_ffwd(pctx->src + 1, req->src, req->assoclen);
 331        if (sg != pctx->src + 1)
 332                sg_chain(pctx->src, 2, sg);
 333
 334        if (req->src != req->dst) {
 335                sg_init_table(pctx->dst, 3);
 336                sg_set_buf(pctx->dst, tag, 16);
 337                sg = scatterwalk_ffwd(pctx->dst + 1, req->dst, req->assoclen);
 338                if (sg != pctx->dst + 1)
 339                        sg_chain(pctx->dst, 2, sg);
 340        }
 341
 342        return 0;
 343}
 344
 345static int crypto_ccm_encrypt(struct aead_request *req)
 346{
 347        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 348        struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
 349        struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
 350        struct ablkcipher_request *abreq = &pctx->abreq;
 351        struct scatterlist *dst;
 352        unsigned int cryptlen = req->cryptlen;
 353        u8 *odata = pctx->odata;
 354        u8 *iv = req->iv;
 355        int err;
 356
 357        err = crypto_ccm_init_crypt(req, odata);
 358        if (err)
 359                return err;
 360
 361        err = crypto_ccm_auth(req, sg_next(pctx->src), cryptlen);
 362        if (err)
 363                return err;
 364
 365        dst = pctx->src;
 366        if (req->src != req->dst)
 367                dst = pctx->dst;
 368
 369        ablkcipher_request_set_tfm(abreq, ctx->ctr);
 370        ablkcipher_request_set_callback(abreq, pctx->flags,
 371                                        crypto_ccm_encrypt_done, req);
 372        ablkcipher_request_set_crypt(abreq, pctx->src, dst, cryptlen + 16, iv);
 373        err = crypto_ablkcipher_encrypt(abreq);
 374        if (err)
 375                return err;
 376
 377        /* copy authtag to end of dst */
 378        scatterwalk_map_and_copy(odata, sg_next(dst), cryptlen,
 379                                 crypto_aead_authsize(aead), 1);
 380        return err;
 381}
 382
 383static void crypto_ccm_decrypt_done(struct crypto_async_request *areq,
 384                                   int err)
 385{
 386        struct aead_request *req = areq->data;
 387        struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
 388        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 389        unsigned int authsize = crypto_aead_authsize(aead);
 390        unsigned int cryptlen = req->cryptlen - authsize;
 391        struct scatterlist *dst;
 392
 393        pctx->flags = 0;
 394
 395        dst = sg_next(req->src == req->dst ? pctx->src : pctx->dst);
 396
 397        if (!err) {
 398                err = crypto_ccm_auth(req, dst, cryptlen);
 399                if (!err && crypto_memneq(pctx->auth_tag, pctx->odata, authsize))
 400                        err = -EBADMSG;
 401        }
 402        aead_request_complete(req, err);
 403}
 404
 405static int crypto_ccm_decrypt(struct aead_request *req)
 406{
 407        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 408        struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
 409        struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
 410        struct ablkcipher_request *abreq = &pctx->abreq;
 411        struct scatterlist *dst;
 412        unsigned int authsize = crypto_aead_authsize(aead);
 413        unsigned int cryptlen = req->cryptlen;
 414        u8 *authtag = pctx->auth_tag;
 415        u8 *odata = pctx->odata;
 416        u8 *iv = req->iv;
 417        int err;
 418
 419        cryptlen -= authsize;
 420
 421        err = crypto_ccm_init_crypt(req, authtag);
 422        if (err)
 423                return err;
 424
 425        scatterwalk_map_and_copy(authtag, sg_next(pctx->src), cryptlen,
 426                                 authsize, 0);
 427
 428        dst = pctx->src;
 429        if (req->src != req->dst)
 430                dst = pctx->dst;
 431
 432        ablkcipher_request_set_tfm(abreq, ctx->ctr);
 433        ablkcipher_request_set_callback(abreq, pctx->flags,
 434                                        crypto_ccm_decrypt_done, req);
 435        ablkcipher_request_set_crypt(abreq, pctx->src, dst, cryptlen + 16, iv);
 436        err = crypto_ablkcipher_decrypt(abreq);
 437        if (err)
 438                return err;
 439
 440        err = crypto_ccm_auth(req, sg_next(dst), cryptlen);
 441        if (err)
 442                return err;
 443
 444        /* verify */
 445        if (crypto_memneq(authtag, odata, authsize))
 446                return -EBADMSG;
 447
 448        return err;
 449}
 450
 451static int crypto_ccm_init_tfm(struct crypto_aead *tfm)
 452{
 453        struct aead_instance *inst = aead_alg_instance(tfm);
 454        struct ccm_instance_ctx *ictx = aead_instance_ctx(inst);
 455        struct crypto_ccm_ctx *ctx = crypto_aead_ctx(tfm);
 456        struct crypto_cipher *cipher;
 457        struct crypto_ablkcipher *ctr;
 458        unsigned long align;
 459        int err;
 460
 461        cipher = crypto_spawn_cipher(&ictx->cipher);
 462        if (IS_ERR(cipher))
 463                return PTR_ERR(cipher);
 464
 465        ctr = crypto_spawn_skcipher(&ictx->ctr);
 466        err = PTR_ERR(ctr);
 467        if (IS_ERR(ctr))
 468                goto err_free_cipher;
 469
 470        ctx->cipher = cipher;
 471        ctx->ctr = ctr;
 472
 473        align = crypto_aead_alignmask(tfm);
 474        align &= ~(crypto_tfm_ctx_alignment() - 1);
 475        crypto_aead_set_reqsize(
 476                tfm,
 477                align + sizeof(struct crypto_ccm_req_priv_ctx) +
 478                crypto_ablkcipher_reqsize(ctr));
 479
 480        return 0;
 481
 482err_free_cipher:
 483        crypto_free_cipher(cipher);
 484        return err;
 485}
 486
 487static void crypto_ccm_exit_tfm(struct crypto_aead *tfm)
 488{
 489        struct crypto_ccm_ctx *ctx = crypto_aead_ctx(tfm);
 490
 491        crypto_free_cipher(ctx->cipher);
 492        crypto_free_ablkcipher(ctx->ctr);
 493}
 494
 495static void crypto_ccm_free(struct aead_instance *inst)
 496{
 497        struct ccm_instance_ctx *ctx = aead_instance_ctx(inst);
 498
 499        crypto_drop_spawn(&ctx->cipher);
 500        crypto_drop_skcipher(&ctx->ctr);
 501        kfree(inst);
 502}
 503
 504static int crypto_ccm_create_common(struct crypto_template *tmpl,
 505                                    struct rtattr **tb,
 506                                    const char *full_name,
 507                                    const char *ctr_name,
 508                                    const char *cipher_name)
 509{
 510        struct crypto_attr_type *algt;
 511        struct aead_instance *inst;
 512        struct crypto_alg *ctr;
 513        struct crypto_alg *cipher;
 514        struct ccm_instance_ctx *ictx;
 515        int err;
 516
 517        algt = crypto_get_attr_type(tb);
 518        if (IS_ERR(algt))
 519                return PTR_ERR(algt);
 520
 521        if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
 522                return -EINVAL;
 523
 524        cipher = crypto_alg_mod_lookup(cipher_name,  CRYPTO_ALG_TYPE_CIPHER,
 525                                       CRYPTO_ALG_TYPE_MASK);
 526        if (IS_ERR(cipher))
 527                return PTR_ERR(cipher);
 528
 529        err = -EINVAL;
 530        if (cipher->cra_blocksize != 16)
 531                goto out_put_cipher;
 532
 533        inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
 534        err = -ENOMEM;
 535        if (!inst)
 536                goto out_put_cipher;
 537
 538        ictx = aead_instance_ctx(inst);
 539
 540        err = crypto_init_spawn(&ictx->cipher, cipher,
 541                                aead_crypto_instance(inst),
 542                                CRYPTO_ALG_TYPE_MASK);
 543        if (err)
 544                goto err_free_inst;
 545
 546        crypto_set_skcipher_spawn(&ictx->ctr, aead_crypto_instance(inst));
 547        err = crypto_grab_skcipher(&ictx->ctr, ctr_name, 0,
 548                                   crypto_requires_sync(algt->type,
 549                                                        algt->mask));
 550        if (err)
 551                goto err_drop_cipher;
 552
 553        ctr = crypto_skcipher_spawn_alg(&ictx->ctr);
 554
 555        /* Not a stream cipher? */
 556        err = -EINVAL;
 557        if (ctr->cra_blocksize != 1)
 558                goto err_drop_ctr;
 559
 560        /* We want the real thing! */
 561        if (ctr->cra_ablkcipher.ivsize != 16)
 562                goto err_drop_ctr;
 563
 564        err = -ENAMETOOLONG;
 565        if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
 566                     "ccm_base(%s,%s)", ctr->cra_driver_name,
 567                     cipher->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
 568                goto err_drop_ctr;
 569
 570        memcpy(inst->alg.base.cra_name, full_name, CRYPTO_MAX_ALG_NAME);
 571
 572        inst->alg.base.cra_flags = ctr->cra_flags & CRYPTO_ALG_ASYNC;
 573        inst->alg.base.cra_priority = (cipher->cra_priority +
 574                                       ctr->cra_priority) / 2;
 575        inst->alg.base.cra_blocksize = 1;
 576        inst->alg.base.cra_alignmask = cipher->cra_alignmask |
 577                                       ctr->cra_alignmask |
 578                                       (__alignof__(u32) - 1);
 579        inst->alg.ivsize = 16;
 580        inst->alg.maxauthsize = 16;
 581        inst->alg.base.cra_ctxsize = sizeof(struct crypto_ccm_ctx);
 582        inst->alg.init = crypto_ccm_init_tfm;
 583        inst->alg.exit = crypto_ccm_exit_tfm;
 584        inst->alg.setkey = crypto_ccm_setkey;
 585        inst->alg.setauthsize = crypto_ccm_setauthsize;
 586        inst->alg.encrypt = crypto_ccm_encrypt;
 587        inst->alg.decrypt = crypto_ccm_decrypt;
 588
 589        inst->free = crypto_ccm_free;
 590
 591        err = aead_register_instance(tmpl, inst);
 592        if (err)
 593                goto err_drop_ctr;
 594
 595out_put_cipher:
 596        crypto_mod_put(cipher);
 597        return err;
 598
 599err_drop_ctr:
 600        crypto_drop_skcipher(&ictx->ctr);
 601err_drop_cipher:
 602        crypto_drop_spawn(&ictx->cipher);
 603err_free_inst:
 604        kfree(inst);
 605        goto out_put_cipher;
 606}
 607
 608static int crypto_ccm_create(struct crypto_template *tmpl, struct rtattr **tb)
 609{
 610        const char *cipher_name;
 611        char ctr_name[CRYPTO_MAX_ALG_NAME];
 612        char full_name[CRYPTO_MAX_ALG_NAME];
 613
 614        cipher_name = crypto_attr_alg_name(tb[1]);
 615        if (IS_ERR(cipher_name))
 616                return PTR_ERR(cipher_name);
 617
 618        if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)",
 619                     cipher_name) >= CRYPTO_MAX_ALG_NAME)
 620                return -ENAMETOOLONG;
 621
 622        if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "ccm(%s)", cipher_name) >=
 623            CRYPTO_MAX_ALG_NAME)
 624                return -ENAMETOOLONG;
 625
 626        return crypto_ccm_create_common(tmpl, tb, full_name, ctr_name,
 627                                        cipher_name);
 628}
 629
 630static struct crypto_template crypto_ccm_tmpl = {
 631        .name = "ccm",
 632        .create = crypto_ccm_create,
 633        .module = THIS_MODULE,
 634};
 635
 636static int crypto_ccm_base_create(struct crypto_template *tmpl,
 637                                  struct rtattr **tb)
 638{
 639        const char *ctr_name;
 640        const char *cipher_name;
 641        char full_name[CRYPTO_MAX_ALG_NAME];
 642
 643        ctr_name = crypto_attr_alg_name(tb[1]);
 644        if (IS_ERR(ctr_name))
 645                return PTR_ERR(ctr_name);
 646
 647        cipher_name = crypto_attr_alg_name(tb[2]);
 648        if (IS_ERR(cipher_name))
 649                return PTR_ERR(cipher_name);
 650
 651        if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "ccm_base(%s,%s)",
 652                     ctr_name, cipher_name) >= CRYPTO_MAX_ALG_NAME)
 653                return -ENAMETOOLONG;
 654
 655        return crypto_ccm_create_common(tmpl, tb, full_name, ctr_name,
 656                                        cipher_name);
 657}
 658
 659static struct crypto_template crypto_ccm_base_tmpl = {
 660        .name = "ccm_base",
 661        .create = crypto_ccm_base_create,
 662        .module = THIS_MODULE,
 663};
 664
 665static int crypto_rfc4309_setkey(struct crypto_aead *parent, const u8 *key,
 666                                 unsigned int keylen)
 667{
 668        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(parent);
 669        struct crypto_aead *child = ctx->child;
 670        int err;
 671
 672        if (keylen < 3)
 673                return -EINVAL;
 674
 675        keylen -= 3;
 676        memcpy(ctx->nonce, key + keylen, 3);
 677
 678        crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
 679        crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
 680                                     CRYPTO_TFM_REQ_MASK);
 681        err = crypto_aead_setkey(child, key, keylen);
 682        crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
 683                                      CRYPTO_TFM_RES_MASK);
 684
 685        return err;
 686}
 687
 688static int crypto_rfc4309_setauthsize(struct crypto_aead *parent,
 689                                      unsigned int authsize)
 690{
 691        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(parent);
 692
 693        switch (authsize) {
 694        case 8:
 695        case 12:
 696        case 16:
 697                break;
 698        default:
 699                return -EINVAL;
 700        }
 701
 702        return crypto_aead_setauthsize(ctx->child, authsize);
 703}
 704
 705static struct aead_request *crypto_rfc4309_crypt(struct aead_request *req)
 706{
 707        struct crypto_rfc4309_req_ctx *rctx = aead_request_ctx(req);
 708        struct aead_request *subreq = &rctx->subreq;
 709        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 710        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(aead);
 711        struct crypto_aead *child = ctx->child;
 712        struct scatterlist *sg;
 713        u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
 714                           crypto_aead_alignmask(child) + 1);
 715
 716        /* L' */
 717        iv[0] = 3;
 718
 719        memcpy(iv + 1, ctx->nonce, 3);
 720        memcpy(iv + 4, req->iv, 8);
 721
 722        scatterwalk_map_and_copy(iv + 16, req->src, 0, req->assoclen - 8, 0);
 723
 724        sg_init_table(rctx->src, 3);
 725        sg_set_buf(rctx->src, iv + 16, req->assoclen - 8);
 726        sg = scatterwalk_ffwd(rctx->src + 1, req->src, req->assoclen);
 727        if (sg != rctx->src + 1)
 728                sg_chain(rctx->src, 2, sg);
 729
 730        if (req->src != req->dst) {
 731                sg_init_table(rctx->dst, 3);
 732                sg_set_buf(rctx->dst, iv + 16, req->assoclen - 8);
 733                sg = scatterwalk_ffwd(rctx->dst + 1, req->dst, req->assoclen);
 734                if (sg != rctx->dst + 1)
 735                        sg_chain(rctx->dst, 2, sg);
 736        }
 737
 738        aead_request_set_tfm(subreq, child);
 739        aead_request_set_callback(subreq, req->base.flags, req->base.complete,
 740                                  req->base.data);
 741        aead_request_set_crypt(subreq, rctx->src,
 742                               req->src == req->dst ? rctx->src : rctx->dst,
 743                               req->cryptlen, iv);
 744        aead_request_set_ad(subreq, req->assoclen - 8);
 745
 746        return subreq;
 747}
 748
 749static int crypto_rfc4309_encrypt(struct aead_request *req)
 750{
 751        if (req->assoclen != 16 && req->assoclen != 20)
 752                return -EINVAL;
 753
 754        req = crypto_rfc4309_crypt(req);
 755
 756        return crypto_aead_encrypt(req);
 757}
 758
 759static int crypto_rfc4309_decrypt(struct aead_request *req)
 760{
 761        if (req->assoclen != 16 && req->assoclen != 20)
 762                return -EINVAL;
 763
 764        req = crypto_rfc4309_crypt(req);
 765
 766        return crypto_aead_decrypt(req);
 767}
 768
 769static int crypto_rfc4309_init_tfm(struct crypto_aead *tfm)
 770{
 771        struct aead_instance *inst = aead_alg_instance(tfm);
 772        struct crypto_aead_spawn *spawn = aead_instance_ctx(inst);
 773        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(tfm);
 774        struct crypto_aead *aead;
 775        unsigned long align;
 776
 777        aead = crypto_spawn_aead(spawn);
 778        if (IS_ERR(aead))
 779                return PTR_ERR(aead);
 780
 781        ctx->child = aead;
 782
 783        align = crypto_aead_alignmask(aead);
 784        align &= ~(crypto_tfm_ctx_alignment() - 1);
 785        crypto_aead_set_reqsize(
 786                tfm,
 787                sizeof(struct crypto_rfc4309_req_ctx) +
 788                ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) +
 789                align + 32);
 790
 791        return 0;
 792}
 793
 794static void crypto_rfc4309_exit_tfm(struct crypto_aead *tfm)
 795{
 796        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(tfm);
 797
 798        crypto_free_aead(ctx->child);
 799}
 800
 801static void crypto_rfc4309_free(struct aead_instance *inst)
 802{
 803        crypto_drop_aead(aead_instance_ctx(inst));
 804        kfree(inst);
 805}
 806
 807static int crypto_rfc4309_create(struct crypto_template *tmpl,
 808                                 struct rtattr **tb)
 809{
 810        struct crypto_attr_type *algt;
 811        struct aead_instance *inst;
 812        struct crypto_aead_spawn *spawn;
 813        struct aead_alg *alg;
 814        const char *ccm_name;
 815        int err;
 816
 817        algt = crypto_get_attr_type(tb);
 818        if (IS_ERR(algt))
 819                return PTR_ERR(algt);
 820
 821        if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
 822                return -EINVAL;
 823
 824        ccm_name = crypto_attr_alg_name(tb[1]);
 825        if (IS_ERR(ccm_name))
 826                return PTR_ERR(ccm_name);
 827
 828        inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
 829        if (!inst)
 830                return -ENOMEM;
 831
 832        spawn = aead_instance_ctx(inst);
 833        crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
 834        err = crypto_grab_aead(spawn, ccm_name, 0,
 835                               crypto_requires_sync(algt->type, algt->mask));
 836        if (err)
 837                goto out_free_inst;
 838
 839        alg = crypto_spawn_aead_alg(spawn);
 840
 841        err = -EINVAL;
 842
 843        /* We only support 16-byte blocks. */
 844        if (crypto_aead_alg_ivsize(alg) != 16)
 845                goto out_drop_alg;
 846
 847        /* Not a stream cipher? */
 848        if (alg->base.cra_blocksize != 1)
 849                goto out_drop_alg;
 850
 851        err = -ENAMETOOLONG;
 852        if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
 853                     "rfc4309(%s)", alg->base.cra_name) >=
 854            CRYPTO_MAX_ALG_NAME ||
 855            snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
 856                     "rfc4309(%s)", alg->base.cra_driver_name) >=
 857            CRYPTO_MAX_ALG_NAME)
 858                goto out_drop_alg;
 859
 860        inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
 861        inst->alg.base.cra_priority = alg->base.cra_priority;
 862        inst->alg.base.cra_blocksize = 1;
 863        inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
 864
 865        inst->alg.ivsize = 8;
 866        inst->alg.maxauthsize = 16;
 867
 868        inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc4309_ctx);
 869
 870        inst->alg.init = crypto_rfc4309_init_tfm;
 871        inst->alg.exit = crypto_rfc4309_exit_tfm;
 872
 873        inst->alg.setkey = crypto_rfc4309_setkey;
 874        inst->alg.setauthsize = crypto_rfc4309_setauthsize;
 875        inst->alg.encrypt = crypto_rfc4309_encrypt;
 876        inst->alg.decrypt = crypto_rfc4309_decrypt;
 877
 878        inst->free = crypto_rfc4309_free;
 879
 880        err = aead_register_instance(tmpl, inst);
 881        if (err)
 882                goto out_drop_alg;
 883
 884out:
 885        return err;
 886
 887out_drop_alg:
 888        crypto_drop_aead(spawn);
 889out_free_inst:
 890        kfree(inst);
 891        goto out;
 892}
 893
 894static struct crypto_template crypto_rfc4309_tmpl = {
 895        .name = "rfc4309",
 896        .create = crypto_rfc4309_create,
 897        .module = THIS_MODULE,
 898};
 899
 900static int __init crypto_ccm_module_init(void)
 901{
 902        int err;
 903
 904        err = crypto_register_template(&crypto_ccm_base_tmpl);
 905        if (err)
 906                goto out;
 907
 908        err = crypto_register_template(&crypto_ccm_tmpl);
 909        if (err)
 910                goto out_undo_base;
 911
 912        err = crypto_register_template(&crypto_rfc4309_tmpl);
 913        if (err)
 914                goto out_undo_ccm;
 915
 916out:
 917        return err;
 918
 919out_undo_ccm:
 920        crypto_unregister_template(&crypto_ccm_tmpl);
 921out_undo_base:
 922        crypto_unregister_template(&crypto_ccm_base_tmpl);
 923        goto out;
 924}
 925
 926static void __exit crypto_ccm_module_exit(void)
 927{
 928        crypto_unregister_template(&crypto_rfc4309_tmpl);
 929        crypto_unregister_template(&crypto_ccm_tmpl);
 930        crypto_unregister_template(&crypto_ccm_base_tmpl);
 931}
 932
 933module_init(crypto_ccm_module_init);
 934module_exit(crypto_ccm_module_exit);
 935
 936MODULE_LICENSE("GPL");
 937MODULE_DESCRIPTION("Counter with CBC MAC");
 938MODULE_ALIAS_CRYPTO("ccm_base");
 939MODULE_ALIAS_CRYPTO("rfc4309");
 940MODULE_ALIAS_CRYPTO("ccm");
 941