11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Cryptographic API. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * HMAC: Keyed-Hashing for Message Authentication (RFC2104). 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 70796ae06SHerbert Xu * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * The HMAC implementation is derived from USAGI. 101da177e4SLinus Torvalds * Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify it 131da177e4SLinus Torvalds * under the terms of the GNU General Public License as published by the Free 141da177e4SLinus Torvalds * Software Foundation; either version 2 of the License, or (at your option) 151da177e4SLinus Torvalds * any later version. 161da177e4SLinus Torvalds * 171da177e4SLinus Torvalds */ 180796ae06SHerbert Xu 1903d7db56SCorentin LABBE #include <crypto/hmac.h> 205f7082edSHerbert Xu #include <crypto/internal/hash.h> 21b2ab4a57SHerbert Xu #include <crypto/scatterwalk.h> 220796ae06SHerbert Xu #include <linux/err.h> 230796ae06SHerbert Xu #include <linux/init.h> 240796ae06SHerbert Xu #include <linux/kernel.h> 250796ae06SHerbert Xu #include <linux/module.h> 26378f058cSDavid Hardeman #include <linux/scatterlist.h> 270796ae06SHerbert Xu #include <linux/string.h> 280796ae06SHerbert Xu 290796ae06SHerbert Xu struct hmac_ctx { 300b767b4dSHerbert Xu struct crypto_shash *hash; 310796ae06SHerbert Xu }; 321da177e4SLinus Torvalds 330796ae06SHerbert Xu static inline void *align_ptr(void *p, unsigned int align) 340796ae06SHerbert Xu { 350796ae06SHerbert Xu return (void *)ALIGN((unsigned long)p, align); 360796ae06SHerbert Xu } 370796ae06SHerbert Xu 388bd1209cSHerbert Xu static inline struct hmac_ctx *hmac_ctx(struct crypto_shash *tfm) 390796ae06SHerbert Xu { 408bd1209cSHerbert Xu return align_ptr(crypto_shash_ctx_aligned(tfm) + 410b767b4dSHerbert Xu crypto_shash_statesize(tfm) * 2, 428bd1209cSHerbert Xu crypto_tfm_ctx_alignment()); 430796ae06SHerbert Xu } 440796ae06SHerbert Xu 458bd1209cSHerbert Xu static int hmac_setkey(struct crypto_shash *parent, 460796ae06SHerbert Xu const u8 *inkey, unsigned int keylen) 470796ae06SHerbert Xu { 488bd1209cSHerbert Xu int bs = crypto_shash_blocksize(parent); 498bd1209cSHerbert Xu int ds = crypto_shash_digestsize(parent); 500b767b4dSHerbert Xu int ss = crypto_shash_statesize(parent); 518bd1209cSHerbert Xu char *ipad = crypto_shash_ctx_aligned(parent); 520b767b4dSHerbert Xu char *opad = ipad + ss; 530b767b4dSHerbert Xu struct hmac_ctx *ctx = align_ptr(opad + ss, 548bd1209cSHerbert Xu crypto_tfm_ctx_alignment()); 550b767b4dSHerbert Xu struct crypto_shash *hash = ctx->hash; 56ffb32e97SJan-Simon Möller SHASH_DESC_ON_STACK(shash, hash); 570796ae06SHerbert Xu unsigned int i; 580796ae06SHerbert Xu 59ffb32e97SJan-Simon Möller shash->tfm = hash; 60ffb32e97SJan-Simon Möller shash->flags = crypto_shash_get_flags(parent) 61ffb32e97SJan-Simon Möller & CRYPTO_TFM_REQ_MAY_SLEEP; 620b767b4dSHerbert Xu 630796ae06SHerbert Xu if (keylen > bs) { 640796ae06SHerbert Xu int err; 650796ae06SHerbert Xu 66ffb32e97SJan-Simon Möller err = crypto_shash_digest(shash, inkey, keylen, ipad); 670796ae06SHerbert Xu if (err) 680796ae06SHerbert Xu return err; 690796ae06SHerbert Xu 700796ae06SHerbert Xu keylen = ds; 710b767b4dSHerbert Xu } else 720796ae06SHerbert Xu memcpy(ipad, inkey, keylen); 730b767b4dSHerbert Xu 740796ae06SHerbert Xu memset(ipad + keylen, 0, bs - keylen); 750796ae06SHerbert Xu memcpy(opad, ipad, bs); 760796ae06SHerbert Xu 770796ae06SHerbert Xu for (i = 0; i < bs; i++) { 7803d7db56SCorentin LABBE ipad[i] ^= HMAC_IPAD_VALUE; 7903d7db56SCorentin LABBE opad[i] ^= HMAC_OPAD_VALUE; 800796ae06SHerbert Xu } 810796ae06SHerbert Xu 82ffb32e97SJan-Simon Möller return crypto_shash_init(shash) ?: 83ffb32e97SJan-Simon Möller crypto_shash_update(shash, ipad, bs) ?: 84ffb32e97SJan-Simon Möller crypto_shash_export(shash, ipad) ?: 85ffb32e97SJan-Simon Möller crypto_shash_init(shash) ?: 86ffb32e97SJan-Simon Möller crypto_shash_update(shash, opad, bs) ?: 87ffb32e97SJan-Simon Möller crypto_shash_export(shash, opad); 880b767b4dSHerbert Xu } 890b767b4dSHerbert Xu 900b767b4dSHerbert Xu static int hmac_export(struct shash_desc *pdesc, void *out) 910b767b4dSHerbert Xu { 920b767b4dSHerbert Xu struct shash_desc *desc = shash_desc_ctx(pdesc); 930b767b4dSHerbert Xu 940b767b4dSHerbert Xu desc->flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; 950b767b4dSHerbert Xu 960b767b4dSHerbert Xu return crypto_shash_export(desc, out); 970b767b4dSHerbert Xu } 980b767b4dSHerbert Xu 990b767b4dSHerbert Xu static int hmac_import(struct shash_desc *pdesc, const void *in) 1000b767b4dSHerbert Xu { 1010b767b4dSHerbert Xu struct shash_desc *desc = shash_desc_ctx(pdesc); 1020b767b4dSHerbert Xu struct hmac_ctx *ctx = hmac_ctx(pdesc->tfm); 1030b767b4dSHerbert Xu 1040b767b4dSHerbert Xu desc->tfm = ctx->hash; 1050b767b4dSHerbert Xu desc->flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; 1060b767b4dSHerbert Xu 1070b767b4dSHerbert Xu return crypto_shash_import(desc, in); 1080796ae06SHerbert Xu } 1090796ae06SHerbert Xu 1108bd1209cSHerbert Xu static int hmac_init(struct shash_desc *pdesc) 1110796ae06SHerbert Xu { 1120b767b4dSHerbert Xu return hmac_import(pdesc, crypto_shash_ctx_aligned(pdesc->tfm)); 1130796ae06SHerbert Xu } 1140796ae06SHerbert Xu 1158bd1209cSHerbert Xu static int hmac_update(struct shash_desc *pdesc, 1168bd1209cSHerbert Xu const u8 *data, unsigned int nbytes) 1170796ae06SHerbert Xu { 1188bd1209cSHerbert Xu struct shash_desc *desc = shash_desc_ctx(pdesc); 1190796ae06SHerbert Xu 1208bd1209cSHerbert Xu desc->flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; 1210796ae06SHerbert Xu 1228bd1209cSHerbert Xu return crypto_shash_update(desc, data, nbytes); 1230796ae06SHerbert Xu } 1240796ae06SHerbert Xu 1258bd1209cSHerbert Xu static int hmac_final(struct shash_desc *pdesc, u8 *out) 1260796ae06SHerbert Xu { 1278bd1209cSHerbert Xu struct crypto_shash *parent = pdesc->tfm; 1288bd1209cSHerbert Xu int ds = crypto_shash_digestsize(parent); 1290b767b4dSHerbert Xu int ss = crypto_shash_statesize(parent); 1300b767b4dSHerbert Xu char *opad = crypto_shash_ctx_aligned(parent) + ss; 1318bd1209cSHerbert Xu struct shash_desc *desc = shash_desc_ctx(pdesc); 1320796ae06SHerbert Xu 1338bd1209cSHerbert Xu desc->flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; 1340796ae06SHerbert Xu 1350b767b4dSHerbert Xu return crypto_shash_final(desc, out) ?: 1360b767b4dSHerbert Xu crypto_shash_import(desc, opad) ?: 1370b767b4dSHerbert Xu crypto_shash_finup(desc, out, ds, out); 1380796ae06SHerbert Xu } 1390796ae06SHerbert Xu 1408bd1209cSHerbert Xu static int hmac_finup(struct shash_desc *pdesc, const u8 *data, 1410796ae06SHerbert Xu unsigned int nbytes, u8 *out) 1420796ae06SHerbert Xu { 1438bd1209cSHerbert Xu 1448bd1209cSHerbert Xu struct crypto_shash *parent = pdesc->tfm; 1458bd1209cSHerbert Xu int ds = crypto_shash_digestsize(parent); 1460b767b4dSHerbert Xu int ss = crypto_shash_statesize(parent); 1470b767b4dSHerbert Xu char *opad = crypto_shash_ctx_aligned(parent) + ss; 1488bd1209cSHerbert Xu struct shash_desc *desc = shash_desc_ctx(pdesc); 1490796ae06SHerbert Xu 1508bd1209cSHerbert Xu desc->flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; 1510796ae06SHerbert Xu 1520b767b4dSHerbert Xu return crypto_shash_finup(desc, data, nbytes, out) ?: 1530b767b4dSHerbert Xu crypto_shash_import(desc, opad) ?: 1540b767b4dSHerbert Xu crypto_shash_finup(desc, out, ds, out); 1550796ae06SHerbert Xu } 1560796ae06SHerbert Xu 1570796ae06SHerbert Xu static int hmac_init_tfm(struct crypto_tfm *tfm) 1580796ae06SHerbert Xu { 1598bd1209cSHerbert Xu struct crypto_shash *parent = __crypto_shash_cast(tfm); 1608bd1209cSHerbert Xu struct crypto_shash *hash; 1610796ae06SHerbert Xu struct crypto_instance *inst = (void *)tfm->__crt_alg; 1628bd1209cSHerbert Xu struct crypto_shash_spawn *spawn = crypto_instance_ctx(inst); 1638bd1209cSHerbert Xu struct hmac_ctx *ctx = hmac_ctx(parent); 1640796ae06SHerbert Xu 1658bd1209cSHerbert Xu hash = crypto_spawn_shash(spawn); 1662e306ee0SHerbert Xu if (IS_ERR(hash)) 1672e306ee0SHerbert Xu return PTR_ERR(hash); 1680796ae06SHerbert Xu 1698bd1209cSHerbert Xu parent->descsize = sizeof(struct shash_desc) + 1708bd1209cSHerbert Xu crypto_shash_descsize(hash); 1718bd1209cSHerbert Xu 1720b767b4dSHerbert Xu ctx->hash = hash; 1730796ae06SHerbert Xu return 0; 1740796ae06SHerbert Xu } 1750796ae06SHerbert Xu 1760796ae06SHerbert Xu static void hmac_exit_tfm(struct crypto_tfm *tfm) 1770796ae06SHerbert Xu { 1788bd1209cSHerbert Xu struct hmac_ctx *ctx = hmac_ctx(__crypto_shash_cast(tfm)); 1790b767b4dSHerbert Xu crypto_free_shash(ctx->hash); 1800796ae06SHerbert Xu } 1810796ae06SHerbert Xu 1828bd1209cSHerbert Xu static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) 1830796ae06SHerbert Xu { 1848bd1209cSHerbert Xu struct shash_instance *inst; 1850796ae06SHerbert Xu struct crypto_alg *alg; 1868bd1209cSHerbert Xu struct shash_alg *salg; 187ebc610e5SHerbert Xu int err; 188ca786dc7SHerbert Xu int ds; 1890b767b4dSHerbert Xu int ss; 1900796ae06SHerbert Xu 1918bd1209cSHerbert Xu err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH); 192ebc610e5SHerbert Xu if (err) 1938bd1209cSHerbert Xu return err; 194ebc610e5SHerbert Xu 1958bd1209cSHerbert Xu salg = shash_attr_alg(tb[1], 0, 0); 1968bd1209cSHerbert Xu if (IS_ERR(salg)) 1978bd1209cSHerbert Xu return PTR_ERR(salg); 1980796ae06SHerbert Xu 1998bd1209cSHerbert Xu err = -EINVAL; 2008bd1209cSHerbert Xu ds = salg->digestsize; 2010b767b4dSHerbert Xu ss = salg->statesize; 2028bd1209cSHerbert Xu alg = &salg->base; 2030b767b4dSHerbert Xu if (ds > alg->cra_blocksize || 2040b767b4dSHerbert Xu ss < alg->cra_blocksize) 205ca786dc7SHerbert Xu goto out_put_alg; 206ca786dc7SHerbert Xu 2078bd1209cSHerbert Xu inst = shash_alloc_instance("hmac", alg); 2083b3fc322SHerbert Xu err = PTR_ERR(inst); 2090796ae06SHerbert Xu if (IS_ERR(inst)) 2100796ae06SHerbert Xu goto out_put_alg; 2110796ae06SHerbert Xu 2128bd1209cSHerbert Xu err = crypto_init_shash_spawn(shash_instance_ctx(inst), salg, 2138bd1209cSHerbert Xu shash_crypto_instance(inst)); 2148bd1209cSHerbert Xu if (err) 2158bd1209cSHerbert Xu goto out_free_inst; 2160796ae06SHerbert Xu 2178bd1209cSHerbert Xu inst->alg.base.cra_priority = alg->cra_priority; 2188bd1209cSHerbert Xu inst->alg.base.cra_blocksize = alg->cra_blocksize; 2198bd1209cSHerbert Xu inst->alg.base.cra_alignmask = alg->cra_alignmask; 2200796ae06SHerbert Xu 2210b767b4dSHerbert Xu ss = ALIGN(ss, alg->cra_alignmask + 1); 2228bd1209cSHerbert Xu inst->alg.digestsize = ds; 2230b767b4dSHerbert Xu inst->alg.statesize = ss; 2240796ae06SHerbert Xu 2258bd1209cSHerbert Xu inst->alg.base.cra_ctxsize = sizeof(struct hmac_ctx) + 2260b767b4dSHerbert Xu ALIGN(ss * 2, crypto_tfm_ctx_alignment()); 2270796ae06SHerbert Xu 2288bd1209cSHerbert Xu inst->alg.base.cra_init = hmac_init_tfm; 2298bd1209cSHerbert Xu inst->alg.base.cra_exit = hmac_exit_tfm; 2308bd1209cSHerbert Xu 2318bd1209cSHerbert Xu inst->alg.init = hmac_init; 2328bd1209cSHerbert Xu inst->alg.update = hmac_update; 2338bd1209cSHerbert Xu inst->alg.final = hmac_final; 2348bd1209cSHerbert Xu inst->alg.finup = hmac_finup; 2350b767b4dSHerbert Xu inst->alg.export = hmac_export; 2360b767b4dSHerbert Xu inst->alg.import = hmac_import; 2378bd1209cSHerbert Xu inst->alg.setkey = hmac_setkey; 2388bd1209cSHerbert Xu 2398bd1209cSHerbert Xu err = shash_register_instance(tmpl, inst); 2408bd1209cSHerbert Xu if (err) { 2418bd1209cSHerbert Xu out_free_inst: 2428bd1209cSHerbert Xu shash_free_instance(shash_crypto_instance(inst)); 2438bd1209cSHerbert Xu } 2440796ae06SHerbert Xu 2450796ae06SHerbert Xu out_put_alg: 2460796ae06SHerbert Xu crypto_mod_put(alg); 2478bd1209cSHerbert Xu return err; 2480796ae06SHerbert Xu } 2490796ae06SHerbert Xu 2500796ae06SHerbert Xu static struct crypto_template hmac_tmpl = { 2510796ae06SHerbert Xu .name = "hmac", 2528bd1209cSHerbert Xu .create = hmac_create, 2538bd1209cSHerbert Xu .free = shash_free_instance, 2540796ae06SHerbert Xu .module = THIS_MODULE, 2550796ae06SHerbert Xu }; 2560796ae06SHerbert Xu 2570796ae06SHerbert Xu static int __init hmac_module_init(void) 2580796ae06SHerbert Xu { 2590796ae06SHerbert Xu return crypto_register_template(&hmac_tmpl); 2600796ae06SHerbert Xu } 2610796ae06SHerbert Xu 2620796ae06SHerbert Xu static void __exit hmac_module_exit(void) 2630796ae06SHerbert Xu { 2640796ae06SHerbert Xu crypto_unregister_template(&hmac_tmpl); 2650796ae06SHerbert Xu } 2660796ae06SHerbert Xu 2670796ae06SHerbert Xu module_init(hmac_module_init); 2680796ae06SHerbert Xu module_exit(hmac_module_exit); 2690796ae06SHerbert Xu 2700796ae06SHerbert Xu MODULE_LICENSE("GPL"); 2710796ae06SHerbert Xu MODULE_DESCRIPTION("HMAC hash algorithm"); 2724943ba16SKees Cook MODULE_ALIAS_CRYPTO("hmac"); 273