Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4 LT |
2 | /* |
3 | * Cryptographic API. | |
4 | * | |
5 | * HMAC: Keyed-Hashing for Message Authentication (RFC2104). | |
6 | * | |
7 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | |
0796ae06 | 8 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> |
1da177e4 LT |
9 | * |
10 | * The HMAC implementation is derived from USAGI. | |
11 | * Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI | |
1da177e4 | 12 | */ |
0796ae06 | 13 | |
03d7db56 | 14 | #include <crypto/hmac.h> |
5f7082ed | 15 | #include <crypto/internal/hash.h> |
0796ae06 | 16 | #include <linux/err.h> |
37f36e57 | 17 | #include <linux/fips.h> |
0796ae06 HX |
18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | |
a05a8bc5 | 20 | #include <linux/slab.h> |
0796ae06 HX |
21 | #include <linux/string.h> |
22 | ||
23 | struct hmac_ctx { | |
0b767b4d | 24 | struct crypto_shash *hash; |
25c74a39 EB |
25 | /* Contains 'u8 ipad[statesize];', then 'u8 opad[statesize];' */ |
26 | u8 pads[]; | |
0796ae06 | 27 | }; |
1da177e4 | 28 | |
c3103416 HX |
29 | struct ahash_hmac_ctx { |
30 | struct crypto_ahash *hash; | |
31 | /* Contains 'u8 ipad[statesize];', then 'u8 opad[statesize];' */ | |
32 | u8 pads[]; | |
33 | }; | |
34 | ||
8bd1209c | 35 | static int hmac_setkey(struct crypto_shash *parent, |
0796ae06 HX |
36 | const u8 *inkey, unsigned int keylen) |
37 | { | |
8bd1209c HX |
38 | int bs = crypto_shash_blocksize(parent); |
39 | int ds = crypto_shash_digestsize(parent); | |
0b767b4d | 40 | int ss = crypto_shash_statesize(parent); |
25c74a39 EB |
41 | struct hmac_ctx *tctx = crypto_shash_ctx(parent); |
42 | struct crypto_shash *hash = tctx->hash; | |
43 | u8 *ipad = &tctx->pads[0]; | |
44 | u8 *opad = &tctx->pads[ss]; | |
ffb32e97 | 45 | SHASH_DESC_ON_STACK(shash, hash); |
a05a8bc5 | 46 | int err, i; |
0796ae06 | 47 | |
37f36e57 SM |
48 | if (fips_enabled && (keylen < 112 / 8)) |
49 | return -EINVAL; | |
50 | ||
ffb32e97 | 51 | shash->tfm = hash; |
0b767b4d | 52 | |
0796ae06 | 53 | if (keylen > bs) { |
0796ae06 HX |
54 | int err; |
55 | ||
ffb32e97 | 56 | err = crypto_shash_digest(shash, inkey, keylen, ipad); |
0796ae06 HX |
57 | if (err) |
58 | return err; | |
59 | ||
0796ae06 | 60 | keylen = ds; |
0b767b4d HX |
61 | } else |
62 | memcpy(ipad, inkey, keylen); | |
0796ae06 | 63 | |
0796ae06 HX |
64 | memset(ipad + keylen, 0, bs - keylen); |
65 | memcpy(opad, ipad, bs); | |
66 | ||
67 | for (i = 0; i < bs; i++) { | |
03d7db56 CL |
68 | ipad[i] ^= HMAC_IPAD_VALUE; |
69 | opad[i] ^= HMAC_OPAD_VALUE; | |
0796ae06 HX |
70 | } |
71 | ||
a05a8bc5 HX |
72 | err = crypto_shash_init(shash) ?: |
73 | crypto_shash_update(shash, ipad, bs) ?: | |
74 | crypto_shash_export(shash, ipad) ?: | |
75 | crypto_shash_init(shash) ?: | |
76 | crypto_shash_update(shash, opad, bs) ?: | |
77 | crypto_shash_export(shash, opad); | |
78 | shash_desc_zero(shash); | |
79 | return err; | |
0796ae06 HX |
80 | } |
81 | ||
0b767b4d HX |
82 | static int hmac_export(struct shash_desc *pdesc, void *out) |
83 | { | |
84 | struct shash_desc *desc = shash_desc_ctx(pdesc); | |
85 | ||
0b767b4d HX |
86 | return crypto_shash_export(desc, out); |
87 | } | |
88 | ||
89 | static int hmac_import(struct shash_desc *pdesc, const void *in) | |
0796ae06 | 90 | { |
8bd1209c | 91 | struct shash_desc *desc = shash_desc_ctx(pdesc); |
25c74a39 | 92 | const struct hmac_ctx *tctx = crypto_shash_ctx(pdesc->tfm); |
8bd1209c | 93 | |
25c74a39 | 94 | desc->tfm = tctx->hash; |
8bd1209c | 95 | |
0b767b4d HX |
96 | return crypto_shash_import(desc, in); |
97 | } | |
98 | ||
8cf4c341 HX |
99 | static int hmac_export_core(struct shash_desc *pdesc, void *out) |
100 | { | |
101 | struct shash_desc *desc = shash_desc_ctx(pdesc); | |
102 | ||
103 | return crypto_shash_export_core(desc, out); | |
104 | } | |
105 | ||
106 | static int hmac_import_core(struct shash_desc *pdesc, const void *in) | |
107 | { | |
108 | const struct hmac_ctx *tctx = crypto_shash_ctx(pdesc->tfm); | |
109 | struct shash_desc *desc = shash_desc_ctx(pdesc); | |
110 | ||
111 | desc->tfm = tctx->hash; | |
112 | return crypto_shash_import_core(desc, in); | |
113 | } | |
114 | ||
0b767b4d HX |
115 | static int hmac_init(struct shash_desc *pdesc) |
116 | { | |
25c74a39 EB |
117 | const struct hmac_ctx *tctx = crypto_shash_ctx(pdesc->tfm); |
118 | ||
119 | return hmac_import(pdesc, &tctx->pads[0]); | |
0796ae06 HX |
120 | } |
121 | ||
8bd1209c HX |
122 | static int hmac_update(struct shash_desc *pdesc, |
123 | const u8 *data, unsigned int nbytes) | |
0796ae06 | 124 | { |
8bd1209c | 125 | struct shash_desc *desc = shash_desc_ctx(pdesc); |
0796ae06 | 126 | |
8bd1209c | 127 | return crypto_shash_update(desc, data, nbytes); |
0796ae06 HX |
128 | } |
129 | ||
8bd1209c HX |
130 | static int hmac_finup(struct shash_desc *pdesc, const u8 *data, |
131 | unsigned int nbytes, u8 *out) | |
0796ae06 | 132 | { |
0796ae06 | 133 | |
8bd1209c | 134 | struct crypto_shash *parent = pdesc->tfm; |
8bd1209c | 135 | int ds = crypto_shash_digestsize(parent); |
0b767b4d | 136 | int ss = crypto_shash_statesize(parent); |
25c74a39 EB |
137 | const struct hmac_ctx *tctx = crypto_shash_ctx(parent); |
138 | const u8 *opad = &tctx->pads[ss]; | |
8bd1209c | 139 | struct shash_desc *desc = shash_desc_ctx(pdesc); |
78c2f0b8 | 140 | |
0b767b4d HX |
141 | return crypto_shash_finup(desc, data, nbytes, out) ?: |
142 | crypto_shash_import(desc, opad) ?: | |
143 | crypto_shash_finup(desc, out, ds, out); | |
0796ae06 HX |
144 | } |
145 | ||
d9e1670b | 146 | static int hmac_init_tfm(struct crypto_shash *parent) |
0796ae06 | 147 | { |
8bd1209c | 148 | struct crypto_shash *hash; |
d9e1670b HX |
149 | struct shash_instance *inst = shash_alg_instance(parent); |
150 | struct crypto_shash_spawn *spawn = shash_instance_ctx(inst); | |
25c74a39 | 151 | struct hmac_ctx *tctx = crypto_shash_ctx(parent); |
0796ae06 | 152 | |
8bd1209c | 153 | hash = crypto_spawn_shash(spawn); |
2e306ee0 HX |
154 | if (IS_ERR(hash)) |
155 | return PTR_ERR(hash); | |
0796ae06 | 156 | |
25c74a39 | 157 | tctx->hash = hash; |
0796ae06 HX |
158 | return 0; |
159 | } | |
160 | ||
8538e60d HX |
161 | static int hmac_clone_tfm(struct crypto_shash *dst, struct crypto_shash *src) |
162 | { | |
25c74a39 EB |
163 | struct hmac_ctx *sctx = crypto_shash_ctx(src); |
164 | struct hmac_ctx *dctx = crypto_shash_ctx(dst); | |
8538e60d HX |
165 | struct crypto_shash *hash; |
166 | ||
167 | hash = crypto_clone_shash(sctx->hash); | |
168 | if (IS_ERR(hash)) | |
169 | return PTR_ERR(hash); | |
170 | ||
171 | dctx->hash = hash; | |
172 | return 0; | |
173 | } | |
174 | ||
d9e1670b | 175 | static void hmac_exit_tfm(struct crypto_shash *parent) |
0796ae06 | 176 | { |
25c74a39 | 177 | struct hmac_ctx *tctx = crypto_shash_ctx(parent); |
f75bd28b | 178 | |
25c74a39 | 179 | crypto_free_shash(tctx->hash); |
0796ae06 HX |
180 | } |
181 | ||
c3103416 HX |
182 | static int __hmac_create_shash(struct crypto_template *tmpl, |
183 | struct rtattr **tb, u32 mask) | |
0796ae06 | 184 | { |
8bd1209c | 185 | struct shash_instance *inst; |
39e7a283 | 186 | struct crypto_shash_spawn *spawn; |
0796ae06 | 187 | struct crypto_alg *alg; |
8bd1209c | 188 | struct shash_alg *salg; |
ebc610e5 | 189 | int err; |
ca786dc7 | 190 | int ds; |
0b767b4d | 191 | int ss; |
ebc610e5 | 192 | |
39e7a283 EB |
193 | inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); |
194 | if (!inst) | |
195 | return -ENOMEM; | |
196 | spawn = shash_instance_ctx(inst); | |
197 | ||
8cf4c341 | 198 | mask |= CRYPTO_AHASH_ALG_NO_EXPORT_CORE; |
39e7a283 | 199 | err = crypto_grab_shash(spawn, shash_crypto_instance(inst), |
7bcb2c99 | 200 | crypto_attr_alg_name(tb[1]), 0, mask); |
39e7a283 EB |
201 | if (err) |
202 | goto err_free_inst; | |
203 | salg = crypto_spawn_shash_alg(spawn); | |
af3ff804 | 204 | alg = &salg->base; |
8bd1209c | 205 | |
c2881789 | 206 | /* The underlying hash algorithm must not require a key */ |
8bd1209c | 207 | err = -EINVAL; |
c2881789 | 208 | if (crypto_shash_alg_needs_key(salg)) |
39e7a283 | 209 | goto err_free_inst; |
af3ff804 | 210 | |
8bd1209c | 211 | ds = salg->digestsize; |
0b767b4d | 212 | ss = salg->statesize; |
0b767b4d HX |
213 | if (ds > alg->cra_blocksize || |
214 | ss < alg->cra_blocksize) | |
39e7a283 | 215 | goto err_free_inst; |
ca786dc7 | 216 | |
c3103416 HX |
217 | err = crypto_inst_setname(shash_crypto_instance(inst), "hmac", |
218 | "hmac-shash", alg); | |
8bd1209c | 219 | if (err) |
39e7a283 | 220 | goto err_free_inst; |
8bd1209c HX |
221 | |
222 | inst->alg.base.cra_priority = alg->cra_priority; | |
223 | inst->alg.base.cra_blocksize = alg->cra_blocksize; | |
25c74a39 | 224 | inst->alg.base.cra_ctxsize = sizeof(struct hmac_ctx) + (ss * 2); |
0796ae06 | 225 | |
8bd1209c | 226 | inst->alg.digestsize = ds; |
0b767b4d | 227 | inst->alg.statesize = ss; |
aeffd909 | 228 | inst->alg.descsize = sizeof(struct shash_desc) + salg->descsize; |
8bd1209c HX |
229 | inst->alg.init = hmac_init; |
230 | inst->alg.update = hmac_update; | |
8bd1209c | 231 | inst->alg.finup = hmac_finup; |
0b767b4d HX |
232 | inst->alg.export = hmac_export; |
233 | inst->alg.import = hmac_import; | |
8cf4c341 HX |
234 | inst->alg.export_core = hmac_export_core; |
235 | inst->alg.import_core = hmac_import_core; | |
8bd1209c | 236 | inst->alg.setkey = hmac_setkey; |
d9e1670b | 237 | inst->alg.init_tfm = hmac_init_tfm; |
8538e60d | 238 | inst->alg.clone_tfm = hmac_clone_tfm; |
d9e1670b | 239 | inst->alg.exit_tfm = hmac_exit_tfm; |
8bd1209c | 240 | |
a39c66cc EB |
241 | inst->free = shash_free_singlespawn_instance; |
242 | ||
8bd1209c HX |
243 | err = shash_register_instance(tmpl, inst); |
244 | if (err) { | |
39e7a283 | 245 | err_free_inst: |
a39c66cc | 246 | shash_free_singlespawn_instance(inst); |
8bd1209c | 247 | } |
8bd1209c | 248 | return err; |
0796ae06 HX |
249 | } |
250 | ||
c3103416 HX |
251 | static int hmac_setkey_ahash(struct crypto_ahash *parent, |
252 | const u8 *inkey, unsigned int keylen) | |
253 | { | |
254 | struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(parent); | |
255 | struct crypto_ahash *fb = crypto_ahash_fb(tctx->hash); | |
256 | int ds = crypto_ahash_digestsize(parent); | |
257 | int bs = crypto_ahash_blocksize(parent); | |
258 | int ss = crypto_ahash_statesize(parent); | |
259 | HASH_REQUEST_ON_STACK(req, fb); | |
260 | u8 *opad = &tctx->pads[ss]; | |
261 | u8 *ipad = &tctx->pads[0]; | |
262 | int err, i; | |
263 | ||
264 | if (fips_enabled && (keylen < 112 / 8)) | |
265 | return -EINVAL; | |
266 | ||
267 | ahash_request_set_callback(req, 0, NULL, NULL); | |
268 | ||
269 | if (keylen > bs) { | |
270 | ahash_request_set_virt(req, inkey, ipad, keylen); | |
271 | err = crypto_ahash_digest(req); | |
272 | if (err) | |
273 | goto out_zero_req; | |
274 | ||
275 | keylen = ds; | |
276 | } else | |
277 | memcpy(ipad, inkey, keylen); | |
278 | ||
279 | memset(ipad + keylen, 0, bs - keylen); | |
280 | memcpy(opad, ipad, bs); | |
281 | ||
282 | for (i = 0; i < bs; i++) { | |
283 | ipad[i] ^= HMAC_IPAD_VALUE; | |
284 | opad[i] ^= HMAC_OPAD_VALUE; | |
285 | } | |
286 | ||
287 | ahash_request_set_virt(req, ipad, NULL, bs); | |
288 | err = crypto_ahash_init(req) ?: | |
289 | crypto_ahash_update(req) ?: | |
290 | crypto_ahash_export(req, ipad); | |
291 | ||
292 | ahash_request_set_virt(req, opad, NULL, bs); | |
293 | err = err ?: | |
294 | crypto_ahash_init(req) ?: | |
295 | crypto_ahash_update(req) ?: | |
296 | crypto_ahash_export(req, opad); | |
297 | ||
298 | out_zero_req: | |
299 | HASH_REQUEST_ZERO(req); | |
300 | return err; | |
301 | } | |
302 | ||
303 | static int hmac_export_ahash(struct ahash_request *preq, void *out) | |
304 | { | |
305 | return crypto_ahash_export(ahash_request_ctx(preq), out); | |
306 | } | |
307 | ||
308 | static int hmac_import_ahash(struct ahash_request *preq, const void *in) | |
309 | { | |
310 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); | |
311 | struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); | |
312 | struct ahash_request *req = ahash_request_ctx(preq); | |
313 | ||
314 | ahash_request_set_tfm(req, tctx->hash); | |
315 | return crypto_ahash_import(req, in); | |
316 | } | |
317 | ||
318 | static int hmac_export_core_ahash(struct ahash_request *preq, void *out) | |
319 | { | |
320 | return crypto_ahash_export_core(ahash_request_ctx(preq), out); | |
321 | } | |
322 | ||
323 | static int hmac_import_core_ahash(struct ahash_request *preq, const void *in) | |
324 | { | |
325 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); | |
326 | struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); | |
327 | struct ahash_request *req = ahash_request_ctx(preq); | |
328 | ||
329 | ahash_request_set_tfm(req, tctx->hash); | |
330 | return crypto_ahash_import_core(req, in); | |
331 | } | |
332 | ||
333 | static int hmac_init_ahash(struct ahash_request *preq) | |
334 | { | |
335 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); | |
336 | struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); | |
337 | ||
338 | return hmac_import_ahash(preq, &tctx->pads[0]); | |
339 | } | |
340 | ||
341 | static int hmac_update_ahash(struct ahash_request *preq) | |
342 | { | |
343 | struct ahash_request *req = ahash_request_ctx(preq); | |
344 | ||
345 | ahash_request_set_callback(req, ahash_request_flags(preq), | |
346 | preq->base.complete, preq->base.data); | |
347 | if (ahash_request_isvirt(preq)) | |
348 | ahash_request_set_virt(req, preq->svirt, NULL, preq->nbytes); | |
349 | else | |
350 | ahash_request_set_crypt(req, preq->src, NULL, preq->nbytes); | |
351 | return crypto_ahash_update(req); | |
352 | } | |
353 | ||
354 | static int hmac_finup_finish(struct ahash_request *preq, unsigned int mask) | |
355 | { | |
356 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); | |
357 | struct ahash_request *req = ahash_request_ctx(preq); | |
358 | struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); | |
359 | int ds = crypto_ahash_digestsize(tfm); | |
360 | int ss = crypto_ahash_statesize(tfm); | |
361 | const u8 *opad = &tctx->pads[ss]; | |
362 | ||
363 | ahash_request_set_callback(req, ahash_request_flags(preq) & ~mask, | |
364 | preq->base.complete, preq->base.data); | |
365 | ahash_request_set_virt(req, preq->result, preq->result, ds); | |
366 | return crypto_ahash_import(req, opad) ?: | |
367 | crypto_ahash_finup(req); | |
368 | ||
369 | } | |
370 | ||
371 | static void hmac_finup_done(void *data, int err) | |
372 | { | |
373 | struct ahash_request *preq = data; | |
374 | ||
375 | if (err) | |
376 | goto out; | |
377 | ||
378 | err = hmac_finup_finish(preq, CRYPTO_TFM_REQ_MAY_SLEEP); | |
379 | if (err == -EINPROGRESS || err == -EBUSY) | |
380 | return; | |
381 | ||
382 | out: | |
383 | ahash_request_complete(preq, err); | |
384 | } | |
385 | ||
386 | static int hmac_finup_ahash(struct ahash_request *preq) | |
387 | { | |
388 | struct ahash_request *req = ahash_request_ctx(preq); | |
389 | ||
390 | ahash_request_set_callback(req, ahash_request_flags(preq), | |
391 | hmac_finup_done, preq); | |
392 | if (ahash_request_isvirt(preq)) | |
393 | ahash_request_set_virt(req, preq->svirt, preq->result, | |
394 | preq->nbytes); | |
395 | else | |
396 | ahash_request_set_crypt(req, preq->src, preq->result, | |
397 | preq->nbytes); | |
398 | return crypto_ahash_finup(req) ?: | |
399 | hmac_finup_finish(preq, 0); | |
400 | } | |
401 | ||
402 | static int hmac_digest_ahash(struct ahash_request *preq) | |
403 | { | |
404 | return hmac_init_ahash(preq) ?: | |
405 | hmac_finup_ahash(preq); | |
406 | } | |
407 | ||
408 | static int hmac_init_ahash_tfm(struct crypto_ahash *parent) | |
409 | { | |
410 | struct ahash_instance *inst = ahash_alg_instance(parent); | |
411 | struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(parent); | |
412 | struct crypto_ahash *hash; | |
413 | ||
414 | hash = crypto_spawn_ahash(ahash_instance_ctx(inst)); | |
415 | if (IS_ERR(hash)) | |
416 | return PTR_ERR(hash); | |
417 | ||
418 | if (crypto_ahash_reqsize(parent) < sizeof(struct ahash_request) + | |
419 | crypto_ahash_reqsize(hash)) | |
420 | return -EINVAL; | |
421 | ||
422 | tctx->hash = hash; | |
423 | return 0; | |
424 | } | |
425 | ||
426 | static int hmac_clone_ahash_tfm(struct crypto_ahash *dst, | |
427 | struct crypto_ahash *src) | |
428 | { | |
429 | struct ahash_hmac_ctx *sctx = crypto_ahash_ctx(src); | |
430 | struct ahash_hmac_ctx *dctx = crypto_ahash_ctx(dst); | |
431 | struct crypto_ahash *hash; | |
432 | ||
433 | hash = crypto_clone_ahash(sctx->hash); | |
434 | if (IS_ERR(hash)) | |
435 | return PTR_ERR(hash); | |
436 | ||
437 | dctx->hash = hash; | |
438 | return 0; | |
439 | } | |
440 | ||
441 | static void hmac_exit_ahash_tfm(struct crypto_ahash *parent) | |
442 | { | |
443 | struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(parent); | |
444 | ||
445 | crypto_free_ahash(tctx->hash); | |
446 | } | |
447 | ||
448 | static int hmac_create_ahash(struct crypto_template *tmpl, struct rtattr **tb, | |
449 | u32 mask) | |
450 | { | |
451 | struct crypto_ahash_spawn *spawn; | |
452 | struct ahash_instance *inst; | |
453 | struct crypto_alg *alg; | |
454 | struct hash_alg_common *halg; | |
455 | int ds, ss, err; | |
456 | ||
457 | inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); | |
458 | if (!inst) | |
459 | return -ENOMEM; | |
460 | spawn = ahash_instance_ctx(inst); | |
461 | ||
462 | mask |= CRYPTO_AHASH_ALG_NO_EXPORT_CORE; | |
463 | err = crypto_grab_ahash(spawn, ahash_crypto_instance(inst), | |
464 | crypto_attr_alg_name(tb[1]), 0, mask); | |
465 | if (err) | |
466 | goto err_free_inst; | |
467 | halg = crypto_spawn_ahash_alg(spawn); | |
468 | alg = &halg->base; | |
469 | ||
470 | /* The underlying hash algorithm must not require a key */ | |
471 | err = -EINVAL; | |
472 | if (crypto_hash_alg_needs_key(halg)) | |
473 | goto err_free_inst; | |
474 | ||
475 | ds = halg->digestsize; | |
476 | ss = halg->statesize; | |
477 | if (ds > alg->cra_blocksize || ss < alg->cra_blocksize) | |
478 | goto err_free_inst; | |
479 | ||
480 | err = crypto_inst_setname(ahash_crypto_instance(inst), tmpl->name, alg); | |
481 | if (err) | |
482 | goto err_free_inst; | |
483 | ||
484 | inst->alg.halg.base.cra_flags = alg->cra_flags & | |
485 | CRYPTO_ALG_INHERITED_FLAGS; | |
486 | inst->alg.halg.base.cra_flags |= CRYPTO_ALG_REQ_VIRT; | |
487 | inst->alg.halg.base.cra_priority = alg->cra_priority + 100; | |
488 | inst->alg.halg.base.cra_blocksize = alg->cra_blocksize; | |
489 | inst->alg.halg.base.cra_ctxsize = sizeof(struct ahash_hmac_ctx) + | |
490 | (ss * 2); | |
491 | inst->alg.halg.base.cra_reqsize = sizeof(struct ahash_request) + | |
492 | alg->cra_reqsize; | |
493 | ||
494 | inst->alg.halg.digestsize = ds; | |
495 | inst->alg.halg.statesize = ss; | |
496 | inst->alg.init = hmac_init_ahash; | |
497 | inst->alg.update = hmac_update_ahash; | |
498 | inst->alg.finup = hmac_finup_ahash; | |
499 | inst->alg.digest = hmac_digest_ahash; | |
500 | inst->alg.export = hmac_export_ahash; | |
501 | inst->alg.import = hmac_import_ahash; | |
502 | inst->alg.export_core = hmac_export_core_ahash; | |
503 | inst->alg.import_core = hmac_import_core_ahash; | |
504 | inst->alg.setkey = hmac_setkey_ahash; | |
505 | inst->alg.init_tfm = hmac_init_ahash_tfm; | |
506 | inst->alg.clone_tfm = hmac_clone_ahash_tfm; | |
507 | inst->alg.exit_tfm = hmac_exit_ahash_tfm; | |
508 | ||
509 | inst->free = ahash_free_singlespawn_instance; | |
510 | ||
511 | err = ahash_register_instance(tmpl, inst); | |
512 | if (err) { | |
513 | err_free_inst: | |
514 | ahash_free_singlespawn_instance(inst); | |
515 | } | |
516 | return err; | |
517 | } | |
518 | ||
519 | static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) | |
520 | { | |
521 | struct crypto_attr_type *algt; | |
522 | u32 mask; | |
523 | ||
524 | algt = crypto_get_attr_type(tb); | |
525 | if (IS_ERR(algt)) | |
526 | return PTR_ERR(algt); | |
527 | ||
528 | mask = crypto_algt_inherited_mask(algt); | |
529 | ||
530 | if (!((algt->type ^ CRYPTO_ALG_TYPE_AHASH) & | |
531 | algt->mask & CRYPTO_ALG_TYPE_MASK)) | |
532 | return hmac_create_ahash(tmpl, tb, mask); | |
533 | ||
534 | if ((algt->type ^ CRYPTO_ALG_TYPE_SHASH) & | |
535 | algt->mask & CRYPTO_ALG_TYPE_MASK) | |
536 | return -EINVAL; | |
537 | ||
538 | return __hmac_create_shash(tmpl, tb, mask); | |
539 | } | |
540 | ||
541 | static int hmac_create_shash(struct crypto_template *tmpl, struct rtattr **tb) | |
542 | { | |
543 | u32 mask; | |
544 | int err; | |
545 | ||
546 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask); | |
547 | if (err) | |
548 | return err == -EINVAL ? -ENOENT : err; | |
549 | ||
550 | return __hmac_create_shash(tmpl, tb, mask); | |
551 | } | |
552 | ||
553 | static struct crypto_template hmac_tmpls[] = { | |
554 | { | |
555 | .name = "hmac", | |
556 | .create = hmac_create, | |
557 | .module = THIS_MODULE, | |
558 | }, | |
559 | { | |
560 | .name = "hmac-shash", | |
561 | .create = hmac_create_shash, | |
562 | .module = THIS_MODULE, | |
563 | }, | |
0796ae06 HX |
564 | }; |
565 | ||
566 | static int __init hmac_module_init(void) | |
567 | { | |
c3103416 | 568 | return crypto_register_templates(hmac_tmpls, ARRAY_SIZE(hmac_tmpls)); |
0796ae06 HX |
569 | } |
570 | ||
571 | static void __exit hmac_module_exit(void) | |
572 | { | |
c3103416 | 573 | crypto_unregister_templates(hmac_tmpls, ARRAY_SIZE(hmac_tmpls)); |
0796ae06 HX |
574 | } |
575 | ||
ef93f156 | 576 | module_init(hmac_module_init); |
0796ae06 HX |
577 | module_exit(hmac_module_exit); |
578 | ||
579 | MODULE_LICENSE("GPL"); | |
580 | MODULE_DESCRIPTION("HMAC hash algorithm"); | |
4943ba16 | 581 | MODULE_ALIAS_CRYPTO("hmac"); |