• Home
  • Raw
  • Download

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
79 return -EOVERFLOW; in set_msg_len()
82 memcpy(block - csize, (u8 *)&data + 4 - csize, csize); in set_msg_len()
91 struct crypto_skcipher *ctr = ctx->ctr; in crypto_ccm_setkey()
92 struct crypto_ahash *mac = ctx->mac; in crypto_ccm_setkey() local
102 crypto_ahash_clear_flags(mac, CRYPTO_TFM_REQ_MASK); in crypto_ccm_setkey()
103 crypto_ahash_set_flags(mac, crypto_aead_get_flags(aead) & in crypto_ccm_setkey()
105 return crypto_ahash_setkey(mac, key, keylen); in crypto_ccm_setkey()
121 return -EINVAL; in crypto_ccm_setauthsize()
131 unsigned int lp = req->iv[0]; in format_input()
137 memcpy(info, req->iv, 16); in format_input()
140 * NIST Special Publication 800-38C in format_input()
142 *info |= (8 * ((m - 2) / 2)); in format_input()
143 if (req->assoclen) in format_input()
146 return set_msg_len(info + 16 - l, cryptlen, l); in format_input()
154 * RFC 3610 and NIST Special Publication 800-38C in format_adata()
174 struct ahash_request *ahreq = &pctx->ahreq; in crypto_ccm_auth()
175 unsigned int assoclen = req->assoclen; in crypto_ccm_auth()
177 u8 *odata = pctx->odata; in crypto_ccm_auth()
178 u8 *idata = pctx->idata; in crypto_ccm_auth()
189 /* format associated data and compute into mac */ in crypto_ccm_auth()
193 sg_chain(sg, 3, req->src); in crypto_ccm_auth()
196 sg_chain(sg, 2, req->src); in crypto_ccm_auth()
199 ahash_request_set_tfm(ahreq, ctx->mac); in crypto_ccm_auth()
200 ahash_request_set_callback(ahreq, pctx->flags, NULL, NULL); in crypto_ccm_auth()
209 /* we need to pad the MAC input to a round multiple of the block size */ in crypto_ccm_auth()
210 ilen = 16 - (assoclen + ilen) % 16; in crypto_ccm_auth()
232 u8 *odata = pctx->odata; in crypto_ccm_encrypt_done()
235 scatterwalk_map_and_copy(odata, req->dst, in crypto_ccm_encrypt_done()
236 req->assoclen + req->cryptlen, in crypto_ccm_encrypt_done()
245 return -EINVAL; in crypto_ccm_check_iv()
254 u8 *iv = req->iv; in crypto_ccm_init_crypt()
261 pctx->flags = aead_request_flags(req); in crypto_ccm_init_crypt()
263 /* Note: rfc 3610 and NIST 800-38C require counter of in crypto_ccm_init_crypt()
266 memset(iv + 15 - iv[0], 0, iv[0] + 1); in crypto_ccm_init_crypt()
268 sg_init_table(pctx->src, 3); in crypto_ccm_init_crypt()
269 sg_set_buf(pctx->src, tag, 16); in crypto_ccm_init_crypt()
270 sg = scatterwalk_ffwd(pctx->src + 1, req->src, req->assoclen); in crypto_ccm_init_crypt()
271 if (sg != pctx->src + 1) in crypto_ccm_init_crypt()
272 sg_chain(pctx->src, 2, sg); in crypto_ccm_init_crypt()
274 if (req->src != req->dst) { in crypto_ccm_init_crypt()
275 sg_init_table(pctx->dst, 3); in crypto_ccm_init_crypt()
276 sg_set_buf(pctx->dst, tag, 16); in crypto_ccm_init_crypt()
277 sg = scatterwalk_ffwd(pctx->dst + 1, req->dst, req->assoclen); in crypto_ccm_init_crypt()
278 if (sg != pctx->dst + 1) in crypto_ccm_init_crypt()
279 sg_chain(pctx->dst, 2, sg); in crypto_ccm_init_crypt()
290 struct skcipher_request *skreq = &pctx->skreq; in crypto_ccm_encrypt()
292 unsigned int cryptlen = req->cryptlen; in crypto_ccm_encrypt()
293 u8 *odata = pctx->odata; in crypto_ccm_encrypt()
294 u8 *iv = req->iv; in crypto_ccm_encrypt()
301 err = crypto_ccm_auth(req, sg_next(pctx->src), cryptlen); in crypto_ccm_encrypt()
305 dst = pctx->src; in crypto_ccm_encrypt()
306 if (req->src != req->dst) in crypto_ccm_encrypt()
307 dst = pctx->dst; in crypto_ccm_encrypt()
309 skcipher_request_set_tfm(skreq, ctx->ctr); in crypto_ccm_encrypt()
310 skcipher_request_set_callback(skreq, pctx->flags, in crypto_ccm_encrypt()
312 skcipher_request_set_crypt(skreq, pctx->src, dst, cryptlen + 16, iv); in crypto_ccm_encrypt()
329 unsigned int cryptlen = req->cryptlen - authsize; in crypto_ccm_decrypt_done()
332 pctx->flags = 0; in crypto_ccm_decrypt_done()
334 dst = sg_next(req->src == req->dst ? pctx->src : pctx->dst); in crypto_ccm_decrypt_done()
338 if (!err && crypto_memneq(pctx->auth_tag, pctx->odata, authsize)) in crypto_ccm_decrypt_done()
339 err = -EBADMSG; in crypto_ccm_decrypt_done()
349 struct skcipher_request *skreq = &pctx->skreq; in crypto_ccm_decrypt()
352 unsigned int cryptlen = req->cryptlen; in crypto_ccm_decrypt()
353 u8 *authtag = pctx->auth_tag; in crypto_ccm_decrypt()
354 u8 *odata = pctx->odata; in crypto_ccm_decrypt()
355 u8 *iv = pctx->idata; in crypto_ccm_decrypt()
358 cryptlen -= authsize; in crypto_ccm_decrypt()
364 scatterwalk_map_and_copy(authtag, sg_next(pctx->src), cryptlen, in crypto_ccm_decrypt()
367 dst = pctx->src; in crypto_ccm_decrypt()
368 if (req->src != req->dst) in crypto_ccm_decrypt()
369 dst = pctx->dst; in crypto_ccm_decrypt()
371 memcpy(iv, req->iv, 16); in crypto_ccm_decrypt()
373 skcipher_request_set_tfm(skreq, ctx->ctr); in crypto_ccm_decrypt()
374 skcipher_request_set_callback(skreq, pctx->flags, in crypto_ccm_decrypt()
376 skcipher_request_set_crypt(skreq, pctx->src, dst, cryptlen + 16, iv); in crypto_ccm_decrypt()
387 return -EBADMSG; in crypto_ccm_decrypt()
397 struct crypto_ahash *mac; in crypto_ccm_init_tfm() local
402 mac = crypto_spawn_ahash(&ictx->mac); in crypto_ccm_init_tfm()
403 if (IS_ERR(mac)) in crypto_ccm_init_tfm()
404 return PTR_ERR(mac); in crypto_ccm_init_tfm()
406 ctr = crypto_spawn_skcipher(&ictx->ctr); in crypto_ccm_init_tfm()
411 ctx->mac = mac; in crypto_ccm_init_tfm()
412 ctx->ctr = ctr; in crypto_ccm_init_tfm()
415 align &= ~(crypto_tfm_ctx_alignment() - 1); in crypto_ccm_init_tfm()
419 max(crypto_ahash_reqsize(mac), crypto_skcipher_reqsize(ctr))); in crypto_ccm_init_tfm()
424 crypto_free_ahash(mac); in crypto_ccm_init_tfm()
432 crypto_free_ahash(ctx->mac); in crypto_ccm_exit_tfm()
433 crypto_free_skcipher(ctx->ctr); in crypto_ccm_exit_tfm()
440 crypto_drop_ahash(&ctx->mac); in crypto_ccm_free()
441 crypto_drop_skcipher(&ctx->ctr); in crypto_ccm_free()
454 struct hash_alg_common *mac; in crypto_ccm_create_common() local
463 return -ENOMEM; in crypto_ccm_create_common()
466 err = crypto_grab_ahash(&ictx->mac, aead_crypto_instance(inst), in crypto_ccm_create_common()
470 mac = crypto_spawn_ahash_alg(&ictx->mac); in crypto_ccm_create_common()
472 err = -EINVAL; in crypto_ccm_create_common()
473 if (strncmp(mac->base.cra_name, "cbcmac(", 7) != 0 || in crypto_ccm_create_common()
474 mac->digestsize != 16) in crypto_ccm_create_common()
477 err = crypto_grab_skcipher(&ictx->ctr, aead_crypto_instance(inst), in crypto_ccm_create_common()
481 ctr = crypto_spawn_skcipher_alg(&ictx->ctr); in crypto_ccm_create_common()
483 /* The skcipher algorithm must be CTR mode, using 16-byte blocks. */ in crypto_ccm_create_common()
484 err = -EINVAL; in crypto_ccm_create_common()
485 if (strncmp(ctr->base.cra_name, "ctr(", 4) != 0 || in crypto_ccm_create_common()
487 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 = mac->base.cra_alignmask | in crypto_ccm_create_common()
508 ctr->base.cra_alignmask; in crypto_ccm_create_common()
509 inst->alg.ivsize = 16; in crypto_ccm_create_common()
510 inst->alg.chunksize = crypto_skcipher_alg_chunksize(ctr); in crypto_ccm_create_common()
511 inst->alg.maxauthsize = 16; in crypto_ccm_create_common()
512 inst->alg.base.cra_ctxsize = sizeof(struct crypto_ccm_ctx); in crypto_ccm_create_common()
513 inst->alg.init = crypto_ccm_init_tfm; in crypto_ccm_create_common()
514 inst->alg.exit = crypto_ccm_exit_tfm; in crypto_ccm_create_common()
515 inst->alg.setkey = crypto_ccm_setkey; in crypto_ccm_create_common()
516 inst->alg.setauthsize = crypto_ccm_setauthsize; in crypto_ccm_create_common()
517 inst->alg.encrypt = crypto_ccm_encrypt; in crypto_ccm_create_common()
518 inst->alg.decrypt = crypto_ccm_decrypt; in crypto_ccm_create_common()
520 inst->free = crypto_ccm_free; in crypto_ccm_create_common()
542 return -ENAMETOOLONG; in crypto_ccm_create()
546 return -ENAMETOOLONG; in crypto_ccm_create()
572 struct crypto_aead *child = ctx->child; in crypto_rfc4309_setkey()
575 return -EINVAL; in crypto_rfc4309_setkey()
577 keylen -= 3; in crypto_rfc4309_setkey()
578 memcpy(ctx->nonce, key + keylen, 3); in crypto_rfc4309_setkey()
597 return -EINVAL; in crypto_rfc4309_setauthsize()
600 return crypto_aead_setauthsize(ctx->child, authsize); in crypto_rfc4309_setauthsize()
606 struct aead_request *subreq = &rctx->subreq; in crypto_rfc4309_crypt()
609 struct crypto_aead *child = ctx->child; in crypto_rfc4309_crypt()
617 memcpy(iv + 1, ctx->nonce, 3); in crypto_rfc4309_crypt()
618 memcpy(iv + 4, req->iv, 8); in crypto_rfc4309_crypt()
620 scatterwalk_map_and_copy(iv + 16, req->src, 0, req->assoclen - 8, 0); in crypto_rfc4309_crypt()
622 sg_init_table(rctx->src, 3); in crypto_rfc4309_crypt()
623 sg_set_buf(rctx->src, iv + 16, req->assoclen - 8); in crypto_rfc4309_crypt()
624 sg = scatterwalk_ffwd(rctx->src + 1, req->src, req->assoclen); in crypto_rfc4309_crypt()
625 if (sg != rctx->src + 1) in crypto_rfc4309_crypt()
626 sg_chain(rctx->src, 2, sg); in crypto_rfc4309_crypt()
628 if (req->src != req->dst) { in crypto_rfc4309_crypt()
629 sg_init_table(rctx->dst, 3); in crypto_rfc4309_crypt()
630 sg_set_buf(rctx->dst, iv + 16, req->assoclen - 8); in crypto_rfc4309_crypt()
631 sg = scatterwalk_ffwd(rctx->dst + 1, req->dst, req->assoclen); in crypto_rfc4309_crypt()
632 if (sg != rctx->dst + 1) in crypto_rfc4309_crypt()
633 sg_chain(rctx->dst, 2, sg); in crypto_rfc4309_crypt()
637 aead_request_set_callback(subreq, req->base.flags, req->base.complete, in crypto_rfc4309_crypt()
638 req->base.data); in crypto_rfc4309_crypt()
639 aead_request_set_crypt(subreq, rctx->src, in crypto_rfc4309_crypt()
640 req->src == req->dst ? rctx->src : rctx->dst, in crypto_rfc4309_crypt()
641 req->cryptlen, iv); in crypto_rfc4309_crypt()
642 aead_request_set_ad(subreq, req->assoclen - 8); in crypto_rfc4309_crypt()
649 if (req->assoclen != 16 && req->assoclen != 20) in crypto_rfc4309_encrypt()
650 return -EINVAL; in crypto_rfc4309_encrypt()
659 if (req->assoclen != 16 && req->assoclen != 20) in crypto_rfc4309_decrypt()
660 return -EINVAL; in crypto_rfc4309_decrypt()
679 ctx->child = aead; in crypto_rfc4309_init_tfm()
682 align &= ~(crypto_tfm_ctx_alignment() - 1); in crypto_rfc4309_init_tfm()
696 crypto_free_aead(ctx->child); in crypto_rfc4309_exit_tfm()
720 return -ENOMEM; in crypto_rfc4309_create()
730 err = -EINVAL; in crypto_rfc4309_create()
732 /* We only support 16-byte blocks. */ in crypto_rfc4309_create()
737 if (alg->base.cra_blocksize != 1) in crypto_rfc4309_create()
740 err = -ENAMETOOLONG; in crypto_rfc4309_create()
741 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, in crypto_rfc4309_create()
742 "rfc4309(%s)", alg->base.cra_name) >= in crypto_rfc4309_create()
744 snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, in crypto_rfc4309_create()
745 "rfc4309(%s)", alg->base.cra_driver_name) >= in crypto_rfc4309_create()
749 inst->alg.base.cra_priority = alg->base.cra_priority; in crypto_rfc4309_create()
750 inst->alg.base.cra_blocksize = 1; in crypto_rfc4309_create()
751 inst->alg.base.cra_alignmask = alg->base.cra_alignmask; in crypto_rfc4309_create()
753 inst->alg.ivsize = 8; in crypto_rfc4309_create()
754 inst->alg.chunksize = crypto_aead_alg_chunksize(alg); in crypto_rfc4309_create()
755 inst->alg.maxauthsize = 16; in crypto_rfc4309_create()
757 inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc4309_ctx); in crypto_rfc4309_create()
759 inst->alg.init = crypto_rfc4309_init_tfm; in crypto_rfc4309_create()
760 inst->alg.exit = crypto_rfc4309_exit_tfm; in crypto_rfc4309_create()
762 inst->alg.setkey = crypto_rfc4309_setkey; in crypto_rfc4309_create()
763 inst->alg.setauthsize = crypto_rfc4309_setauthsize; in crypto_rfc4309_create()
764 inst->alg.encrypt = crypto_rfc4309_encrypt; in crypto_rfc4309_create()
765 inst->alg.decrypt = crypto_rfc4309_decrypt; in crypto_rfc4309_create()
767 inst->free = crypto_rfc4309_free; in crypto_rfc4309_create()
782 return crypto_cipher_setkey(ctx->child, inkey, keylen); in crypto_cbcmac_digest_setkey()
788 int bs = crypto_shash_digestsize(pdesc->tfm); in crypto_cbcmac_digest_init()
789 u8 *dg = (u8 *)ctx + crypto_shash_descsize(pdesc->tfm) - bs; in crypto_cbcmac_digest_init()
791 ctx->len = 0; in crypto_cbcmac_digest_init()
800 struct crypto_shash *parent = pdesc->tfm; in crypto_cbcmac_digest_update()
803 struct crypto_cipher *tfm = tctx->child; in crypto_cbcmac_digest_update()
805 u8 *dg = (u8 *)ctx + crypto_shash_descsize(parent) - bs; in crypto_cbcmac_digest_update()
808 unsigned int l = min(len, bs - ctx->len); in crypto_cbcmac_digest_update()
810 crypto_xor(dg + ctx->len, p, l); in crypto_cbcmac_digest_update()
811 ctx->len +=l; in crypto_cbcmac_digest_update()
812 len -= l; in crypto_cbcmac_digest_update()
815 if (ctx->len == bs) { in crypto_cbcmac_digest_update()
817 ctx->len = 0; in crypto_cbcmac_digest_update()
826 struct crypto_shash *parent = pdesc->tfm; in crypto_cbcmac_digest_final()
829 struct crypto_cipher *tfm = tctx->child; in crypto_cbcmac_digest_final()
831 u8 *dg = (u8 *)ctx + crypto_shash_descsize(parent) - bs; in crypto_cbcmac_digest_final()
833 if (ctx->len) in crypto_cbcmac_digest_final()
843 struct crypto_instance *inst = (void *)tfm->__crt_alg; in cbcmac_init_tfm()
851 ctx->child = cipher; in cbcmac_init_tfm()
859 crypto_free_cipher(ctx->child); in cbcmac_exit_tfm()
876 return -ENOMEM; in cbcmac_create()
885 err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg); in cbcmac_create()
889 inst->alg.base.cra_priority = alg->cra_priority; in cbcmac_create()
890 inst->alg.base.cra_blocksize = 1; in cbcmac_create()
892 inst->alg.digestsize = alg->cra_blocksize; in cbcmac_create()
893 inst->alg.descsize = ALIGN(sizeof(struct cbcmac_desc_ctx), in cbcmac_create()
894 alg->cra_alignmask + 1) + in cbcmac_create()
895 alg->cra_blocksize; in cbcmac_create()
897 inst->alg.base.cra_ctxsize = sizeof(struct cbcmac_tfm_ctx); in cbcmac_create()
898 inst->alg.base.cra_init = cbcmac_init_tfm; in cbcmac_create()
899 inst->alg.base.cra_exit = cbcmac_exit_tfm; in cbcmac_create()
901 inst->alg.init = crypto_cbcmac_digest_init; in cbcmac_create()
902 inst->alg.update = crypto_cbcmac_digest_update; in cbcmac_create()
903 inst->alg.final = crypto_cbcmac_digest_final; in cbcmac_create()
904 inst->alg.setkey = crypto_cbcmac_digest_setkey; in cbcmac_create()
906 inst->free = shash_free_singlespawn_instance; in cbcmac_create()
952 MODULE_DESCRIPTION("Counter with CBC MAC");