blob: a1c7609578eabcb16fd3d864772aecc59ea0d76c
1 | /* |
2 | * Synchronous Cryptographic Hash operations. |
3 | * |
4 | * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the Free |
8 | * Software Foundation; either version 2 of the License, or (at your option) |
9 | * any later version. |
10 | * |
11 | */ |
12 | |
13 | #include <crypto/scatterwalk.h> |
14 | #include <crypto/internal/hash.h> |
15 | #include <linux/err.h> |
16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> |
18 | #include <linux/slab.h> |
19 | #include <linux/seq_file.h> |
20 | #include <linux/cryptouser.h> |
21 | #include <net/netlink.h> |
22 | |
23 | #include "internal.h" |
24 | |
25 | static const struct crypto_type crypto_shash_type; |
26 | |
27 | int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, |
28 | unsigned int keylen) |
29 | { |
30 | return -ENOSYS; |
31 | } |
32 | EXPORT_SYMBOL_GPL(shash_no_setkey); |
33 | |
34 | static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, |
35 | unsigned int keylen) |
36 | { |
37 | struct shash_alg *shash = crypto_shash_alg(tfm); |
38 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
39 | unsigned long absize; |
40 | u8 *buffer, *alignbuffer; |
41 | int err; |
42 | |
43 | absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); |
44 | buffer = kmalloc(absize, GFP_ATOMIC); |
45 | if (!buffer) |
46 | return -ENOMEM; |
47 | |
48 | alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); |
49 | memcpy(alignbuffer, key, keylen); |
50 | err = shash->setkey(tfm, alignbuffer, keylen); |
51 | kzfree(buffer); |
52 | return err; |
53 | } |
54 | |
55 | static void shash_set_needkey(struct crypto_shash *tfm, struct shash_alg *alg) |
56 | { |
57 | if (crypto_shash_alg_has_setkey(alg) && |
58 | !(alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY)) |
59 | crypto_shash_set_flags(tfm, CRYPTO_TFM_NEED_KEY); |
60 | } |
61 | |
62 | int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key, |
63 | unsigned int keylen) |
64 | { |
65 | struct shash_alg *shash = crypto_shash_alg(tfm); |
66 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
67 | int err; |
68 | |
69 | if ((unsigned long)key & alignmask) |
70 | err = shash_setkey_unaligned(tfm, key, keylen); |
71 | else |
72 | err = shash->setkey(tfm, key, keylen); |
73 | |
74 | if (unlikely(err)) { |
75 | shash_set_needkey(tfm, shash); |
76 | return err; |
77 | } |
78 | |
79 | crypto_shash_clear_flags(tfm, CRYPTO_TFM_NEED_KEY); |
80 | return 0; |
81 | } |
82 | EXPORT_SYMBOL_GPL(crypto_shash_setkey); |
83 | |
84 | static inline unsigned int shash_align_buffer_size(unsigned len, |
85 | unsigned long mask) |
86 | { |
87 | typedef u8 __attribute__ ((aligned)) u8_aligned; |
88 | return len + (mask & ~(__alignof__(u8_aligned) - 1)); |
89 | } |
90 | |
91 | static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, |
92 | unsigned int len) |
93 | { |
94 | struct crypto_shash *tfm = desc->tfm; |
95 | struct shash_alg *shash = crypto_shash_alg(tfm); |
96 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
97 | unsigned int unaligned_len = alignmask + 1 - |
98 | ((unsigned long)data & alignmask); |
99 | u8 ubuf[shash_align_buffer_size(unaligned_len, alignmask)] |
100 | __attribute__ ((aligned)); |
101 | u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); |
102 | int err; |
103 | |
104 | if (unaligned_len > len) |
105 | unaligned_len = len; |
106 | |
107 | memcpy(buf, data, unaligned_len); |
108 | err = shash->update(desc, buf, unaligned_len); |
109 | memset(buf, 0, unaligned_len); |
110 | |
111 | return err ?: |
112 | shash->update(desc, data + unaligned_len, len - unaligned_len); |
113 | } |
114 | |
115 | int crypto_shash_update(struct shash_desc *desc, const u8 *data, |
116 | unsigned int len) |
117 | { |
118 | struct crypto_shash *tfm = desc->tfm; |
119 | struct shash_alg *shash = crypto_shash_alg(tfm); |
120 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
121 | |
122 | if ((unsigned long)data & alignmask) |
123 | return shash_update_unaligned(desc, data, len); |
124 | |
125 | return shash->update(desc, data, len); |
126 | } |
127 | EXPORT_SYMBOL_GPL(crypto_shash_update); |
128 | |
129 | static int shash_final_unaligned(struct shash_desc *desc, u8 *out) |
130 | { |
131 | struct crypto_shash *tfm = desc->tfm; |
132 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
133 | struct shash_alg *shash = crypto_shash_alg(tfm); |
134 | unsigned int ds = crypto_shash_digestsize(tfm); |
135 | u8 ubuf[shash_align_buffer_size(ds, alignmask)] |
136 | __attribute__ ((aligned)); |
137 | u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); |
138 | int err; |
139 | |
140 | err = shash->final(desc, buf); |
141 | if (err) |
142 | goto out; |
143 | |
144 | memcpy(out, buf, ds); |
145 | |
146 | out: |
147 | memset(buf, 0, ds); |
148 | return err; |
149 | } |
150 | |
151 | int crypto_shash_final(struct shash_desc *desc, u8 *out) |
152 | { |
153 | struct crypto_shash *tfm = desc->tfm; |
154 | struct shash_alg *shash = crypto_shash_alg(tfm); |
155 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
156 | |
157 | if ((unsigned long)out & alignmask) |
158 | return shash_final_unaligned(desc, out); |
159 | |
160 | return shash->final(desc, out); |
161 | } |
162 | EXPORT_SYMBOL_GPL(crypto_shash_final); |
163 | |
164 | static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data, |
165 | unsigned int len, u8 *out) |
166 | { |
167 | return crypto_shash_update(desc, data, len) ?: |
168 | crypto_shash_final(desc, out); |
169 | } |
170 | |
171 | int crypto_shash_finup(struct shash_desc *desc, const u8 *data, |
172 | unsigned int len, u8 *out) |
173 | { |
174 | struct crypto_shash *tfm = desc->tfm; |
175 | struct shash_alg *shash = crypto_shash_alg(tfm); |
176 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
177 | |
178 | if (((unsigned long)data | (unsigned long)out) & alignmask) |
179 | return shash_finup_unaligned(desc, data, len, out); |
180 | |
181 | return shash->finup(desc, data, len, out); |
182 | } |
183 | EXPORT_SYMBOL_GPL(crypto_shash_finup); |
184 | |
185 | static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data, |
186 | unsigned int len, u8 *out) |
187 | { |
188 | return crypto_shash_init(desc) ?: |
189 | crypto_shash_finup(desc, data, len, out); |
190 | } |
191 | |
192 | int crypto_shash_digest(struct shash_desc *desc, const u8 *data, |
193 | unsigned int len, u8 *out) |
194 | { |
195 | struct crypto_shash *tfm = desc->tfm; |
196 | struct shash_alg *shash = crypto_shash_alg(tfm); |
197 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
198 | |
199 | if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) |
200 | return -ENOKEY; |
201 | |
202 | if (((unsigned long)data | (unsigned long)out) & alignmask) |
203 | return shash_digest_unaligned(desc, data, len, out); |
204 | |
205 | return shash->digest(desc, data, len, out); |
206 | } |
207 | EXPORT_SYMBOL_GPL(crypto_shash_digest); |
208 | |
209 | static int shash_default_export(struct shash_desc *desc, void *out) |
210 | { |
211 | memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm)); |
212 | return 0; |
213 | } |
214 | |
215 | static int shash_default_import(struct shash_desc *desc, const void *in) |
216 | { |
217 | memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(desc->tfm)); |
218 | return 0; |
219 | } |
220 | |
221 | static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key, |
222 | unsigned int keylen) |
223 | { |
224 | struct crypto_shash **ctx = crypto_ahash_ctx(tfm); |
225 | |
226 | return crypto_shash_setkey(*ctx, key, keylen); |
227 | } |
228 | |
229 | static int shash_async_init(struct ahash_request *req) |
230 | { |
231 | struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); |
232 | struct shash_desc *desc = ahash_request_ctx(req); |
233 | |
234 | desc->tfm = *ctx; |
235 | desc->flags = req->base.flags; |
236 | |
237 | return crypto_shash_init(desc); |
238 | } |
239 | |
240 | int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc) |
241 | { |
242 | struct crypto_hash_walk walk; |
243 | int nbytes; |
244 | |
245 | for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0; |
246 | nbytes = crypto_hash_walk_done(&walk, nbytes)) |
247 | nbytes = crypto_shash_update(desc, walk.data, nbytes); |
248 | |
249 | return nbytes; |
250 | } |
251 | EXPORT_SYMBOL_GPL(shash_ahash_update); |
252 | |
253 | static int shash_async_update(struct ahash_request *req) |
254 | { |
255 | return shash_ahash_update(req, ahash_request_ctx(req)); |
256 | } |
257 | |
258 | static int shash_async_final(struct ahash_request *req) |
259 | { |
260 | return crypto_shash_final(ahash_request_ctx(req), req->result); |
261 | } |
262 | |
263 | int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc) |
264 | { |
265 | struct crypto_hash_walk walk; |
266 | int nbytes; |
267 | |
268 | nbytes = crypto_hash_walk_first(req, &walk); |
269 | if (!nbytes) |
270 | return crypto_shash_final(desc, req->result); |
271 | |
272 | do { |
273 | nbytes = crypto_hash_walk_last(&walk) ? |
274 | crypto_shash_finup(desc, walk.data, nbytes, |
275 | req->result) : |
276 | crypto_shash_update(desc, walk.data, nbytes); |
277 | nbytes = crypto_hash_walk_done(&walk, nbytes); |
278 | } while (nbytes > 0); |
279 | |
280 | return nbytes; |
281 | } |
282 | EXPORT_SYMBOL_GPL(shash_ahash_finup); |
283 | |
284 | static int shash_async_finup(struct ahash_request *req) |
285 | { |
286 | struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); |
287 | struct shash_desc *desc = ahash_request_ctx(req); |
288 | |
289 | desc->tfm = *ctx; |
290 | desc->flags = req->base.flags; |
291 | |
292 | return shash_ahash_finup(req, desc); |
293 | } |
294 | |
295 | int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) |
296 | { |
297 | unsigned int nbytes = req->nbytes; |
298 | struct scatterlist *sg; |
299 | unsigned int offset; |
300 | int err; |
301 | |
302 | if (nbytes && |
303 | (sg = req->src, offset = sg->offset, |
304 | nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) { |
305 | void *data; |
306 | |
307 | data = kmap_atomic(sg_page(sg)); |
308 | err = crypto_shash_digest(desc, data + offset, nbytes, |
309 | req->result); |
310 | kunmap_atomic(data); |
311 | crypto_yield(desc->flags); |
312 | } else |
313 | err = crypto_shash_init(desc) ?: |
314 | shash_ahash_finup(req, desc); |
315 | |
316 | return err; |
317 | } |
318 | EXPORT_SYMBOL_GPL(shash_ahash_digest); |
319 | |
320 | static int shash_async_digest(struct ahash_request *req) |
321 | { |
322 | struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); |
323 | struct shash_desc *desc = ahash_request_ctx(req); |
324 | |
325 | desc->tfm = *ctx; |
326 | desc->flags = req->base.flags; |
327 | |
328 | return shash_ahash_digest(req, desc); |
329 | } |
330 | |
331 | static int shash_async_export(struct ahash_request *req, void *out) |
332 | { |
333 | return crypto_shash_export(ahash_request_ctx(req), out); |
334 | } |
335 | |
336 | static int shash_async_import(struct ahash_request *req, const void *in) |
337 | { |
338 | struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); |
339 | struct shash_desc *desc = ahash_request_ctx(req); |
340 | |
341 | desc->tfm = *ctx; |
342 | desc->flags = req->base.flags; |
343 | |
344 | return crypto_shash_import(desc, in); |
345 | } |
346 | |
347 | static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) |
348 | { |
349 | struct crypto_shash **ctx = crypto_tfm_ctx(tfm); |
350 | |
351 | crypto_free_shash(*ctx); |
352 | } |
353 | |
354 | int crypto_init_shash_ops_async(struct crypto_tfm *tfm) |
355 | { |
356 | struct crypto_alg *calg = tfm->__crt_alg; |
357 | struct shash_alg *alg = __crypto_shash_alg(calg); |
358 | struct crypto_ahash *crt = __crypto_ahash_cast(tfm); |
359 | struct crypto_shash **ctx = crypto_tfm_ctx(tfm); |
360 | struct crypto_shash *shash; |
361 | |
362 | if (!crypto_mod_get(calg)) |
363 | return -EAGAIN; |
364 | |
365 | shash = crypto_create_tfm(calg, &crypto_shash_type); |
366 | if (IS_ERR(shash)) { |
367 | crypto_mod_put(calg); |
368 | return PTR_ERR(shash); |
369 | } |
370 | |
371 | *ctx = shash; |
372 | tfm->exit = crypto_exit_shash_ops_async; |
373 | |
374 | crt->init = shash_async_init; |
375 | crt->update = shash_async_update; |
376 | crt->final = shash_async_final; |
377 | crt->finup = shash_async_finup; |
378 | crt->digest = shash_async_digest; |
379 | if (crypto_shash_alg_has_setkey(alg)) |
380 | crt->setkey = shash_async_setkey; |
381 | |
382 | crypto_ahash_set_flags(crt, crypto_shash_get_flags(shash) & |
383 | CRYPTO_TFM_NEED_KEY); |
384 | |
385 | if (alg->export) |
386 | crt->export = shash_async_export; |
387 | if (alg->import) |
388 | crt->import = shash_async_import; |
389 | |
390 | crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash); |
391 | |
392 | return 0; |
393 | } |
394 | |
395 | static int crypto_shash_init_tfm(struct crypto_tfm *tfm) |
396 | { |
397 | struct crypto_shash *hash = __crypto_shash_cast(tfm); |
398 | struct shash_alg *alg = crypto_shash_alg(hash); |
399 | |
400 | hash->descsize = alg->descsize; |
401 | |
402 | shash_set_needkey(hash, alg); |
403 | |
404 | return 0; |
405 | } |
406 | |
407 | #ifdef CONFIG_NET |
408 | static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) |
409 | { |
410 | struct crypto_report_hash rhash; |
411 | struct shash_alg *salg = __crypto_shash_alg(alg); |
412 | |
413 | strncpy(rhash.type, "shash", sizeof(rhash.type)); |
414 | |
415 | rhash.blocksize = alg->cra_blocksize; |
416 | rhash.digestsize = salg->digestsize; |
417 | |
418 | if (nla_put(skb, CRYPTOCFGA_REPORT_HASH, |
419 | sizeof(struct crypto_report_hash), &rhash)) |
420 | goto nla_put_failure; |
421 | return 0; |
422 | |
423 | nla_put_failure: |
424 | return -EMSGSIZE; |
425 | } |
426 | #else |
427 | static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) |
428 | { |
429 | return -ENOSYS; |
430 | } |
431 | #endif |
432 | |
433 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) |
434 | __attribute__ ((unused)); |
435 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) |
436 | { |
437 | struct shash_alg *salg = __crypto_shash_alg(alg); |
438 | |
439 | seq_printf(m, "type : shash\n"); |
440 | seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); |
441 | seq_printf(m, "digestsize : %u\n", salg->digestsize); |
442 | } |
443 | |
444 | static const struct crypto_type crypto_shash_type = { |
445 | .extsize = crypto_alg_extsize, |
446 | .init_tfm = crypto_shash_init_tfm, |
447 | #ifdef CONFIG_PROC_FS |
448 | .show = crypto_shash_show, |
449 | #endif |
450 | .report = crypto_shash_report, |
451 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, |
452 | .maskset = CRYPTO_ALG_TYPE_MASK, |
453 | .type = CRYPTO_ALG_TYPE_SHASH, |
454 | .tfmsize = offsetof(struct crypto_shash, base), |
455 | }; |
456 | |
457 | struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, |
458 | u32 mask) |
459 | { |
460 | return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask); |
461 | } |
462 | EXPORT_SYMBOL_GPL(crypto_alloc_shash); |
463 | |
464 | static int shash_prepare_alg(struct shash_alg *alg) |
465 | { |
466 | struct crypto_alg *base = &alg->base; |
467 | |
468 | if (alg->digestsize > PAGE_SIZE / 8 || |
469 | alg->descsize > PAGE_SIZE / 8 || |
470 | alg->statesize > PAGE_SIZE / 8) |
471 | return -EINVAL; |
472 | |
473 | base->cra_type = &crypto_shash_type; |
474 | base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; |
475 | base->cra_flags |= CRYPTO_ALG_TYPE_SHASH; |
476 | |
477 | if (!alg->finup) |
478 | alg->finup = shash_finup_unaligned; |
479 | if (!alg->digest) |
480 | alg->digest = shash_digest_unaligned; |
481 | if (!alg->export) { |
482 | alg->export = shash_default_export; |
483 | alg->import = shash_default_import; |
484 | alg->statesize = alg->descsize; |
485 | } |
486 | if (!alg->setkey) |
487 | alg->setkey = shash_no_setkey; |
488 | |
489 | return 0; |
490 | } |
491 | |
492 | int crypto_register_shash(struct shash_alg *alg) |
493 | { |
494 | struct crypto_alg *base = &alg->base; |
495 | int err; |
496 | |
497 | err = shash_prepare_alg(alg); |
498 | if (err) |
499 | return err; |
500 | |
501 | return crypto_register_alg(base); |
502 | } |
503 | EXPORT_SYMBOL_GPL(crypto_register_shash); |
504 | |
505 | int crypto_unregister_shash(struct shash_alg *alg) |
506 | { |
507 | return crypto_unregister_alg(&alg->base); |
508 | } |
509 | EXPORT_SYMBOL_GPL(crypto_unregister_shash); |
510 | |
511 | int crypto_register_shashes(struct shash_alg *algs, int count) |
512 | { |
513 | int i, ret; |
514 | |
515 | for (i = 0; i < count; i++) { |
516 | ret = crypto_register_shash(&algs[i]); |
517 | if (ret) |
518 | goto err; |
519 | } |
520 | |
521 | return 0; |
522 | |
523 | err: |
524 | for (--i; i >= 0; --i) |
525 | crypto_unregister_shash(&algs[i]); |
526 | |
527 | return ret; |
528 | } |
529 | EXPORT_SYMBOL_GPL(crypto_register_shashes); |
530 | |
531 | int crypto_unregister_shashes(struct shash_alg *algs, int count) |
532 | { |
533 | int i, ret; |
534 | |
535 | for (i = count - 1; i >= 0; --i) { |
536 | ret = crypto_unregister_shash(&algs[i]); |
537 | if (ret) |
538 | pr_err("Failed to unregister %s %s: %d\n", |
539 | algs[i].base.cra_driver_name, |
540 | algs[i].base.cra_name, ret); |
541 | } |
542 | |
543 | return 0; |
544 | } |
545 | EXPORT_SYMBOL_GPL(crypto_unregister_shashes); |
546 | |
547 | int shash_register_instance(struct crypto_template *tmpl, |
548 | struct shash_instance *inst) |
549 | { |
550 | int err; |
551 | |
552 | err = shash_prepare_alg(&inst->alg); |
553 | if (err) |
554 | return err; |
555 | |
556 | return crypto_register_instance(tmpl, shash_crypto_instance(inst)); |
557 | } |
558 | EXPORT_SYMBOL_GPL(shash_register_instance); |
559 | |
560 | void shash_free_instance(struct crypto_instance *inst) |
561 | { |
562 | crypto_drop_spawn(crypto_instance_ctx(inst)); |
563 | kfree(shash_instance(inst)); |
564 | } |
565 | EXPORT_SYMBOL_GPL(shash_free_instance); |
566 | |
567 | int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn, |
568 | struct shash_alg *alg, |
569 | struct crypto_instance *inst) |
570 | { |
571 | return crypto_init_spawn2(&spawn->base, &alg->base, inst, |
572 | &crypto_shash_type); |
573 | } |
574 | EXPORT_SYMBOL_GPL(crypto_init_shash_spawn); |
575 | |
576 | struct shash_alg *shash_attr_alg(struct rtattr *rta, u32 type, u32 mask) |
577 | { |
578 | struct crypto_alg *alg; |
579 | |
580 | alg = crypto_attr_alg2(rta, &crypto_shash_type, type, mask); |
581 | return IS_ERR(alg) ? ERR_CAST(alg) : |
582 | container_of(alg, struct shash_alg, base); |
583 | } |
584 | EXPORT_SYMBOL_GPL(shash_attr_alg); |
585 | |
586 | MODULE_LICENSE("GPL"); |
587 | MODULE_DESCRIPTION("Synchronous cryptographic hash type"); |
588 |