Lines Matching +full:mac +full:- +full:base

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * CCM: Counter with CBC-MAC
5 * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
21 struct crypto_ahash_spawn mac; member
25 struct crypto_ahash *mac; member
80 return -EOVERFLOW; in set_msg_len()
83 memcpy(block - csize, (u8 *)&data + 4 - csize, csize); in set_msg_len()
92 struct crypto_skcipher *ctr = ctx->ctr; in crypto_ccm_setkey()
93 struct crypto_ahash *mac = ctx->mac; in crypto_ccm_setkey() local
103 crypto_ahash_clear_flags(mac, CRYPTO_TFM_REQ_MASK); in crypto_ccm_setkey()
104 crypto_ahash_set_flags(mac, crypto_aead_get_flags(aead) & in crypto_ccm_setkey()
106 return crypto_ahash_setkey(mac, key, keylen); in crypto_ccm_setkey()
122 return -EINVAL; in crypto_ccm_setauthsize()
132 unsigned int lp = req->iv[0]; in format_input()
138 memcpy(info, req->iv, 16); in format_input()
141 * NIST Special Publication 800-38C in format_input()
143 *info |= (8 * ((m - 2) / 2)); in format_input()
144 if (req->assoclen) in format_input()
147 return set_msg_len(info + 16 - l, cryptlen, l); in format_input()
155 * RFC 3610 and NIST Special Publication 800-38C in format_adata()
175 struct ahash_request *ahreq = &pctx->ahreq; in crypto_ccm_auth()
176 unsigned int assoclen = req->assoclen; in crypto_ccm_auth()
178 u8 *odata = pctx->odata; in crypto_ccm_auth()
179 u8 *idata = pctx->idata; in crypto_ccm_auth()
190 /* format associated data and compute into mac */ in crypto_ccm_auth()
194 sg_chain(sg, 3, req->src); in crypto_ccm_auth()
197 sg_chain(sg, 2, req->src); in crypto_ccm_auth()
200 ahash_request_set_tfm(ahreq, ctx->mac); in crypto_ccm_auth()
201 ahash_request_set_callback(ahreq, pctx->flags, NULL, NULL); in crypto_ccm_auth()
210 /* we need to pad the MAC input to a round multiple of the block size */ in crypto_ccm_auth()
211 ilen = 16 - (assoclen + ilen) % 16; in crypto_ccm_auth()
233 u8 *odata = pctx->odata; in crypto_ccm_encrypt_done()
236 scatterwalk_map_and_copy(odata, req->dst, in crypto_ccm_encrypt_done()
237 req->assoclen + req->cryptlen, in crypto_ccm_encrypt_done()
246 return -EINVAL; in crypto_ccm_check_iv()
255 u8 *iv = req->iv; in crypto_ccm_init_crypt()
262 pctx->flags = aead_request_flags(req); in crypto_ccm_init_crypt()
264 /* Note: rfc 3610 and NIST 800-38C require counter of in crypto_ccm_init_crypt()
267 memset(iv + 15 - iv[0], 0, iv[0] + 1); in crypto_ccm_init_crypt()
269 sg_init_table(pctx->src, 3); in crypto_ccm_init_crypt()
270 sg_set_buf(pctx->src, tag, 16); in crypto_ccm_init_crypt()
271 sg = scatterwalk_ffwd(pctx->src + 1, req->src, req->assoclen); in crypto_ccm_init_crypt()
272 if (sg != pctx->src + 1) in crypto_ccm_init_crypt()
273 sg_chain(pctx->src, 2, sg); in crypto_ccm_init_crypt()
275 if (req->src != req->dst) { in crypto_ccm_init_crypt()
276 sg_init_table(pctx->dst, 3); in crypto_ccm_init_crypt()
277 sg_set_buf(pctx->dst, tag, 16); in crypto_ccm_init_crypt()
278 sg = scatterwalk_ffwd(pctx->dst + 1, req->dst, req->assoclen); in crypto_ccm_init_crypt()
279 if (sg != pctx->dst + 1) in crypto_ccm_init_crypt()
280 sg_chain(pctx->dst, 2, sg); in crypto_ccm_init_crypt()
291 struct skcipher_request *skreq = &pctx->skreq; in crypto_ccm_encrypt()
293 unsigned int cryptlen = req->cryptlen; in crypto_ccm_encrypt()
294 u8 *odata = pctx->odata; in crypto_ccm_encrypt()
295 u8 *iv = req->iv; in crypto_ccm_encrypt()
302 err = crypto_ccm_auth(req, sg_next(pctx->src), cryptlen); in crypto_ccm_encrypt()
306 dst = pctx->src; in crypto_ccm_encrypt()
307 if (req->src != req->dst) in crypto_ccm_encrypt()
308 dst = pctx->dst; in crypto_ccm_encrypt()
310 skcipher_request_set_tfm(skreq, ctx->ctr); in crypto_ccm_encrypt()
311 skcipher_request_set_callback(skreq, pctx->flags, in crypto_ccm_encrypt()
313 skcipher_request_set_crypt(skreq, pctx->src, dst, cryptlen + 16, iv); in crypto_ccm_encrypt()
330 unsigned int cryptlen = req->cryptlen - authsize; in crypto_ccm_decrypt_done()
333 pctx->flags = 0; in crypto_ccm_decrypt_done()
335 dst = sg_next(req->src == req->dst ? pctx->src : pctx->dst); in crypto_ccm_decrypt_done()
339 if (!err && crypto_memneq(pctx->auth_tag, pctx->odata, authsize)) in crypto_ccm_decrypt_done()
340 err = -EBADMSG; in crypto_ccm_decrypt_done()
350 struct skcipher_request *skreq = &pctx->skreq; in crypto_ccm_decrypt()
353 unsigned int cryptlen = req->cryptlen; in crypto_ccm_decrypt()
354 u8 *authtag = pctx->auth_tag; in crypto_ccm_decrypt()
355 u8 *odata = pctx->odata; in crypto_ccm_decrypt()
356 u8 *iv = pctx->idata; in crypto_ccm_decrypt()
359 cryptlen -= authsize; in crypto_ccm_decrypt()
365 scatterwalk_map_and_copy(authtag, sg_next(pctx->src), cryptlen, in crypto_ccm_decrypt()
368 dst = pctx->src; in crypto_ccm_decrypt()
369 if (req->src != req->dst) in crypto_ccm_decrypt()
370 dst = pctx->dst; in crypto_ccm_decrypt()
372 memcpy(iv, req->iv, 16); in crypto_ccm_decrypt()
374 skcipher_request_set_tfm(skreq, ctx->ctr); in crypto_ccm_decrypt()
375 skcipher_request_set_callback(skreq, pctx->flags, in crypto_ccm_decrypt()
377 skcipher_request_set_crypt(skreq, pctx->src, dst, cryptlen + 16, iv); in crypto_ccm_decrypt()
388 return -EBADMSG; in crypto_ccm_decrypt()
398 struct crypto_ahash *mac; in crypto_ccm_init_tfm() local
403 mac = crypto_spawn_ahash(&ictx->mac); in crypto_ccm_init_tfm()
404 if (IS_ERR(mac)) in crypto_ccm_init_tfm()
405 return PTR_ERR(mac); in crypto_ccm_init_tfm()
407 ctr = crypto_spawn_skcipher(&ictx->ctr); in crypto_ccm_init_tfm()
412 ctx->mac = mac; in crypto_ccm_init_tfm()
413 ctx->ctr = ctr; in crypto_ccm_init_tfm()
416 align &= ~(crypto_tfm_ctx_alignment() - 1); in crypto_ccm_init_tfm()
420 max(crypto_ahash_reqsize(mac), crypto_skcipher_reqsize(ctr))); in crypto_ccm_init_tfm()
425 crypto_free_ahash(mac); in crypto_ccm_init_tfm()
433 crypto_free_ahash(ctx->mac); in crypto_ccm_exit_tfm()
434 crypto_free_skcipher(ctx->ctr); in crypto_ccm_exit_tfm()
441 crypto_drop_ahash(&ctx->mac); in crypto_ccm_free()
442 crypto_drop_skcipher(&ctx->ctr); in crypto_ccm_free()
455 struct hash_alg_common *mac; in crypto_ccm_create_common() local
464 return -ENOMEM; in crypto_ccm_create_common()
467 err = crypto_grab_ahash(&ictx->mac, aead_crypto_instance(inst), in crypto_ccm_create_common()
471 mac = crypto_spawn_ahash_alg(&ictx->mac); in crypto_ccm_create_common()
473 err = -EINVAL; in crypto_ccm_create_common()
474 if (strncmp(mac->base.cra_name, "cbcmac(", 7) != 0 || in crypto_ccm_create_common()
475 mac->digestsize != 16) in crypto_ccm_create_common()
478 err = crypto_grab_skcipher(&ictx->ctr, aead_crypto_instance(inst), in crypto_ccm_create_common()
482 ctr = crypto_spawn_skcipher_alg_common(&ictx->ctr); in crypto_ccm_create_common()
484 /* The skcipher algorithm must be CTR mode, using 16-byte blocks. */ in crypto_ccm_create_common()
485 err = -EINVAL; in crypto_ccm_create_common()
486 if (strncmp(ctr->base.cra_name, "ctr(", 4) != 0 || in crypto_ccm_create_common()
487 ctr->ivsize != 16 || ctr->base.cra_blocksize != 1) in crypto_ccm_create_common()
491 if (strcmp(ctr->base.cra_name + 4, mac->base.cra_name + 7) != 0) in crypto_ccm_create_common()
494 err = -ENAMETOOLONG; in crypto_ccm_create_common()
495 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, in crypto_ccm_create_common()
496 "ccm(%s", ctr->base.cra_name + 4) >= CRYPTO_MAX_ALG_NAME) in crypto_ccm_create_common()
499 if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, in crypto_ccm_create_common()
500 "ccm_base(%s,%s)", ctr->base.cra_driver_name, in crypto_ccm_create_common()
501 mac->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) in crypto_ccm_create_common()
504 inst->alg.base.cra_priority = (mac->base.cra_priority + in crypto_ccm_create_common()
505 ctr->base.cra_priority) / 2; in crypto_ccm_create_common()
506 inst->alg.base.cra_blocksize = 1; in crypto_ccm_create_common()
507 inst->alg.base.cra_alignmask = ctr->base.cra_alignmask; in crypto_ccm_create_common()
508 inst->alg.ivsize = 16; in crypto_ccm_create_common()
509 inst->alg.chunksize = ctr->chunksize; in crypto_ccm_create_common()
510 inst->alg.maxauthsize = 16; in crypto_ccm_create_common()
511 inst->alg.base.cra_ctxsize = sizeof(struct crypto_ccm_ctx); in crypto_ccm_create_common()
512 inst->alg.init = crypto_ccm_init_tfm; in crypto_ccm_create_common()
513 inst->alg.exit = crypto_ccm_exit_tfm; in crypto_ccm_create_common()
514 inst->alg.setkey = crypto_ccm_setkey; in crypto_ccm_create_common()
515 inst->alg.setauthsize = crypto_ccm_setauthsize; in crypto_ccm_create_common()
516 inst->alg.encrypt = crypto_ccm_encrypt; in crypto_ccm_create_common()
517 inst->alg.decrypt = crypto_ccm_decrypt; in crypto_ccm_create_common()
519 inst->free = crypto_ccm_free; in crypto_ccm_create_common()
541 return -ENAMETOOLONG; in crypto_ccm_create()
545 return -ENAMETOOLONG; in crypto_ccm_create()
571 struct crypto_aead *child = ctx->child; in crypto_rfc4309_setkey()
574 return -EINVAL; in crypto_rfc4309_setkey()
576 keylen -= 3; in crypto_rfc4309_setkey()
577 memcpy(ctx->nonce, key + keylen, 3); in crypto_rfc4309_setkey()
596 return -EINVAL; in crypto_rfc4309_setauthsize()
599 return crypto_aead_setauthsize(ctx->child, authsize); in crypto_rfc4309_setauthsize()
605 struct aead_request *subreq = &rctx->subreq; in crypto_rfc4309_crypt()
608 struct crypto_aead *child = ctx->child; in crypto_rfc4309_crypt()
616 memcpy(iv + 1, ctx->nonce, 3); in crypto_rfc4309_crypt()
617 memcpy(iv + 4, req->iv, 8); in crypto_rfc4309_crypt()
619 scatterwalk_map_and_copy(iv + 16, req->src, 0, req->assoclen - 8, 0); in crypto_rfc4309_crypt()
621 sg_init_table(rctx->src, 3); in crypto_rfc4309_crypt()
622 sg_set_buf(rctx->src, iv + 16, req->assoclen - 8); in crypto_rfc4309_crypt()
623 sg = scatterwalk_ffwd(rctx->src + 1, req->src, req->assoclen); in crypto_rfc4309_crypt()
624 if (sg != rctx->src + 1) in crypto_rfc4309_crypt()
625 sg_chain(rctx->src, 2, sg); in crypto_rfc4309_crypt()
627 if (req->src != req->dst) { in crypto_rfc4309_crypt()
628 sg_init_table(rctx->dst, 3); in crypto_rfc4309_crypt()
629 sg_set_buf(rctx->dst, iv + 16, req->assoclen - 8); in crypto_rfc4309_crypt()
630 sg = scatterwalk_ffwd(rctx->dst + 1, req->dst, req->assoclen); in crypto_rfc4309_crypt()
631 if (sg != rctx->dst + 1) in crypto_rfc4309_crypt()
632 sg_chain(rctx->dst, 2, sg); in crypto_rfc4309_crypt()
636 aead_request_set_callback(subreq, req->base.flags, req->base.complete, in crypto_rfc4309_crypt()
637 req->base.data); in crypto_rfc4309_crypt()
638 aead_request_set_crypt(subreq, rctx->src, in crypto_rfc4309_crypt()
639 req->src == req->dst ? rctx->src : rctx->dst, in crypto_rfc4309_crypt()
640 req->cryptlen, iv); in crypto_rfc4309_crypt()
641 aead_request_set_ad(subreq, req->assoclen - 8); in crypto_rfc4309_crypt()
648 if (req->assoclen != 16 && req->assoclen != 20) in crypto_rfc4309_encrypt()
649 return -EINVAL; in crypto_rfc4309_encrypt()
658 if (req->assoclen != 16 && req->assoclen != 20) in crypto_rfc4309_decrypt()
659 return -EINVAL; in crypto_rfc4309_decrypt()
678 ctx->child = aead; in crypto_rfc4309_init_tfm()
681 align &= ~(crypto_tfm_ctx_alignment() - 1); in crypto_rfc4309_init_tfm()
695 crypto_free_aead(ctx->child); in crypto_rfc4309_exit_tfm()
719 return -ENOMEM; in crypto_rfc4309_create()
729 err = -EINVAL; in crypto_rfc4309_create()
731 /* We only support 16-byte blocks. */ in crypto_rfc4309_create()
736 if (alg->base.cra_blocksize != 1) in crypto_rfc4309_create()
739 err = -ENAMETOOLONG; in crypto_rfc4309_create()
740 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, in crypto_rfc4309_create()
741 "rfc4309(%s)", alg->base.cra_name) >= in crypto_rfc4309_create()
743 snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, in crypto_rfc4309_create()
744 "rfc4309(%s)", alg->base.cra_driver_name) >= in crypto_rfc4309_create()
748 inst->alg.base.cra_priority = alg->base.cra_priority; in crypto_rfc4309_create()
749 inst->alg.base.cra_blocksize = 1; in crypto_rfc4309_create()
750 inst->alg.base.cra_alignmask = alg->base.cra_alignmask; in crypto_rfc4309_create()
752 inst->alg.ivsize = 8; in crypto_rfc4309_create()
753 inst->alg.chunksize = crypto_aead_alg_chunksize(alg); in crypto_rfc4309_create()
754 inst->alg.maxauthsize = 16; in crypto_rfc4309_create()
756 inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc4309_ctx); in crypto_rfc4309_create()
758 inst->alg.init = crypto_rfc4309_init_tfm; in crypto_rfc4309_create()
759 inst->alg.exit = crypto_rfc4309_exit_tfm; in crypto_rfc4309_create()
761 inst->alg.setkey = crypto_rfc4309_setkey; in crypto_rfc4309_create()
762 inst->alg.setauthsize = crypto_rfc4309_setauthsize; in crypto_rfc4309_create()
763 inst->alg.encrypt = crypto_rfc4309_encrypt; in crypto_rfc4309_create()
764 inst->alg.decrypt = crypto_rfc4309_decrypt; in crypto_rfc4309_create()
766 inst->free = crypto_rfc4309_free; in crypto_rfc4309_create()
781 return crypto_cipher_setkey(ctx->child, inkey, keylen); in crypto_cbcmac_digest_setkey()
787 int bs = crypto_shash_digestsize(pdesc->tfm); in crypto_cbcmac_digest_init()
789 ctx->len = 0; in crypto_cbcmac_digest_init()
790 memset(ctx->dg, 0, bs); in crypto_cbcmac_digest_init()
798 struct crypto_shash *parent = pdesc->tfm; in crypto_cbcmac_digest_update()
801 struct crypto_cipher *tfm = tctx->child; in crypto_cbcmac_digest_update()
805 unsigned int l = min(len, bs - ctx->len); in crypto_cbcmac_digest_update()
807 crypto_xor(&ctx->dg[ctx->len], p, l); in crypto_cbcmac_digest_update()
808 ctx->len +=l; in crypto_cbcmac_digest_update()
809 len -= l; in crypto_cbcmac_digest_update()
812 if (ctx->len == bs) { in crypto_cbcmac_digest_update()
813 crypto_cipher_encrypt_one(tfm, ctx->dg, ctx->dg); in crypto_cbcmac_digest_update()
814 ctx->len = 0; in crypto_cbcmac_digest_update()
823 struct crypto_shash *parent = pdesc->tfm; in crypto_cbcmac_digest_final()
826 struct crypto_cipher *tfm = tctx->child; in crypto_cbcmac_digest_final()
829 if (ctx->len) in crypto_cbcmac_digest_final()
830 crypto_cipher_encrypt_one(tfm, ctx->dg, ctx->dg); in crypto_cbcmac_digest_final()
832 memcpy(out, ctx->dg, bs); in crypto_cbcmac_digest_final()
839 struct crypto_instance *inst = (void *)tfm->__crt_alg; in cbcmac_init_tfm()
847 ctx->child = cipher; in cbcmac_init_tfm()
855 crypto_free_cipher(ctx->child); in cbcmac_exit_tfm()
872 return -ENOMEM; in cbcmac_create()
881 err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg); in cbcmac_create()
885 inst->alg.base.cra_priority = alg->cra_priority; in cbcmac_create()
886 inst->alg.base.cra_blocksize = 1; in cbcmac_create()
888 inst->alg.digestsize = alg->cra_blocksize; in cbcmac_create()
889 inst->alg.descsize = sizeof(struct cbcmac_desc_ctx) + in cbcmac_create()
890 alg->cra_blocksize; in cbcmac_create()
892 inst->alg.base.cra_ctxsize = sizeof(struct cbcmac_tfm_ctx); in cbcmac_create()
893 inst->alg.base.cra_init = cbcmac_init_tfm; in cbcmac_create()
894 inst->alg.base.cra_exit = cbcmac_exit_tfm; in cbcmac_create()
896 inst->alg.init = crypto_cbcmac_digest_init; in cbcmac_create()
897 inst->alg.update = crypto_cbcmac_digest_update; in cbcmac_create()
898 inst->alg.final = crypto_cbcmac_digest_final; in cbcmac_create()
899 inst->alg.setkey = crypto_cbcmac_digest_setkey; in cbcmac_create()
901 inst->free = shash_free_singlespawn_instance; in cbcmac_create()
947 MODULE_DESCRIPTION("Counter with CBC MAC");