xref: /linux/crypto/hmac.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Cryptographic API.
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * HMAC: Keyed-Hashing for Message Authentication (RFC2104).
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
80796ae06SHerbert Xu  * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  * The HMAC implementation is derived from USAGI.
111da177e4SLinus Torvalds  * Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI
121da177e4SLinus Torvalds  */
130796ae06SHerbert Xu 
1403d7db56SCorentin LABBE #include <crypto/hmac.h>
155f7082edSHerbert Xu #include <crypto/internal/hash.h>
16b2ab4a57SHerbert Xu #include <crypto/scatterwalk.h>
170796ae06SHerbert Xu #include <linux/err.h>
1837f36e57SStephan Müller #include <linux/fips.h>
190796ae06SHerbert Xu #include <linux/init.h>
200796ae06SHerbert Xu #include <linux/kernel.h>
210796ae06SHerbert Xu #include <linux/module.h>
22378f058cSDavid Hardeman #include <linux/scatterlist.h>
230796ae06SHerbert Xu #include <linux/string.h>
240796ae06SHerbert Xu 
250796ae06SHerbert Xu struct hmac_ctx {
260b767b4dSHerbert Xu 	struct crypto_shash *hash;
27*25c74a39SEric Biggers 	/* Contains 'u8 ipad[statesize];', then 'u8 opad[statesize];' */
28*25c74a39SEric Biggers 	u8 pads[];
290796ae06SHerbert Xu };
301da177e4SLinus Torvalds 
hmac_setkey(struct crypto_shash * parent,const u8 * inkey,unsigned int keylen)318bd1209cSHerbert Xu static int hmac_setkey(struct crypto_shash *parent,
320796ae06SHerbert Xu 		       const u8 *inkey, unsigned int keylen)
330796ae06SHerbert Xu {
348bd1209cSHerbert Xu 	int bs = crypto_shash_blocksize(parent);
358bd1209cSHerbert Xu 	int ds = crypto_shash_digestsize(parent);
360b767b4dSHerbert Xu 	int ss = crypto_shash_statesize(parent);
37*25c74a39SEric Biggers 	struct hmac_ctx *tctx = crypto_shash_ctx(parent);
38*25c74a39SEric Biggers 	struct crypto_shash *hash = tctx->hash;
39*25c74a39SEric Biggers 	u8 *ipad = &tctx->pads[0];
40*25c74a39SEric Biggers 	u8 *opad = &tctx->pads[ss];
41ffb32e97SJan-Simon Möller 	SHASH_DESC_ON_STACK(shash, hash);
420796ae06SHerbert Xu 	unsigned int i;
430796ae06SHerbert Xu 
4437f36e57SStephan Müller 	if (fips_enabled && (keylen < 112 / 8))
4537f36e57SStephan Müller 		return -EINVAL;
4637f36e57SStephan Müller 
47ffb32e97SJan-Simon Möller 	shash->tfm = hash;
480b767b4dSHerbert Xu 
490796ae06SHerbert Xu 	if (keylen > bs) {
500796ae06SHerbert Xu 		int err;
510796ae06SHerbert Xu 
52ffb32e97SJan-Simon Möller 		err = crypto_shash_digest(shash, inkey, keylen, ipad);
530796ae06SHerbert Xu 		if (err)
540796ae06SHerbert Xu 			return err;
550796ae06SHerbert Xu 
560796ae06SHerbert Xu 		keylen = ds;
570b767b4dSHerbert Xu 	} else
580796ae06SHerbert Xu 		memcpy(ipad, inkey, keylen);
590b767b4dSHerbert Xu 
600796ae06SHerbert Xu 	memset(ipad + keylen, 0, bs - keylen);
610796ae06SHerbert Xu 	memcpy(opad, ipad, bs);
620796ae06SHerbert Xu 
630796ae06SHerbert Xu 	for (i = 0; i < bs; i++) {
6403d7db56SCorentin LABBE 		ipad[i] ^= HMAC_IPAD_VALUE;
6503d7db56SCorentin LABBE 		opad[i] ^= HMAC_OPAD_VALUE;
660796ae06SHerbert Xu 	}
670796ae06SHerbert Xu 
68ffb32e97SJan-Simon Möller 	return crypto_shash_init(shash) ?:
69ffb32e97SJan-Simon Möller 	       crypto_shash_update(shash, ipad, bs) ?:
70ffb32e97SJan-Simon Möller 	       crypto_shash_export(shash, ipad) ?:
71ffb32e97SJan-Simon Möller 	       crypto_shash_init(shash) ?:
72ffb32e97SJan-Simon Möller 	       crypto_shash_update(shash, opad, bs) ?:
73ffb32e97SJan-Simon Möller 	       crypto_shash_export(shash, opad);
740b767b4dSHerbert Xu }
750b767b4dSHerbert Xu 
hmac_export(struct shash_desc * pdesc,void * out)760b767b4dSHerbert Xu static int hmac_export(struct shash_desc *pdesc, void *out)
770b767b4dSHerbert Xu {
780b767b4dSHerbert Xu 	struct shash_desc *desc = shash_desc_ctx(pdesc);
790b767b4dSHerbert Xu 
800b767b4dSHerbert Xu 	return crypto_shash_export(desc, out);
810b767b4dSHerbert Xu }
820b767b4dSHerbert Xu 
hmac_import(struct shash_desc * pdesc,const void * in)830b767b4dSHerbert Xu static int hmac_import(struct shash_desc *pdesc, const void *in)
840b767b4dSHerbert Xu {
850b767b4dSHerbert Xu 	struct shash_desc *desc = shash_desc_ctx(pdesc);
86*25c74a39SEric Biggers 	const struct hmac_ctx *tctx = crypto_shash_ctx(pdesc->tfm);
870b767b4dSHerbert Xu 
88*25c74a39SEric Biggers 	desc->tfm = tctx->hash;
890b767b4dSHerbert Xu 
900b767b4dSHerbert Xu 	return crypto_shash_import(desc, in);
910796ae06SHerbert Xu }
920796ae06SHerbert Xu 
hmac_init(struct shash_desc * pdesc)938bd1209cSHerbert Xu static int hmac_init(struct shash_desc *pdesc)
940796ae06SHerbert Xu {
95*25c74a39SEric Biggers 	const struct hmac_ctx *tctx = crypto_shash_ctx(pdesc->tfm);
96*25c74a39SEric Biggers 
97*25c74a39SEric Biggers 	return hmac_import(pdesc, &tctx->pads[0]);
980796ae06SHerbert Xu }
990796ae06SHerbert Xu 
hmac_update(struct shash_desc * pdesc,const u8 * data,unsigned int nbytes)1008bd1209cSHerbert Xu static int hmac_update(struct shash_desc *pdesc,
1018bd1209cSHerbert Xu 		       const u8 *data, unsigned int nbytes)
1020796ae06SHerbert Xu {
1038bd1209cSHerbert Xu 	struct shash_desc *desc = shash_desc_ctx(pdesc);
1040796ae06SHerbert Xu 
1058bd1209cSHerbert Xu 	return crypto_shash_update(desc, data, nbytes);
1060796ae06SHerbert Xu }
1070796ae06SHerbert Xu 
hmac_final(struct shash_desc * pdesc,u8 * out)1088bd1209cSHerbert Xu static int hmac_final(struct shash_desc *pdesc, u8 *out)
1090796ae06SHerbert Xu {
1108bd1209cSHerbert Xu 	struct crypto_shash *parent = pdesc->tfm;
1118bd1209cSHerbert Xu 	int ds = crypto_shash_digestsize(parent);
1120b767b4dSHerbert Xu 	int ss = crypto_shash_statesize(parent);
113*25c74a39SEric Biggers 	const struct hmac_ctx *tctx = crypto_shash_ctx(parent);
114*25c74a39SEric Biggers 	const u8 *opad = &tctx->pads[ss];
1158bd1209cSHerbert Xu 	struct shash_desc *desc = shash_desc_ctx(pdesc);
1160796ae06SHerbert Xu 
1170b767b4dSHerbert Xu 	return crypto_shash_final(desc, out) ?:
1180b767b4dSHerbert Xu 	       crypto_shash_import(desc, opad) ?:
1190b767b4dSHerbert Xu 	       crypto_shash_finup(desc, out, ds, out);
1200796ae06SHerbert Xu }
1210796ae06SHerbert Xu 
hmac_finup(struct shash_desc * pdesc,const u8 * data,unsigned int nbytes,u8 * out)1228bd1209cSHerbert Xu static int hmac_finup(struct shash_desc *pdesc, const u8 *data,
1230796ae06SHerbert Xu 		      unsigned int nbytes, u8 *out)
1240796ae06SHerbert Xu {
1258bd1209cSHerbert Xu 
1268bd1209cSHerbert Xu 	struct crypto_shash *parent = pdesc->tfm;
1278bd1209cSHerbert Xu 	int ds = crypto_shash_digestsize(parent);
1280b767b4dSHerbert Xu 	int ss = crypto_shash_statesize(parent);
129*25c74a39SEric Biggers 	const struct hmac_ctx *tctx = crypto_shash_ctx(parent);
130*25c74a39SEric Biggers 	const u8 *opad = &tctx->pads[ss];
1318bd1209cSHerbert Xu 	struct shash_desc *desc = shash_desc_ctx(pdesc);
1320796ae06SHerbert Xu 
1330b767b4dSHerbert Xu 	return crypto_shash_finup(desc, data, nbytes, out) ?:
1340b767b4dSHerbert Xu 	       crypto_shash_import(desc, opad) ?:
1350b767b4dSHerbert Xu 	       crypto_shash_finup(desc, out, ds, out);
1360796ae06SHerbert Xu }
1370796ae06SHerbert Xu 
hmac_init_tfm(struct crypto_shash * parent)138d9e1670bSHerbert Xu static int hmac_init_tfm(struct crypto_shash *parent)
1390796ae06SHerbert Xu {
1408bd1209cSHerbert Xu 	struct crypto_shash *hash;
141d9e1670bSHerbert Xu 	struct shash_instance *inst = shash_alg_instance(parent);
142d9e1670bSHerbert Xu 	struct crypto_shash_spawn *spawn = shash_instance_ctx(inst);
143*25c74a39SEric Biggers 	struct hmac_ctx *tctx = crypto_shash_ctx(parent);
1440796ae06SHerbert Xu 
1458bd1209cSHerbert Xu 	hash = crypto_spawn_shash(spawn);
1462e306ee0SHerbert Xu 	if (IS_ERR(hash))
1472e306ee0SHerbert Xu 		return PTR_ERR(hash);
1480796ae06SHerbert Xu 
1498bd1209cSHerbert Xu 	parent->descsize = sizeof(struct shash_desc) +
1508bd1209cSHerbert Xu 			   crypto_shash_descsize(hash);
1518bd1209cSHerbert Xu 
152*25c74a39SEric Biggers 	tctx->hash = hash;
1530796ae06SHerbert Xu 	return 0;
1540796ae06SHerbert Xu }
1550796ae06SHerbert Xu 
hmac_clone_tfm(struct crypto_shash * dst,struct crypto_shash * src)1568538e60dSHerbert Xu static int hmac_clone_tfm(struct crypto_shash *dst, struct crypto_shash *src)
1578538e60dSHerbert Xu {
158*25c74a39SEric Biggers 	struct hmac_ctx *sctx = crypto_shash_ctx(src);
159*25c74a39SEric Biggers 	struct hmac_ctx *dctx = crypto_shash_ctx(dst);
1608538e60dSHerbert Xu 	struct crypto_shash *hash;
1618538e60dSHerbert Xu 
1628538e60dSHerbert Xu 	hash = crypto_clone_shash(sctx->hash);
1638538e60dSHerbert Xu 	if (IS_ERR(hash))
1648538e60dSHerbert Xu 		return PTR_ERR(hash);
1658538e60dSHerbert Xu 
1668538e60dSHerbert Xu 	dctx->hash = hash;
1678538e60dSHerbert Xu 	return 0;
1688538e60dSHerbert Xu }
1698538e60dSHerbert Xu 
hmac_exit_tfm(struct crypto_shash * parent)170d9e1670bSHerbert Xu static void hmac_exit_tfm(struct crypto_shash *parent)
1710796ae06SHerbert Xu {
172*25c74a39SEric Biggers 	struct hmac_ctx *tctx = crypto_shash_ctx(parent);
173f75bd28bSFranziska Naepelt 
174*25c74a39SEric Biggers 	crypto_free_shash(tctx->hash);
1750796ae06SHerbert Xu }
1760796ae06SHerbert Xu 
hmac_create(struct crypto_template * tmpl,struct rtattr ** tb)1778bd1209cSHerbert Xu static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb)
1780796ae06SHerbert Xu {
1798bd1209cSHerbert Xu 	struct shash_instance *inst;
18039e7a283SEric Biggers 	struct crypto_shash_spawn *spawn;
1810796ae06SHerbert Xu 	struct crypto_alg *alg;
1828bd1209cSHerbert Xu 	struct shash_alg *salg;
1837bcb2c99SEric Biggers 	u32 mask;
184ebc610e5SHerbert Xu 	int err;
185ca786dc7SHerbert Xu 	int ds;
1860b767b4dSHerbert Xu 	int ss;
1870796ae06SHerbert Xu 
1887bcb2c99SEric Biggers 	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
189ebc610e5SHerbert Xu 	if (err)
1908bd1209cSHerbert Xu 		return err;
191ebc610e5SHerbert Xu 
19239e7a283SEric Biggers 	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
19339e7a283SEric Biggers 	if (!inst)
19439e7a283SEric Biggers 		return -ENOMEM;
19539e7a283SEric Biggers 	spawn = shash_instance_ctx(inst);
19639e7a283SEric Biggers 
19739e7a283SEric Biggers 	err = crypto_grab_shash(spawn, shash_crypto_instance(inst),
1987bcb2c99SEric Biggers 				crypto_attr_alg_name(tb[1]), 0, mask);
19939e7a283SEric Biggers 	if (err)
20039e7a283SEric Biggers 		goto err_free_inst;
20139e7a283SEric Biggers 	salg = crypto_spawn_shash_alg(spawn);
202af3ff804SEric Biggers 	alg = &salg->base;
2030796ae06SHerbert Xu 
204c2881789SEric Biggers 	/* The underlying hash algorithm must not require a key */
2058bd1209cSHerbert Xu 	err = -EINVAL;
206c2881789SEric Biggers 	if (crypto_shash_alg_needs_key(salg))
20739e7a283SEric Biggers 		goto err_free_inst;
208af3ff804SEric Biggers 
2098bd1209cSHerbert Xu 	ds = salg->digestsize;
2100b767b4dSHerbert Xu 	ss = salg->statesize;
2110b767b4dSHerbert Xu 	if (ds > alg->cra_blocksize ||
2120b767b4dSHerbert Xu 	    ss < alg->cra_blocksize)
21339e7a283SEric Biggers 		goto err_free_inst;
214ca786dc7SHerbert Xu 
21539e7a283SEric Biggers 	err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
2168bd1209cSHerbert Xu 	if (err)
21739e7a283SEric Biggers 		goto err_free_inst;
2180796ae06SHerbert Xu 
2198bd1209cSHerbert Xu 	inst->alg.base.cra_priority = alg->cra_priority;
2208bd1209cSHerbert Xu 	inst->alg.base.cra_blocksize = alg->cra_blocksize;
221*25c74a39SEric Biggers 	inst->alg.base.cra_ctxsize = sizeof(struct hmac_ctx) + (ss * 2);
2220796ae06SHerbert Xu 
2238bd1209cSHerbert Xu 	inst->alg.digestsize = ds;
2240b767b4dSHerbert Xu 	inst->alg.statesize = ss;
2258bd1209cSHerbert Xu 	inst->alg.init = hmac_init;
2268bd1209cSHerbert Xu 	inst->alg.update = hmac_update;
2278bd1209cSHerbert Xu 	inst->alg.final = hmac_final;
2288bd1209cSHerbert Xu 	inst->alg.finup = hmac_finup;
2290b767b4dSHerbert Xu 	inst->alg.export = hmac_export;
2300b767b4dSHerbert Xu 	inst->alg.import = hmac_import;
2318bd1209cSHerbert Xu 	inst->alg.setkey = hmac_setkey;
232d9e1670bSHerbert Xu 	inst->alg.init_tfm = hmac_init_tfm;
2338538e60dSHerbert Xu 	inst->alg.clone_tfm = hmac_clone_tfm;
234d9e1670bSHerbert Xu 	inst->alg.exit_tfm = hmac_exit_tfm;
2358bd1209cSHerbert Xu 
236a39c66ccSEric Biggers 	inst->free = shash_free_singlespawn_instance;
237a39c66ccSEric Biggers 
2388bd1209cSHerbert Xu 	err = shash_register_instance(tmpl, inst);
2398bd1209cSHerbert Xu 	if (err) {
24039e7a283SEric Biggers err_free_inst:
241a39c66ccSEric Biggers 		shash_free_singlespawn_instance(inst);
2428bd1209cSHerbert Xu 	}
2438bd1209cSHerbert Xu 	return err;
2440796ae06SHerbert Xu }
2450796ae06SHerbert Xu 
2460796ae06SHerbert Xu static struct crypto_template hmac_tmpl = {
2470796ae06SHerbert Xu 	.name = "hmac",
2488bd1209cSHerbert Xu 	.create = hmac_create,
2490796ae06SHerbert Xu 	.module = THIS_MODULE,
2500796ae06SHerbert Xu };
2510796ae06SHerbert Xu 
hmac_module_init(void)2520796ae06SHerbert Xu static int __init hmac_module_init(void)
2530796ae06SHerbert Xu {
2540796ae06SHerbert Xu 	return crypto_register_template(&hmac_tmpl);
2550796ae06SHerbert Xu }
2560796ae06SHerbert Xu 
hmac_module_exit(void)2570796ae06SHerbert Xu static void __exit hmac_module_exit(void)
2580796ae06SHerbert Xu {
2590796ae06SHerbert Xu 	crypto_unregister_template(&hmac_tmpl);
2600796ae06SHerbert Xu }
2610796ae06SHerbert Xu 
262c4741b23SEric Biggers subsys_initcall(hmac_module_init);
2630796ae06SHerbert Xu module_exit(hmac_module_exit);
2640796ae06SHerbert Xu 
2650796ae06SHerbert Xu MODULE_LICENSE("GPL");
2660796ae06SHerbert Xu MODULE_DESCRIPTION("HMAC hash algorithm");
2674943ba16SKees Cook MODULE_ALIAS_CRYPTO("hmac");
268