diff options
author | Loc Ho <lho@amcc.com> | 2008-05-14 08:41:47 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-07-10 08:35:13 -0400 |
commit | 004a403c2e954734090a69aedc7f4f822bdcc142 (patch) | |
tree | e8fadd76113132126e308e01e7cd7cdf6b9d44d6 /crypto/ahash.c | |
parent | 534fe2c1c3ffbbc3db66dba0783c82d3b345fd33 (diff) |
[CRYPTO] hash: Add asynchronous hash support
This patch adds asynchronous hash and digest support.
Signed-off-by: Loc Ho <lho@amcc.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/ahash.c')
-rw-r--r-- | crypto/ahash.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c new file mode 100644 index 000000000000..a83e035d9a3f --- /dev/null +++ b/crypto/ahash.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * Asynchronous Cryptographic Hash operations. | ||
3 | * | ||
4 | * This is the asynchronous version of hash.c with notification of | ||
5 | * completion via a callback. | ||
6 | * | ||
7 | * Copyright (c) 2008 Loc Ho <lho@amcc.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <crypto/algapi.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/seq_file.h> | ||
23 | |||
24 | #include "internal.h" | ||
25 | |||
26 | static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, | ||
27 | unsigned int keylen) | ||
28 | { | ||
29 | struct ahash_alg *ahash = crypto_ahash_alg(tfm); | ||
30 | unsigned long alignmask = crypto_ahash_alignmask(tfm); | ||
31 | int ret; | ||
32 | u8 *buffer, *alignbuffer; | ||
33 | unsigned long absize; | ||
34 | |||
35 | absize = keylen + alignmask; | ||
36 | buffer = kmalloc(absize, GFP_ATOMIC); | ||
37 | if (!buffer) | ||
38 | return -ENOMEM; | ||
39 | |||
40 | alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | ||
41 | memcpy(alignbuffer, key, keylen); | ||
42 | ret = ahash->setkey(tfm, alignbuffer, keylen); | ||
43 | memset(alignbuffer, 0, keylen); | ||
44 | kfree(buffer); | ||
45 | return ret; | ||
46 | } | ||
47 | |||
48 | static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key, | ||
49 | unsigned int keylen) | ||
50 | { | ||
51 | struct ahash_alg *ahash = crypto_ahash_alg(tfm); | ||
52 | unsigned long alignmask = crypto_ahash_alignmask(tfm); | ||
53 | |||
54 | if ((unsigned long)key & alignmask) | ||
55 | return ahash_setkey_unaligned(tfm, key, keylen); | ||
56 | |||
57 | return ahash->setkey(tfm, key, keylen); | ||
58 | } | ||
59 | |||
60 | static unsigned int crypto_ahash_ctxsize(struct crypto_alg *alg, u32 type, | ||
61 | u32 mask) | ||
62 | { | ||
63 | return alg->cra_ctxsize; | ||
64 | } | ||
65 | |||
66 | static int crypto_init_ahash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | ||
67 | { | ||
68 | struct ahash_alg *alg = &tfm->__crt_alg->cra_ahash; | ||
69 | struct ahash_tfm *crt = &tfm->crt_ahash; | ||
70 | |||
71 | if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) | ||
72 | return -EINVAL; | ||
73 | |||
74 | crt->init = alg->init; | ||
75 | crt->update = alg->update; | ||
76 | crt->final = alg->final; | ||
77 | crt->digest = alg->digest; | ||
78 | crt->setkey = ahash_setkey; | ||
79 | crt->base = __crypto_ahash_cast(tfm); | ||
80 | crt->digestsize = alg->digestsize; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) | ||
86 | __attribute__ ((unused)); | ||
87 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) | ||
88 | { | ||
89 | seq_printf(m, "type : ahash\n"); | ||
90 | seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? | ||
91 | "yes" : "no"); | ||
92 | seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); | ||
93 | seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize); | ||
94 | } | ||
95 | |||
96 | const struct crypto_type crypto_ahash_type = { | ||
97 | .ctxsize = crypto_ahash_ctxsize, | ||
98 | .init = crypto_init_ahash_ops, | ||
99 | #ifdef CONFIG_PROC_FS | ||
100 | .show = crypto_ahash_show, | ||
101 | #endif | ||
102 | }; | ||
103 | EXPORT_SYMBOL_GPL(crypto_ahash_type); | ||
104 | |||
105 | MODULE_LICENSE("GPL"); | ||
106 | MODULE_DESCRIPTION("Asynchronous cryptographic hash type"); | ||