cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ccm.c (24014B)


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