Branch data Line data Source code
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 : 0 : static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
28 : : unsigned int keylen)
29 : : {
30 : 0 : return -ENOSYS;
31 : : }
32 : :
33 : 0 : static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
34 : : unsigned int keylen)
35 : : {
36 : : struct shash_alg *shash = crypto_shash_alg(tfm);
37 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
38 : : unsigned long absize;
39 : : u8 *buffer, *alignbuffer;
40 : : int err;
41 : :
42 : 0 : absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
43 : : buffer = kmalloc(absize, GFP_KERNEL);
44 [ # # ]: 0 : if (!buffer)
45 : : return -ENOMEM;
46 : :
47 : 0 : alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
48 : 0 : memcpy(alignbuffer, key, keylen);
49 : 0 : err = shash->setkey(tfm, alignbuffer, keylen);
50 : 0 : kzfree(buffer);
51 : 0 : return err;
52 : : }
53 : :
54 : 0 : int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
55 : : unsigned int keylen)
56 : : {
57 : : struct shash_alg *shash = crypto_shash_alg(tfm);
58 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
59 : :
60 [ # # ]: 0 : if ((unsigned long)key & alignmask)
61 : 0 : return shash_setkey_unaligned(tfm, key, keylen);
62 : :
63 : 0 : return shash->setkey(tfm, key, keylen);
64 : : }
65 : : EXPORT_SYMBOL_GPL(crypto_shash_setkey);
66 : :
67 : : static inline unsigned int shash_align_buffer_size(unsigned len,
68 : : unsigned long mask)
69 : : {
70 : : typedef u8 __attribute__ ((aligned)) u8_aligned;
71 : 0 : return len + (mask & ~(__alignof__(u8_aligned) - 1));
72 : : }
73 : :
74 : 0 : static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
75 : : unsigned int len)
76 : : {
77 : 0 : struct crypto_shash *tfm = desc->tfm;
78 : : struct shash_alg *shash = crypto_shash_alg(tfm);
79 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
80 : 0 : unsigned int unaligned_len = alignmask + 1 -
81 : 0 : ((unsigned long)data & alignmask);
82 : 0 : u8 ubuf[shash_align_buffer_size(unaligned_len, alignmask)]
83 : : __attribute__ ((aligned));
84 : 0 : u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
85 : : int err;
86 : :
87 [ # # ]: 0 : if (unaligned_len > len)
88 : : unaligned_len = len;
89 : :
90 : 0 : memcpy(buf, data, unaligned_len);
91 : 0 : err = shash->update(desc, buf, unaligned_len);
92 [ # # ]: 0 : memset(buf, 0, unaligned_len);
93 : :
94 [ # # ]: 0 : return err ?:
95 : 0 : shash->update(desc, data + unaligned_len, len - unaligned_len);
96 : : }
97 : :
98 : 0 : int crypto_shash_update(struct shash_desc *desc, const u8 *data,
99 : : unsigned int len)
100 : : {
101 : 0 : struct crypto_shash *tfm = desc->tfm;
102 : : struct shash_alg *shash = crypto_shash_alg(tfm);
103 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
104 : :
105 [ # # ]: 0 : if ((unsigned long)data & alignmask)
106 : 0 : return shash_update_unaligned(desc, data, len);
107 : :
108 : 0 : return shash->update(desc, data, len);
109 : : }
110 : : EXPORT_SYMBOL_GPL(crypto_shash_update);
111 : :
112 : 0 : static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
113 : : {
114 : 0 : struct crypto_shash *tfm = desc->tfm;
115 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
116 : : struct shash_alg *shash = crypto_shash_alg(tfm);
117 : : unsigned int ds = crypto_shash_digestsize(tfm);
118 : 0 : u8 ubuf[shash_align_buffer_size(ds, alignmask)]
119 : : __attribute__ ((aligned));
120 : 0 : u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
121 : : int err;
122 : :
123 : 0 : err = shash->final(desc, buf);
124 [ # # ]: 0 : if (err)
125 : : goto out;
126 : :
127 : 0 : memcpy(out, buf, ds);
128 : :
129 : : out:
130 [ # # ]: 0 : memset(buf, 0, ds);
131 : 0 : return err;
132 : : }
133 : :
134 : 0 : int crypto_shash_final(struct shash_desc *desc, u8 *out)
135 : : {
136 : 0 : struct crypto_shash *tfm = desc->tfm;
137 : : struct shash_alg *shash = crypto_shash_alg(tfm);
138 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
139 : :
140 [ # # ]: 0 : if ((unsigned long)out & alignmask)
141 : 0 : return shash_final_unaligned(desc, out);
142 : :
143 : 0 : return shash->final(desc, out);
144 : : }
145 : : EXPORT_SYMBOL_GPL(crypto_shash_final);
146 : :
147 : 0 : static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data,
148 : : unsigned int len, u8 *out)
149 : : {
150 [ # # ]: 0 : return crypto_shash_update(desc, data, len) ?:
151 : : crypto_shash_final(desc, out);
152 : : }
153 : :
154 : 0 : int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
155 : : unsigned int len, u8 *out)
156 : : {
157 : 0 : struct crypto_shash *tfm = desc->tfm;
158 : : struct shash_alg *shash = crypto_shash_alg(tfm);
159 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
160 : :
161 [ # # ]: 0 : if (((unsigned long)data | (unsigned long)out) & alignmask)
162 : 0 : return shash_finup_unaligned(desc, data, len, out);
163 : :
164 : 0 : return shash->finup(desc, data, len, out);
165 : : }
166 : : EXPORT_SYMBOL_GPL(crypto_shash_finup);
167 : :
168 : 0 : static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data,
169 : : unsigned int len, u8 *out)
170 : : {
171 [ # # ]: 0 : return crypto_shash_init(desc) ?:
172 : : crypto_shash_finup(desc, data, len, out);
173 : : }
174 : :
175 : 0 : int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
176 : : unsigned int len, u8 *out)
177 : : {
178 : 0 : struct crypto_shash *tfm = desc->tfm;
179 : : struct shash_alg *shash = crypto_shash_alg(tfm);
180 : : unsigned long alignmask = crypto_shash_alignmask(tfm);
181 : :
182 [ # # ]: 0 : if (((unsigned long)data | (unsigned long)out) & alignmask)
183 : 0 : return shash_digest_unaligned(desc, data, len, out);
184 : :
185 : 0 : return shash->digest(desc, data, len, out);
186 : : }
187 : : EXPORT_SYMBOL_GPL(crypto_shash_digest);
188 : :
189 : 0 : static int shash_default_export(struct shash_desc *desc, void *out)
190 : : {
191 : 0 : memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm));
192 : 0 : return 0;
193 : : }
194 : :
195 : 0 : static int shash_default_import(struct shash_desc *desc, const void *in)
196 : : {
197 : 0 : memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(desc->tfm));
198 : 0 : return 0;
199 : : }
200 : :
201 : 0 : static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
202 : : unsigned int keylen)
203 : : {
204 : : struct crypto_shash **ctx = crypto_ahash_ctx(tfm);
205 : :
206 : 0 : return crypto_shash_setkey(*ctx, key, keylen);
207 : : }
208 : :
209 : 0 : static int shash_async_init(struct ahash_request *req)
210 : : {
211 : : struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
212 : 0 : struct shash_desc *desc = ahash_request_ctx(req);
213 : :
214 : 0 : desc->tfm = *ctx;
215 : 0 : desc->flags = req->base.flags;
216 : :
217 : 0 : return crypto_shash_init(desc);
218 : : }
219 : :
220 : 0 : int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc)
221 : : {
222 : : struct crypto_hash_walk walk;
223 : : int nbytes;
224 : :
225 [ # # ]: 0 : for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0;
226 : 0 : nbytes = crypto_hash_walk_done(&walk, nbytes))
227 : 0 : nbytes = crypto_shash_update(desc, walk.data, nbytes);
228 : :
229 : 0 : return nbytes;
230 : : }
231 : : EXPORT_SYMBOL_GPL(shash_ahash_update);
232 : :
233 : 0 : static int shash_async_update(struct ahash_request *req)
234 : : {
235 : 0 : return shash_ahash_update(req, ahash_request_ctx(req));
236 : : }
237 : :
238 : 0 : static int shash_async_final(struct ahash_request *req)
239 : : {
240 : 0 : return crypto_shash_final(ahash_request_ctx(req), req->result);
241 : : }
242 : :
243 : 0 : int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc)
244 : : {
245 : : struct crypto_hash_walk walk;
246 : : int nbytes;
247 : :
248 : 0 : nbytes = crypto_hash_walk_first(req, &walk);
249 [ # # ]: 0 : if (!nbytes)
250 : 0 : return crypto_shash_final(desc, req->result);
251 : :
252 : : do {
253 : 0 : nbytes = crypto_hash_walk_last(&walk) ?
254 : 0 : crypto_shash_finup(desc, walk.data, nbytes,
255 [ # # ]: 0 : req->result) :
256 : 0 : crypto_shash_update(desc, walk.data, nbytes);
257 : 0 : nbytes = crypto_hash_walk_done(&walk, nbytes);
258 [ # # ]: 0 : } while (nbytes > 0);
259 : :
260 : : return nbytes;
261 : : }
262 : : EXPORT_SYMBOL_GPL(shash_ahash_finup);
263 : :
264 : 0 : static int shash_async_finup(struct ahash_request *req)
265 : : {
266 : : struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
267 : 0 : struct shash_desc *desc = ahash_request_ctx(req);
268 : :
269 : 0 : desc->tfm = *ctx;
270 : 0 : desc->flags = req->base.flags;
271 : :
272 : 0 : return shash_ahash_finup(req, desc);
273 : : }
274 : :
275 : 0 : int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
276 : : {
277 : 0 : struct scatterlist *sg = req->src;
278 : 0 : unsigned int offset = sg->offset;
279 : 0 : unsigned int nbytes = req->nbytes;
280 : : int err;
281 : :
282 [ # # ]: 0 : if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
283 : : void *data;
284 : :
285 : 0 : data = kmap_atomic(sg_page(sg));
286 : 0 : err = crypto_shash_digest(desc, data + offset, nbytes,
287 : : req->result);
288 : 0 : kunmap_atomic(data);
289 : 0 : crypto_yield(desc->flags);
290 : : } else
291 [ # # ]: 0 : err = crypto_shash_init(desc) ?:
292 : : shash_ahash_finup(req, desc);
293 : :
294 : 0 : return err;
295 : : }
296 : : EXPORT_SYMBOL_GPL(shash_ahash_digest);
297 : :
298 : 0 : static int shash_async_digest(struct ahash_request *req)
299 : : {
300 : : struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
301 : 0 : struct shash_desc *desc = ahash_request_ctx(req);
302 : :
303 : 0 : desc->tfm = *ctx;
304 : 0 : desc->flags = req->base.flags;
305 : :
306 : 0 : return shash_ahash_digest(req, desc);
307 : : }
308 : :
309 : 0 : static int shash_async_export(struct ahash_request *req, void *out)
310 : : {
311 : 0 : return crypto_shash_export(ahash_request_ctx(req), out);
312 : : }
313 : :
314 : 0 : static int shash_async_import(struct ahash_request *req, const void *in)
315 : : {
316 : : struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
317 : 0 : struct shash_desc *desc = ahash_request_ctx(req);
318 : :
319 : 0 : desc->tfm = *ctx;
320 : 0 : desc->flags = req->base.flags;
321 : :
322 : 0 : return crypto_shash_import(desc, in);
323 : : }
324 : :
325 : 0 : static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm)
326 : : {
327 : : struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
328 : :
329 : 0 : crypto_free_shash(*ctx);
330 : 0 : }
331 : :
332 : 0 : int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
333 : : {
334 : 0 : struct crypto_alg *calg = tfm->__crt_alg;
335 : : struct shash_alg *alg = __crypto_shash_alg(calg);
336 : : struct crypto_ahash *crt = __crypto_ahash_cast(tfm);
337 : : struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
338 : : struct crypto_shash *shash;
339 : :
340 [ # # ]: 0 : if (!crypto_mod_get(calg))
341 : : return -EAGAIN;
342 : :
343 : 0 : shash = crypto_create_tfm(calg, &crypto_shash_type);
344 [ # # ]: 0 : if (IS_ERR(shash)) {
345 : 0 : crypto_mod_put(calg);
346 : 0 : return PTR_ERR(shash);
347 : : }
348 : :
349 : 0 : *ctx = shash;
350 : 0 : tfm->exit = crypto_exit_shash_ops_async;
351 : :
352 : 0 : crt->init = shash_async_init;
353 : 0 : crt->update = shash_async_update;
354 : 0 : crt->final = shash_async_final;
355 : 0 : crt->finup = shash_async_finup;
356 : 0 : crt->digest = shash_async_digest;
357 : :
358 [ # # ]: 0 : if (alg->setkey)
359 : 0 : crt->setkey = shash_async_setkey;
360 [ # # ]: 0 : if (alg->export)
361 : 0 : crt->export = shash_async_export;
362 [ # # ]: 0 : if (alg->import)
363 : 0 : crt->import = shash_async_import;
364 : :
365 : 0 : crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash);
366 : :
367 : 0 : return 0;
368 : : }
369 : :
370 : 0 : static int shash_compat_setkey(struct crypto_hash *tfm, const u8 *key,
371 : : unsigned int keylen)
372 : : {
373 : : struct shash_desc **descp = crypto_hash_ctx(tfm);
374 : 0 : struct shash_desc *desc = *descp;
375 : :
376 : 0 : return crypto_shash_setkey(desc->tfm, key, keylen);
377 : : }
378 : :
379 : 0 : static int shash_compat_init(struct hash_desc *hdesc)
380 : : {
381 : 0 : struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
382 : 0 : struct shash_desc *desc = *descp;
383 : :
384 : 0 : desc->flags = hdesc->flags;
385 : :
386 : 0 : return crypto_shash_init(desc);
387 : : }
388 : :
389 : 0 : static int shash_compat_update(struct hash_desc *hdesc, struct scatterlist *sg,
390 : : unsigned int len)
391 : : {
392 : 0 : struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
393 : 0 : struct shash_desc *desc = *descp;
394 : : struct crypto_hash_walk walk;
395 : : int nbytes;
396 : :
397 [ # # ]: 0 : for (nbytes = crypto_hash_walk_first_compat(hdesc, &walk, sg, len);
398 : 0 : nbytes > 0; nbytes = crypto_hash_walk_done(&walk, nbytes))
399 : 0 : nbytes = crypto_shash_update(desc, walk.data, nbytes);
400 : :
401 : 0 : return nbytes;
402 : : }
403 : :
404 : 0 : static int shash_compat_final(struct hash_desc *hdesc, u8 *out)
405 : : {
406 : 0 : struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
407 : :
408 : 0 : return crypto_shash_final(*descp, out);
409 : : }
410 : :
411 : 0 : static int shash_compat_digest(struct hash_desc *hdesc, struct scatterlist *sg,
412 : : unsigned int nbytes, u8 *out)
413 : : {
414 : 0 : unsigned int offset = sg->offset;
415 : : int err;
416 : :
417 [ # # ]: 0 : if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
418 : 0 : struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
419 : 0 : struct shash_desc *desc = *descp;
420 : : void *data;
421 : :
422 : 0 : desc->flags = hdesc->flags;
423 : :
424 : 0 : data = kmap_atomic(sg_page(sg));
425 : 0 : err = crypto_shash_digest(desc, data + offset, nbytes, out);
426 : 0 : kunmap_atomic(data);
427 : 0 : crypto_yield(desc->flags);
428 : : goto out;
429 : : }
430 : :
431 : : err = shash_compat_init(hdesc);
432 [ # # ]: 0 : if (err)
433 : : goto out;
434 : :
435 : 0 : err = shash_compat_update(hdesc, sg, nbytes);
436 [ # # ]: 0 : if (err)
437 : : goto out;
438 : :
439 : : err = shash_compat_final(hdesc, out);
440 : :
441 : : out:
442 : 0 : return err;
443 : : }
444 : :
445 : 0 : static void crypto_exit_shash_ops_compat(struct crypto_tfm *tfm)
446 : : {
447 : : struct shash_desc **descp = crypto_tfm_ctx(tfm);
448 : 0 : struct shash_desc *desc = *descp;
449 : :
450 : 0 : crypto_free_shash(desc->tfm);
451 : 0 : kzfree(desc);
452 : 0 : }
453 : :
454 : 0 : static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm)
455 : : {
456 : : struct hash_tfm *crt = &tfm->crt_hash;
457 : 0 : struct crypto_alg *calg = tfm->__crt_alg;
458 : : struct shash_alg *alg = __crypto_shash_alg(calg);
459 : : struct shash_desc **descp = crypto_tfm_ctx(tfm);
460 : : struct crypto_shash *shash;
461 : : struct shash_desc *desc;
462 : :
463 [ # # ]: 0 : if (!crypto_mod_get(calg))
464 : : return -EAGAIN;
465 : :
466 : 0 : shash = crypto_create_tfm(calg, &crypto_shash_type);
467 [ # # ]: 0 : if (IS_ERR(shash)) {
468 : 0 : crypto_mod_put(calg);
469 : 0 : return PTR_ERR(shash);
470 : : }
471 : :
472 : 0 : desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(shash),
473 : : GFP_KERNEL);
474 [ # # ]: 0 : if (!desc) {
475 : : crypto_free_shash(shash);
476 : 0 : return -ENOMEM;
477 : : }
478 : :
479 : 0 : *descp = desc;
480 : 0 : desc->tfm = shash;
481 : 0 : tfm->exit = crypto_exit_shash_ops_compat;
482 : :
483 : 0 : crt->init = shash_compat_init;
484 : 0 : crt->update = shash_compat_update;
485 : 0 : crt->final = shash_compat_final;
486 : 0 : crt->digest = shash_compat_digest;
487 : 0 : crt->setkey = shash_compat_setkey;
488 : :
489 : 0 : crt->digestsize = alg->digestsize;
490 : :
491 : 0 : return 0;
492 : : }
493 : :
494 : 0 : static int crypto_init_shash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
495 : : {
496 [ # # ]: 0 : switch (mask & CRYPTO_ALG_TYPE_MASK) {
497 : : case CRYPTO_ALG_TYPE_HASH_MASK:
498 : 0 : return crypto_init_shash_ops_compat(tfm);
499 : : }
500 : :
501 : : return -EINVAL;
502 : : }
503 : :
504 : 0 : static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type,
505 : : u32 mask)
506 : : {
507 [ # # ]: 0 : switch (mask & CRYPTO_ALG_TYPE_MASK) {
508 : : case CRYPTO_ALG_TYPE_HASH_MASK:
509 : : return sizeof(struct shash_desc *);
510 : : }
511 : :
512 : 0 : return 0;
513 : : }
514 : :
515 : 0 : static int crypto_shash_init_tfm(struct crypto_tfm *tfm)
516 : : {
517 : : struct crypto_shash *hash = __crypto_shash_cast(tfm);
518 : :
519 : 0 : hash->descsize = crypto_shash_alg(hash)->descsize;
520 : 0 : return 0;
521 : : }
522 : :
523 : 0 : static unsigned int crypto_shash_extsize(struct crypto_alg *alg)
524 : : {
525 : 0 : return alg->cra_ctxsize;
526 : : }
527 : :
528 : : #ifdef CONFIG_NET
529 : 0 : static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
530 : : {
531 : : struct crypto_report_hash rhash;
532 : : struct shash_alg *salg = __crypto_shash_alg(alg);
533 : :
534 : 0 : strncpy(rhash.type, "shash", sizeof(rhash.type));
535 : :
536 : 0 : rhash.blocksize = alg->cra_blocksize;
537 : 0 : rhash.digestsize = salg->digestsize;
538 : :
539 [ # # ]: 0 : if (nla_put(skb, CRYPTOCFGA_REPORT_HASH,
540 : : sizeof(struct crypto_report_hash), &rhash))
541 : : goto nla_put_failure;
542 : : return 0;
543 : :
544 : : nla_put_failure:
545 : 0 : return -EMSGSIZE;
546 : : }
547 : : #else
548 : : static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
549 : : {
550 : : return -ENOSYS;
551 : : }
552 : : #endif
553 : :
554 : : static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
555 : : __attribute__ ((unused));
556 : 0 : static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
557 : : {
558 : : struct shash_alg *salg = __crypto_shash_alg(alg);
559 : :
560 : 5 : seq_printf(m, "type : shash\n");
561 : 5 : seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
562 : 5 : seq_printf(m, "digestsize : %u\n", salg->digestsize);
563 : 5 : }
564 : :
565 : : static const struct crypto_type crypto_shash_type = {
566 : : .ctxsize = crypto_shash_ctxsize,
567 : : .extsize = crypto_shash_extsize,
568 : : .init = crypto_init_shash_ops,
569 : : .init_tfm = crypto_shash_init_tfm,
570 : : #ifdef CONFIG_PROC_FS
571 : : .show = crypto_shash_show,
572 : : #endif
573 : : .report = crypto_shash_report,
574 : : .maskclear = ~CRYPTO_ALG_TYPE_MASK,
575 : : .maskset = CRYPTO_ALG_TYPE_MASK,
576 : : .type = CRYPTO_ALG_TYPE_SHASH,
577 : : .tfmsize = offsetof(struct crypto_shash, base),
578 : : };
579 : :
580 : 0 : struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
581 : : u32 mask)
582 : : {
583 : 0 : return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask);
584 : : }
585 : : EXPORT_SYMBOL_GPL(crypto_alloc_shash);
586 : :
587 : 0 : static int shash_prepare_alg(struct shash_alg *alg)
588 : : {
589 : : struct crypto_alg *base = &alg->base;
590 : :
591 [ # # ][ # # ]: 0 : if (alg->digestsize > PAGE_SIZE / 8 ||
592 [ # # ]: 0 : alg->descsize > PAGE_SIZE / 8 ||
593 : 0 : alg->statesize > PAGE_SIZE / 8)
594 : : return -EINVAL;
595 : :
596 : 0 : base->cra_type = &crypto_shash_type;
597 : 0 : base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
598 : 0 : base->cra_flags |= CRYPTO_ALG_TYPE_SHASH;
599 : :
600 [ # # ]: 0 : if (!alg->finup)
601 : 0 : alg->finup = shash_finup_unaligned;
602 [ # # ]: 0 : if (!alg->digest)
603 : 0 : alg->digest = shash_digest_unaligned;
604 [ # # ]: 0 : if (!alg->export) {
605 : 0 : alg->export = shash_default_export;
606 : 0 : alg->import = shash_default_import;
607 : 0 : alg->statesize = alg->descsize;
608 : : }
609 [ # # ]: 0 : if (!alg->setkey)
610 : 0 : alg->setkey = shash_no_setkey;
611 : :
612 : : return 0;
613 : : }
614 : :
615 : 0 : int crypto_register_shash(struct shash_alg *alg)
616 : : {
617 : 0 : struct crypto_alg *base = &alg->base;
618 : : int err;
619 : :
620 : 0 : err = shash_prepare_alg(alg);
621 [ # # ]: 0 : if (err)
622 : : return err;
623 : :
624 : 0 : return crypto_register_alg(base);
625 : : }
626 : : EXPORT_SYMBOL_GPL(crypto_register_shash);
627 : :
628 : 0 : int crypto_unregister_shash(struct shash_alg *alg)
629 : : {
630 : 0 : return crypto_unregister_alg(&alg->base);
631 : : }
632 : : EXPORT_SYMBOL_GPL(crypto_unregister_shash);
633 : :
634 : 0 : int crypto_register_shashes(struct shash_alg *algs, int count)
635 : : {
636 : : int i, ret;
637 : :
638 [ # # ]: 0 : for (i = 0; i < count; i++) {
639 : 0 : ret = crypto_register_shash(&algs[i]);
640 [ # # ]: 0 : if (ret)
641 : : goto err;
642 : : }
643 : :
644 : : return 0;
645 : :
646 : : err:
647 [ # # ]: 0 : for (--i; i >= 0; --i)
648 : 0 : crypto_unregister_shash(&algs[i]);
649 : :
650 : : return ret;
651 : : }
652 : : EXPORT_SYMBOL_GPL(crypto_register_shashes);
653 : :
654 : 0 : int crypto_unregister_shashes(struct shash_alg *algs, int count)
655 : : {
656 : : int i, ret;
657 : :
658 [ # # ]: 0 : for (i = count - 1; i >= 0; --i) {
659 : 0 : ret = crypto_unregister_shash(&algs[i]);
660 [ # # ]: 0 : if (ret)
661 : 0 : pr_err("Failed to unregister %s %s: %d\n",
662 : : algs[i].base.cra_driver_name,
663 : : algs[i].base.cra_name, ret);
664 : : }
665 : :
666 : 0 : return 0;
667 : : }
668 : : EXPORT_SYMBOL_GPL(crypto_unregister_shashes);
669 : :
670 : 0 : int shash_register_instance(struct crypto_template *tmpl,
671 : : struct shash_instance *inst)
672 : : {
673 : : int err;
674 : :
675 : 0 : err = shash_prepare_alg(&inst->alg);
676 [ # # ]: 0 : if (err)
677 : : return err;
678 : :
679 : 0 : return crypto_register_instance(tmpl, shash_crypto_instance(inst));
680 : : }
681 : : EXPORT_SYMBOL_GPL(shash_register_instance);
682 : :
683 : 0 : void shash_free_instance(struct crypto_instance *inst)
684 : : {
685 : 0 : crypto_drop_spawn(crypto_instance_ctx(inst));
686 : 0 : kfree(shash_instance(inst));
687 : 0 : }
688 : : EXPORT_SYMBOL_GPL(shash_free_instance);
689 : :
690 : 0 : int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn,
691 : : struct shash_alg *alg,
692 : : struct crypto_instance *inst)
693 : : {
694 : 0 : return crypto_init_spawn2(&spawn->base, &alg->base, inst,
695 : : &crypto_shash_type);
696 : : }
697 : : EXPORT_SYMBOL_GPL(crypto_init_shash_spawn);
698 : :
699 : 0 : struct shash_alg *shash_attr_alg(struct rtattr *rta, u32 type, u32 mask)
700 : : {
701 : : struct crypto_alg *alg;
702 : :
703 : 0 : alg = crypto_attr_alg2(rta, &crypto_shash_type, type, mask);
704 [ # # ]: 0 : return IS_ERR(alg) ? ERR_CAST(alg) :
705 : : container_of(alg, struct shash_alg, base);
706 : : }
707 : : EXPORT_SYMBOL_GPL(shash_attr_alg);
708 : :
709 : : MODULE_LICENSE("GPL");
710 : : MODULE_DESCRIPTION("Synchronous cryptographic hash type");
|