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_skcipher *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 skcipher_request skreq;
  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_skcipher *ctr = ctx->ctr;
  87        struct crypto_cipher *tfm = ctx->cipher;
  88        int err = 0;
  89
  90        crypto_skcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
  91        crypto_skcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
  92                                       CRYPTO_TFM_REQ_MASK);
  93        err = crypto_skcipher_setkey(ctr, key, keylen);
  94        crypto_aead_set_flags(aead, crypto_skcipher_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 skcipher_request *skreq = &pctx->skreq;
 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        skcipher_request_set_tfm(skreq, ctx->ctr);
 370        skcipher_request_set_callback(skreq, pctx->flags,
 371                                      crypto_ccm_encrypt_done, req);
 372        skcipher_request_set_crypt(skreq, pctx->src, dst, cryptlen + 16, iv);
 373        err = crypto_skcipher_encrypt(skreq);
 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 skcipher_request *skreq = &pctx->skreq;
 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        skcipher_request_set_tfm(skreq, ctx->ctr);
 433        skcipher_request_set_callback(skreq, pctx->flags,
 434                                      crypto_ccm_decrypt_done, req);
 435        skcipher_request_set_crypt(skreq, pctx->src, dst, cryptlen + 16, iv);
 436        err = crypto_skcipher_decrypt(skreq);
 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_skcipher *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_skcipher2(&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_skcipher_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_skcipher(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 skcipher_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_skcipher2(&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_spawn_skcipher_alg(&ictx->ctr);
 554
 555        /* Not a stream cipher? */
 556        err = -EINVAL;
 557        if (ctr->base.cra_blocksize != 1)
 558                goto err_drop_ctr;
 559
 560        /* We want the real thing! */
 561        if (crypto_skcipher_alg_ivsize(ctr) != 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->base.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->base.cra_flags & CRYPTO_ALG_ASYNC;
 573        inst->alg.base.cra_priority = (cipher->cra_priority +
 574                                       ctr->base.cra_priority) / 2;
 575        inst->alg.base.cra_blocksize = 1;
 576        inst->alg.base.cra_alignmask = cipher->cra_alignmask |
 577                                       ctr->base.cra_alignmask |
 578                                       (__alignof__(u32) - 1);
 579        inst->alg.ivsize = 16;
 580        inst->alg.chunksize = crypto_skcipher_alg_chunksize(ctr);
 581        inst->alg.maxauthsize = 16;
 582        inst->alg.base.cra_ctxsize = sizeof(struct crypto_ccm_ctx);
 583        inst->alg.init = crypto_ccm_init_tfm;
 584        inst->alg.exit = crypto_ccm_exit_tfm;
 585        inst->alg.setkey = crypto_ccm_setkey;
 586        inst->alg.setauthsize = crypto_ccm_setauthsize;
 587        inst->alg.encrypt = crypto_ccm_encrypt;
 588        inst->alg.decrypt = crypto_ccm_decrypt;
 589
 590        inst->free = crypto_ccm_free;
 591
 592        err = aead_register_instance(tmpl, inst);
 593        if (err)
 594                goto err_drop_ctr;
 595
 596out_put_cipher:
 597        crypto_mod_put(cipher);
 598        return err;
 599
 600err_drop_ctr:
 601        crypto_drop_skcipher(&ictx->ctr);
 602err_drop_cipher:
 603        crypto_drop_spawn(&ictx->cipher);
 604err_free_inst:
 605        kfree(inst);
 606        goto out_put_cipher;
 607}
 608
 609static int crypto_ccm_create(struct crypto_template *tmpl, struct rtattr **tb)
 610{
 611        const char *cipher_name;
 612        char ctr_name[CRYPTO_MAX_ALG_NAME];
 613        char full_name[CRYPTO_MAX_ALG_NAME];
 614
 615        cipher_name = crypto_attr_alg_name(tb[1]);
 616        if (IS_ERR(cipher_name))
 617                return PTR_ERR(cipher_name);
 618
 619        if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)",
 620                     cipher_name) >= CRYPTO_MAX_ALG_NAME)
 621                return -ENAMETOOLONG;
 622
 623        if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "ccm(%s)", cipher_name) >=
 624            CRYPTO_MAX_ALG_NAME)
 625                return -ENAMETOOLONG;
 626
 627        return crypto_ccm_create_common(tmpl, tb, full_name, ctr_name,
 628                                        cipher_name);
 629}
 630
 631static struct crypto_template crypto_ccm_tmpl = {
 632        .name = "ccm",
 633        .create = crypto_ccm_create,
 634        .module = THIS_MODULE,
 635};
 636
 637static int crypto_ccm_base_create(struct crypto_template *tmpl,
 638                                  struct rtattr **tb)
 639{
 640        const char *ctr_name;
 641        const char *cipher_name;
 642        char full_name[CRYPTO_MAX_ALG_NAME];
 643
 644        ctr_name = crypto_attr_alg_name(tb[1]);
 645        if (IS_ERR(ctr_name))
 646                return PTR_ERR(ctr_name);
 647
 648        cipher_name = crypto_attr_alg_name(tb[2]);
 649        if (IS_ERR(cipher_name))
 650                return PTR_ERR(cipher_name);
 651
 652        if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "ccm_base(%s,%s)",
 653                     ctr_name, cipher_name) >= CRYPTO_MAX_ALG_NAME)
 654                return -ENAMETOOLONG;
 655
 656        return crypto_ccm_create_common(tmpl, tb, full_name, ctr_name,
 657                                        cipher_name);
 658}
 659
 660static struct crypto_template crypto_ccm_base_tmpl = {
 661        .name = "ccm_base",
 662        .create = crypto_ccm_base_create,
 663        .module = THIS_MODULE,
 664};
 665
 666static int crypto_rfc4309_setkey(struct crypto_aead *parent, const u8 *key,
 667                                 unsigned int keylen)
 668{
 669        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(parent);
 670        struct crypto_aead *child = ctx->child;
 671        int err;
 672
 673        if (keylen < 3)
 674                return -EINVAL;
 675
 676        keylen -= 3;
 677        memcpy(ctx->nonce, key + keylen, 3);
 678
 679        crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
 680        crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
 681                                     CRYPTO_TFM_REQ_MASK);
 682        err = crypto_aead_setkey(child, key, keylen);
 683        crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
 684                                      CRYPTO_TFM_RES_MASK);
 685
 686        return err;
 687}
 688
 689static int crypto_rfc4309_setauthsize(struct crypto_aead *parent,
 690                                      unsigned int authsize)
 691{
 692        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(parent);
 693
 694        switch (authsize) {
 695        case 8:
 696        case 12:
 697        case 16:
 698                break;
 699        default:
 700                return -EINVAL;
 701        }
 702
 703        return crypto_aead_setauthsize(ctx->child, authsize);
 704}
 705
 706static struct aead_request *crypto_rfc4309_crypt(struct aead_request *req)
 707{
 708        struct crypto_rfc4309_req_ctx *rctx = aead_request_ctx(req);
 709        struct aead_request *subreq = &rctx->subreq;
 710        struct crypto_aead *aead = crypto_aead_reqtfm(req);
 711        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(aead);
 712        struct crypto_aead *child = ctx->child;
 713        struct scatterlist *sg;
 714        u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
 715                           crypto_aead_alignmask(child) + 1);
 716
 717        /* L' */
 718        iv[0] = 3;
 719
 720        memcpy(iv + 1, ctx->nonce, 3);
 721        memcpy(iv + 4, req->iv, 8);
 722
 723        scatterwalk_map_and_copy(iv + 16, req->src, 0, req->assoclen - 8, 0);
 724
 725        sg_init_table(rctx->src, 3);
 726        sg_set_buf(rctx->src, iv + 16, req->assoclen - 8);
 727        sg = scatterwalk_ffwd(rctx->src + 1, req->src, req->assoclen);
 728        if (sg != rctx->src + 1)
 729                sg_chain(rctx->src, 2, sg);
 730
 731        if (req->src != req->dst) {
 732                sg_init_table(rctx->dst, 3);
 733                sg_set_buf(rctx->dst, iv + 16, req->assoclen - 8);
 734                sg = scatterwalk_ffwd(rctx->dst + 1, req->dst, req->assoclen);
 735                if (sg != rctx->dst + 1)
 736                        sg_chain(rctx->dst, 2, sg);
 737        }
 738
 739        aead_request_set_tfm(subreq, child);
 740        aead_request_set_callback(subreq, req->base.flags, req->base.complete,
 741                                  req->base.data);
 742        aead_request_set_crypt(subreq, rctx->src,
 743                               req->src == req->dst ? rctx->src : rctx->dst,
 744                               req->cryptlen, iv);
 745        aead_request_set_ad(subreq, req->assoclen - 8);
 746
 747        return subreq;
 748}
 749
 750static int crypto_rfc4309_encrypt(struct aead_request *req)
 751{
 752        if (req->assoclen != 16 && req->assoclen != 20)
 753                return -EINVAL;
 754
 755        req = crypto_rfc4309_crypt(req);
 756
 757        return crypto_aead_encrypt(req);
 758}
 759
 760static int crypto_rfc4309_decrypt(struct aead_request *req)
 761{
 762        if (req->assoclen != 16 && req->assoclen != 20)
 763                return -EINVAL;
 764
 765        req = crypto_rfc4309_crypt(req);
 766
 767        return crypto_aead_decrypt(req);
 768}
 769
 770static int crypto_rfc4309_init_tfm(struct crypto_aead *tfm)
 771{
 772        struct aead_instance *inst = aead_alg_instance(tfm);
 773        struct crypto_aead_spawn *spawn = aead_instance_ctx(inst);
 774        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(tfm);
 775        struct crypto_aead *aead;
 776        unsigned long align;
 777
 778        aead = crypto_spawn_aead(spawn);
 779        if (IS_ERR(aead))
 780                return PTR_ERR(aead);
 781
 782        ctx->child = aead;
 783
 784        align = crypto_aead_alignmask(aead);
 785        align &= ~(crypto_tfm_ctx_alignment() - 1);
 786        crypto_aead_set_reqsize(
 787                tfm,
 788                sizeof(struct crypto_rfc4309_req_ctx) +
 789                ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) +
 790                align + 32);
 791
 792        return 0;
 793}
 794
 795static void crypto_rfc4309_exit_tfm(struct crypto_aead *tfm)
 796{
 797        struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(tfm);
 798
 799        crypto_free_aead(ctx->child);
 800}
 801
 802static void crypto_rfc4309_free(struct aead_instance *inst)
 803{
 804        crypto_drop_aead(aead_instance_ctx(inst));
 805        kfree(inst);
 806}
 807
 808static int crypto_rfc4309_create(struct crypto_template *tmpl,
 809                                 struct rtattr **tb)
 810{
 811        struct crypto_attr_type *algt;
 812        struct aead_instance *inst;
 813        struct crypto_aead_spawn *spawn;
 814        struct aead_alg *alg;
 815        const char *ccm_name;
 816        int err;
 817
 818        algt = crypto_get_attr_type(tb);
 819        if (IS_ERR(algt))
 820                return PTR_ERR(algt);
 821
 822        if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
 823                return -EINVAL;
 824
 825        ccm_name = crypto_attr_alg_name(tb[1]);
 826        if (IS_ERR(ccm_name))
 827                return PTR_ERR(ccm_name);
 828
 829        inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
 830        if (!inst)
 831                return -ENOMEM;
 832
 833        spawn = aead_instance_ctx(inst);
 834        crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
 835        err = crypto_grab_aead(spawn, ccm_name, 0,
 836                               crypto_requires_sync(algt->type, algt->mask));
 837        if (err)
 838                goto out_free_inst;
 839
 840        alg = crypto_spawn_aead_alg(spawn);
 841
 842        err = -EINVAL;
 843
 844        /* We only support 16-byte blocks. */
 845        if (crypto_aead_alg_ivsize(alg) != 16)
 846                goto out_drop_alg;
 847
 848        /* Not a stream cipher? */
 849        if (alg->base.cra_blocksize != 1)
 850                goto out_drop_alg;
 851
 852        err = -ENAMETOOLONG;
 853        if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
 854                     "rfc4309(%s)", alg->base.cra_name) >=
 855            CRYPTO_MAX_ALG_NAME ||
 856            snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
 857                     "rfc4309(%s)", alg->base.cra_driver_name) >=
 858            CRYPTO_MAX_ALG_NAME)
 859                goto out_drop_alg;
 860
 861        inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
 862        inst->alg.base.cra_priority = alg->base.cra_priority;
 863        inst->alg.base.cra_blocksize = 1;
 864        inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
 865
 866        inst->alg.ivsize = 8;
 867        inst->alg.chunksize = crypto_aead_alg_chunksize(alg);
 868        inst->alg.maxauthsize = 16;
 869
 870        inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc4309_ctx);
 871
 872        inst->alg.init = crypto_rfc4309_init_tfm;
 873        inst->alg.exit = crypto_rfc4309_exit_tfm;
 874
 875        inst->alg.setkey = crypto_rfc4309_setkey;
 876        inst->alg.setauthsize = crypto_rfc4309_setauthsize;
 877        inst->alg.encrypt = crypto_rfc4309_encrypt;
 878        inst->alg.decrypt = crypto_rfc4309_decrypt;
 879
 880        inst->free = crypto_rfc4309_free;
 881
 882        err = aead_register_instance(tmpl, inst);
 883        if (err)
 884                goto out_drop_alg;
 885
 886out:
 887        return err;
 888
 889out_drop_alg:
 890        crypto_drop_aead(spawn);
 891out_free_inst:
 892        kfree(inst);
 893        goto out;
 894}
 895
 896static struct crypto_template crypto_rfc4309_tmpl = {
 897        .name = "rfc4309",
 898        .create = crypto_rfc4309_create,
 899        .module = THIS_MODULE,
 900};
 901
 902static int __init crypto_ccm_module_init(void)
 903{
 904        int err;
 905
 906        err = crypto_register_template(&crypto_ccm_base_tmpl);
 907        if (err)
 908                goto out;
 909
 910        err = crypto_register_template(&crypto_ccm_tmpl);
 911        if (err)
 912                goto out_undo_base;
 913
 914        err = crypto_register_template(&crypto_rfc4309_tmpl);
 915        if (err)
 916                goto out_undo_ccm;
 917
 918out:
 919        return err;
 920
 921out_undo_ccm:
 922        crypto_unregister_template(&crypto_ccm_tmpl);
 923out_undo_base:
 924        crypto_unregister_template(&crypto_ccm_base_tmpl);
 925        goto out;
 926}
 927
 928static void __exit crypto_ccm_module_exit(void)
 929{
 930        crypto_unregister_template(&crypto_rfc4309_tmpl);
 931        crypto_unregister_template(&crypto_ccm_tmpl);
 932        crypto_unregister_template(&crypto_ccm_base_tmpl);
 933}
 934
 935module_init(crypto_ccm_module_init);
 936module_exit(crypto_ccm_module_exit);
 937
 938MODULE_LICENSE("GPL");
 939MODULE_DESCRIPTION("Counter with CBC MAC");
 940MODULE_ALIAS_CRYPTO("ccm_base");
 941MODULE_ALIAS_CRYPTO("rfc4309");
 942MODULE_ALIAS_CRYPTO("ccm");
 943