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 | |
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>
-rw-r--r-- | crypto/Makefile | 1 | ||||
-rw-r--r-- | crypto/ahash.c | 106 | ||||
-rw-r--r-- | crypto/api.c | 8 | ||||
-rw-r--r-- | crypto/digest.c | 81 | ||||
-rw-r--r-- | crypto/hash.c | 102 | ||||
-rw-r--r-- | crypto/internal.h | 1 | ||||
-rw-r--r-- | include/crypto/algapi.h | 36 | ||||
-rw-r--r-- | include/linux/crypto.h | 187 |
8 files changed, 507 insertions, 15 deletions
diff --git a/crypto/Makefile b/crypto/Makefile index 807656b64e02..d4f3ed857df0 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_CRYPTO_BLKCIPHER) += crypto_blkcipher.o | |||
19 | obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o | 19 | obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o |
20 | 20 | ||
21 | crypto_hash-objs := hash.o | 21 | crypto_hash-objs := hash.o |
22 | crypto_hash-objs += ahash.o | ||
22 | obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o | 23 | obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o |
23 | 24 | ||
24 | obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o | 25 | obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o |
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"); | ||
diff --git a/crypto/api.c b/crypto/api.c index 0a0f41ef255f..d06e33270abe 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
@@ -235,8 +235,12 @@ static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
235 | return crypto_init_cipher_ops(tfm); | 235 | return crypto_init_cipher_ops(tfm); |
236 | 236 | ||
237 | case CRYPTO_ALG_TYPE_DIGEST: | 237 | case CRYPTO_ALG_TYPE_DIGEST: |
238 | return crypto_init_digest_ops(tfm); | 238 | if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != |
239 | 239 | CRYPTO_ALG_TYPE_HASH_MASK) | |
240 | return crypto_init_digest_ops_async(tfm); | ||
241 | else | ||
242 | return crypto_init_digest_ops(tfm); | ||
243 | |||
240 | case CRYPTO_ALG_TYPE_COMPRESS: | 244 | case CRYPTO_ALG_TYPE_COMPRESS: |
241 | return crypto_init_compress_ops(tfm); | 245 | return crypto_init_compress_ops(tfm); |
242 | 246 | ||
diff --git a/crypto/digest.c b/crypto/digest.c index b526cc348b79..025c9aea24ed 100644 --- a/crypto/digest.c +++ b/crypto/digest.c | |||
@@ -157,3 +157,84 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm) | |||
157 | void crypto_exit_digest_ops(struct crypto_tfm *tfm) | 157 | void crypto_exit_digest_ops(struct crypto_tfm *tfm) |
158 | { | 158 | { |
159 | } | 159 | } |
160 | |||
161 | static int digest_async_nosetkey(struct crypto_ahash *tfm_async, const u8 *key, | ||
162 | unsigned int keylen) | ||
163 | { | ||
164 | crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK); | ||
165 | return -ENOSYS; | ||
166 | } | ||
167 | |||
168 | static int digest_async_setkey(struct crypto_ahash *tfm_async, const u8 *key, | ||
169 | unsigned int keylen) | ||
170 | { | ||
171 | struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async); | ||
172 | struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; | ||
173 | |||
174 | crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK); | ||
175 | return dalg->dia_setkey(tfm, key, keylen); | ||
176 | } | ||
177 | |||
178 | static int digest_async_init(struct ahash_request *req) | ||
179 | { | ||
180 | struct crypto_tfm *tfm = req->base.tfm; | ||
181 | struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; | ||
182 | |||
183 | dalg->dia_init(tfm); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int digest_async_update(struct ahash_request *req) | ||
188 | { | ||
189 | struct crypto_tfm *tfm = req->base.tfm; | ||
190 | struct hash_desc desc = { | ||
191 | .tfm = __crypto_hash_cast(tfm), | ||
192 | .flags = req->base.flags, | ||
193 | }; | ||
194 | |||
195 | update(&desc, req->src, req->nbytes); | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static int digest_async_final(struct ahash_request *req) | ||
200 | { | ||
201 | struct crypto_tfm *tfm = req->base.tfm; | ||
202 | struct hash_desc desc = { | ||
203 | .tfm = __crypto_hash_cast(tfm), | ||
204 | .flags = req->base.flags, | ||
205 | }; | ||
206 | |||
207 | final(&desc, req->result); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static int digest_async_digest(struct ahash_request *req) | ||
212 | { | ||
213 | struct crypto_tfm *tfm = req->base.tfm; | ||
214 | struct hash_desc desc = { | ||
215 | .tfm = __crypto_hash_cast(tfm), | ||
216 | .flags = req->base.flags, | ||
217 | }; | ||
218 | |||
219 | return digest(&desc, req->src, req->nbytes, req->result); | ||
220 | } | ||
221 | |||
222 | int crypto_init_digest_ops_async(struct crypto_tfm *tfm) | ||
223 | { | ||
224 | struct ahash_tfm *crt = &tfm->crt_ahash; | ||
225 | struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; | ||
226 | |||
227 | if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm)) | ||
228 | return -EINVAL; | ||
229 | |||
230 | crt->init = digest_async_init; | ||
231 | crt->update = digest_async_update; | ||
232 | crt->final = digest_async_final; | ||
233 | crt->digest = digest_async_digest; | ||
234 | crt->setkey = dalg->dia_setkey ? digest_async_setkey : | ||
235 | digest_async_nosetkey; | ||
236 | crt->digestsize = dalg->dia_digestsize; | ||
237 | crt->base = __crypto_ahash_cast(tfm); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
diff --git a/crypto/hash.c b/crypto/hash.c index 7dcff671c19b..f9400a014e74 100644 --- a/crypto/hash.c +++ b/crypto/hash.c | |||
@@ -59,24 +59,108 @@ static int hash_setkey(struct crypto_hash *crt, const u8 *key, | |||
59 | return alg->setkey(crt, key, keylen); | 59 | return alg->setkey(crt, key, keylen); |
60 | } | 60 | } |
61 | 61 | ||
62 | static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | 62 | static int hash_async_setkey(struct crypto_ahash *tfm_async, const u8 *key, |
63 | unsigned int keylen) | ||
64 | { | ||
65 | struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async); | ||
66 | struct crypto_hash *tfm_hash = __crypto_hash_cast(tfm); | ||
67 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
68 | |||
69 | return alg->setkey(tfm_hash, key, keylen); | ||
70 | } | ||
71 | |||
72 | static int hash_async_init(struct ahash_request *req) | ||
73 | { | ||
74 | struct crypto_tfm *tfm = req->base.tfm; | ||
75 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
76 | struct hash_desc desc = { | ||
77 | .tfm = __crypto_hash_cast(tfm), | ||
78 | .flags = req->base.flags, | ||
79 | }; | ||
80 | |||
81 | return alg->init(&desc); | ||
82 | } | ||
83 | |||
84 | static int hash_async_update(struct ahash_request *req) | ||
85 | { | ||
86 | struct crypto_tfm *tfm = req->base.tfm; | ||
87 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
88 | struct hash_desc desc = { | ||
89 | .tfm = __crypto_hash_cast(tfm), | ||
90 | .flags = req->base.flags, | ||
91 | }; | ||
92 | |||
93 | return alg->update(&desc, req->src, req->nbytes); | ||
94 | } | ||
95 | |||
96 | static int hash_async_final(struct ahash_request *req) | ||
97 | { | ||
98 | struct crypto_tfm *tfm = req->base.tfm; | ||
99 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
100 | struct hash_desc desc = { | ||
101 | .tfm = __crypto_hash_cast(tfm), | ||
102 | .flags = req->base.flags, | ||
103 | }; | ||
104 | |||
105 | return alg->final(&desc, req->result); | ||
106 | } | ||
107 | |||
108 | static int hash_async_digest(struct ahash_request *req) | ||
109 | { | ||
110 | struct crypto_tfm *tfm = req->base.tfm; | ||
111 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
112 | struct hash_desc desc = { | ||
113 | .tfm = __crypto_hash_cast(tfm), | ||
114 | .flags = req->base.flags, | ||
115 | }; | ||
116 | |||
117 | return alg->digest(&desc, req->src, req->nbytes, req->result); | ||
118 | } | ||
119 | |||
120 | static int crypto_init_hash_ops_async(struct crypto_tfm *tfm) | ||
121 | { | ||
122 | struct ahash_tfm *crt = &tfm->crt_ahash; | ||
123 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
124 | |||
125 | crt->init = hash_async_init; | ||
126 | crt->update = hash_async_update; | ||
127 | crt->final = hash_async_final; | ||
128 | crt->digest = hash_async_digest; | ||
129 | crt->setkey = hash_async_setkey; | ||
130 | crt->digestsize = alg->digestsize; | ||
131 | crt->base = __crypto_ahash_cast(tfm); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int crypto_init_hash_ops_sync(struct crypto_tfm *tfm) | ||
63 | { | 137 | { |
64 | struct hash_tfm *crt = &tfm->crt_hash; | 138 | struct hash_tfm *crt = &tfm->crt_hash; |
65 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | 139 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; |
66 | 140 | ||
67 | if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) | 141 | crt->init = alg->init; |
68 | return -EINVAL; | 142 | crt->update = alg->update; |
69 | 143 | crt->final = alg->final; | |
70 | crt->init = alg->init; | 144 | crt->digest = alg->digest; |
71 | crt->update = alg->update; | 145 | crt->setkey = hash_setkey; |
72 | crt->final = alg->final; | ||
73 | crt->digest = alg->digest; | ||
74 | crt->setkey = hash_setkey; | ||
75 | crt->digestsize = alg->digestsize; | 146 | crt->digestsize = alg->digestsize; |
76 | 147 | ||
77 | return 0; | 148 | return 0; |
78 | } | 149 | } |
79 | 150 | ||
151 | static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | ||
152 | { | ||
153 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
154 | |||
155 | if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) | ||
156 | return -EINVAL; | ||
157 | |||
158 | if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK) | ||
159 | return crypto_init_hash_ops_async(tfm); | ||
160 | else | ||
161 | return crypto_init_hash_ops_sync(tfm); | ||
162 | } | ||
163 | |||
80 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | 164 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) |
81 | __attribute__ ((unused)); | 165 | __attribute__ ((unused)); |
82 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | 166 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) |
diff --git a/crypto/internal.h b/crypto/internal.h index 32f4c2145603..683fcb2d91f4 100644 --- a/crypto/internal.h +++ b/crypto/internal.h | |||
@@ -86,6 +86,7 @@ struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask); | |||
86 | struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask); | 86 | struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask); |
87 | 87 | ||
88 | int crypto_init_digest_ops(struct crypto_tfm *tfm); | 88 | int crypto_init_digest_ops(struct crypto_tfm *tfm); |
89 | int crypto_init_digest_ops_async(struct crypto_tfm *tfm); | ||
89 | int crypto_init_cipher_ops(struct crypto_tfm *tfm); | 90 | int crypto_init_cipher_ops(struct crypto_tfm *tfm); |
90 | int crypto_init_compress_ops(struct crypto_tfm *tfm); | 91 | int crypto_init_compress_ops(struct crypto_tfm *tfm); |
91 | 92 | ||
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 60d06e784be3..fef272a8ceeb 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h | |||
@@ -98,6 +98,7 @@ extern const struct crypto_type crypto_ablkcipher_type; | |||
98 | extern const struct crypto_type crypto_aead_type; | 98 | extern const struct crypto_type crypto_aead_type; |
99 | extern const struct crypto_type crypto_blkcipher_type; | 99 | extern const struct crypto_type crypto_blkcipher_type; |
100 | extern const struct crypto_type crypto_hash_type; | 100 | extern const struct crypto_type crypto_hash_type; |
101 | extern const struct crypto_type crypto_ahash_type; | ||
101 | 102 | ||
102 | void crypto_mod_put(struct crypto_alg *alg); | 103 | void crypto_mod_put(struct crypto_alg *alg); |
103 | 104 | ||
@@ -314,5 +315,40 @@ static inline int crypto_requires_sync(u32 type, u32 mask) | |||
314 | return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC; | 315 | return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC; |
315 | } | 316 | } |
316 | 317 | ||
318 | static inline void *crypto_ahash_ctx(struct crypto_ahash *tfm) | ||
319 | { | ||
320 | return crypto_tfm_ctx(&tfm->base); | ||
321 | } | ||
322 | |||
323 | static inline struct ahash_alg *crypto_ahash_alg( | ||
324 | struct crypto_ahash *tfm) | ||
325 | { | ||
326 | return &crypto_ahash_tfm(tfm)->__crt_alg->cra_ahash; | ||
327 | } | ||
328 | |||
329 | static inline int ahash_enqueue_request(struct crypto_queue *queue, | ||
330 | struct ahash_request *request) | ||
331 | { | ||
332 | return crypto_enqueue_request(queue, &request->base); | ||
333 | } | ||
334 | |||
335 | static inline struct ahash_request *ahash_dequeue_request( | ||
336 | struct crypto_queue *queue) | ||
337 | { | ||
338 | return ahash_request_cast(crypto_dequeue_request(queue)); | ||
339 | } | ||
340 | |||
341 | static inline void *ahash_request_ctx(struct ahash_request *req) | ||
342 | { | ||
343 | return req->__ctx; | ||
344 | } | ||
345 | |||
346 | static inline int ahash_tfm_in_queue(struct crypto_queue *queue, | ||
347 | struct crypto_ahash *tfm) | ||
348 | { | ||
349 | return crypto_tfm_in_queue(queue, crypto_ahash_tfm(tfm)); | ||
350 | } | ||
351 | |||
352 | |||
317 | #endif /* _CRYPTO_ALGAPI_H */ | 353 | #endif /* _CRYPTO_ALGAPI_H */ |
318 | 354 | ||
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 425824bd49f3..b6efe569128d 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -30,15 +30,17 @@ | |||
30 | */ | 30 | */ |
31 | #define CRYPTO_ALG_TYPE_MASK 0x0000000f | 31 | #define CRYPTO_ALG_TYPE_MASK 0x0000000f |
32 | #define CRYPTO_ALG_TYPE_CIPHER 0x00000001 | 32 | #define CRYPTO_ALG_TYPE_CIPHER 0x00000001 |
33 | #define CRYPTO_ALG_TYPE_DIGEST 0x00000002 | 33 | #define CRYPTO_ALG_TYPE_COMPRESS 0x00000002 |
34 | #define CRYPTO_ALG_TYPE_HASH 0x00000003 | 34 | #define CRYPTO_ALG_TYPE_AEAD 0x00000003 |
35 | #define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004 | 35 | #define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004 |
36 | #define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005 | 36 | #define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005 |
37 | #define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006 | 37 | #define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006 |
38 | #define CRYPTO_ALG_TYPE_COMPRESS 0x00000008 | 38 | #define CRYPTO_ALG_TYPE_DIGEST 0x00000008 |
39 | #define CRYPTO_ALG_TYPE_AEAD 0x00000009 | 39 | #define CRYPTO_ALG_TYPE_HASH 0x00000009 |
40 | #define CRYPTO_ALG_TYPE_AHASH 0x0000000a | ||
40 | 41 | ||
41 | #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e | 42 | #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e |
43 | #define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000c | ||
42 | #define CRYPTO_ALG_TYPE_BLKCIPHER_MASK 0x0000000c | 44 | #define CRYPTO_ALG_TYPE_BLKCIPHER_MASK 0x0000000c |
43 | 45 | ||
44 | #define CRYPTO_ALG_LARVAL 0x00000010 | 46 | #define CRYPTO_ALG_LARVAL 0x00000010 |
@@ -102,6 +104,7 @@ struct crypto_async_request; | |||
102 | struct crypto_aead; | 104 | struct crypto_aead; |
103 | struct crypto_blkcipher; | 105 | struct crypto_blkcipher; |
104 | struct crypto_hash; | 106 | struct crypto_hash; |
107 | struct crypto_ahash; | ||
105 | struct crypto_tfm; | 108 | struct crypto_tfm; |
106 | struct crypto_type; | 109 | struct crypto_type; |
107 | struct aead_givcrypt_request; | 110 | struct aead_givcrypt_request; |
@@ -131,6 +134,18 @@ struct ablkcipher_request { | |||
131 | void *__ctx[] CRYPTO_MINALIGN_ATTR; | 134 | void *__ctx[] CRYPTO_MINALIGN_ATTR; |
132 | }; | 135 | }; |
133 | 136 | ||
137 | struct ahash_request { | ||
138 | struct crypto_async_request base; | ||
139 | |||
140 | void *info; | ||
141 | |||
142 | unsigned int nbytes; | ||
143 | struct scatterlist *src; | ||
144 | u8 *result; | ||
145 | |||
146 | void *__ctx[] CRYPTO_MINALIGN_ATTR; | ||
147 | }; | ||
148 | |||
134 | /** | 149 | /** |
135 | * struct aead_request - AEAD request | 150 | * struct aead_request - AEAD request |
136 | * @base: Common attributes for async crypto requests | 151 | * @base: Common attributes for async crypto requests |
@@ -195,6 +210,17 @@ struct ablkcipher_alg { | |||
195 | unsigned int ivsize; | 210 | unsigned int ivsize; |
196 | }; | 211 | }; |
197 | 212 | ||
213 | struct ahash_alg { | ||
214 | int (*init)(struct ahash_request *req); | ||
215 | int (*update)(struct ahash_request *req); | ||
216 | int (*final)(struct ahash_request *req); | ||
217 | int (*digest)(struct ahash_request *req); | ||
218 | int (*setkey)(struct crypto_ahash *tfm, const u8 *key, | ||
219 | unsigned int keylen); | ||
220 | |||
221 | unsigned int digestsize; | ||
222 | }; | ||
223 | |||
198 | struct aead_alg { | 224 | struct aead_alg { |
199 | int (*setkey)(struct crypto_aead *tfm, const u8 *key, | 225 | int (*setkey)(struct crypto_aead *tfm, const u8 *key, |
200 | unsigned int keylen); | 226 | unsigned int keylen); |
@@ -272,6 +298,7 @@ struct compress_alg { | |||
272 | #define cra_cipher cra_u.cipher | 298 | #define cra_cipher cra_u.cipher |
273 | #define cra_digest cra_u.digest | 299 | #define cra_digest cra_u.digest |
274 | #define cra_hash cra_u.hash | 300 | #define cra_hash cra_u.hash |
301 | #define cra_ahash cra_u.ahash | ||
275 | #define cra_compress cra_u.compress | 302 | #define cra_compress cra_u.compress |
276 | 303 | ||
277 | struct crypto_alg { | 304 | struct crypto_alg { |
@@ -298,6 +325,7 @@ struct crypto_alg { | |||
298 | struct cipher_alg cipher; | 325 | struct cipher_alg cipher; |
299 | struct digest_alg digest; | 326 | struct digest_alg digest; |
300 | struct hash_alg hash; | 327 | struct hash_alg hash; |
328 | struct ahash_alg ahash; | ||
301 | struct compress_alg compress; | 329 | struct compress_alg compress; |
302 | } cra_u; | 330 | } cra_u; |
303 | 331 | ||
@@ -383,6 +411,19 @@ struct hash_tfm { | |||
383 | unsigned int digestsize; | 411 | unsigned int digestsize; |
384 | }; | 412 | }; |
385 | 413 | ||
414 | struct ahash_tfm { | ||
415 | int (*init)(struct ahash_request *req); | ||
416 | int (*update)(struct ahash_request *req); | ||
417 | int (*final)(struct ahash_request *req); | ||
418 | int (*digest)(struct ahash_request *req); | ||
419 | int (*setkey)(struct crypto_ahash *tfm, const u8 *key, | ||
420 | unsigned int keylen); | ||
421 | |||
422 | unsigned int digestsize; | ||
423 | struct crypto_ahash *base; | ||
424 | unsigned int reqsize; | ||
425 | }; | ||
426 | |||
386 | struct compress_tfm { | 427 | struct compress_tfm { |
387 | int (*cot_compress)(struct crypto_tfm *tfm, | 428 | int (*cot_compress)(struct crypto_tfm *tfm, |
388 | const u8 *src, unsigned int slen, | 429 | const u8 *src, unsigned int slen, |
@@ -397,6 +438,7 @@ struct compress_tfm { | |||
397 | #define crt_blkcipher crt_u.blkcipher | 438 | #define crt_blkcipher crt_u.blkcipher |
398 | #define crt_cipher crt_u.cipher | 439 | #define crt_cipher crt_u.cipher |
399 | #define crt_hash crt_u.hash | 440 | #define crt_hash crt_u.hash |
441 | #define crt_ahash crt_u.ahash | ||
400 | #define crt_compress crt_u.compress | 442 | #define crt_compress crt_u.compress |
401 | 443 | ||
402 | struct crypto_tfm { | 444 | struct crypto_tfm { |
@@ -409,6 +451,7 @@ struct crypto_tfm { | |||
409 | struct blkcipher_tfm blkcipher; | 451 | struct blkcipher_tfm blkcipher; |
410 | struct cipher_tfm cipher; | 452 | struct cipher_tfm cipher; |
411 | struct hash_tfm hash; | 453 | struct hash_tfm hash; |
454 | struct ahash_tfm ahash; | ||
412 | struct compress_tfm compress; | 455 | struct compress_tfm compress; |
413 | } crt_u; | 456 | } crt_u; |
414 | 457 | ||
@@ -441,6 +484,10 @@ struct crypto_hash { | |||
441 | struct crypto_tfm base; | 484 | struct crypto_tfm base; |
442 | }; | 485 | }; |
443 | 486 | ||
487 | struct crypto_ahash { | ||
488 | struct crypto_tfm base; | ||
489 | }; | ||
490 | |||
444 | enum { | 491 | enum { |
445 | CRYPTOA_UNSPEC, | 492 | CRYPTOA_UNSPEC, |
446 | CRYPTOA_ALG, | 493 | CRYPTOA_ALG, |
@@ -1264,5 +1311,137 @@ static inline int crypto_comp_decompress(struct crypto_comp *tfm, | |||
1264 | src, slen, dst, dlen); | 1311 | src, slen, dst, dlen); |
1265 | } | 1312 | } |
1266 | 1313 | ||
1314 | static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) | ||
1315 | { | ||
1316 | return (struct crypto_ahash *)tfm; | ||
1317 | } | ||
1318 | |||
1319 | static inline struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, | ||
1320 | u32 type, u32 mask) | ||
1321 | { | ||
1322 | type &= ~CRYPTO_ALG_TYPE_MASK; | ||
1323 | mask &= ~CRYPTO_ALG_TYPE_MASK; | ||
1324 | type |= CRYPTO_ALG_TYPE_AHASH; | ||
1325 | mask |= CRYPTO_ALG_TYPE_AHASH_MASK; | ||
1326 | |||
1327 | return __crypto_ahash_cast(crypto_alloc_base(alg_name, type, mask)); | ||
1328 | } | ||
1329 | |||
1330 | static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm) | ||
1331 | { | ||
1332 | return &tfm->base; | ||
1333 | } | ||
1334 | |||
1335 | static inline void crypto_free_ahash(struct crypto_ahash *tfm) | ||
1336 | { | ||
1337 | crypto_free_tfm(crypto_ahash_tfm(tfm)); | ||
1338 | } | ||
1339 | |||
1340 | static inline unsigned int crypto_ahash_alignmask( | ||
1341 | struct crypto_ahash *tfm) | ||
1342 | { | ||
1343 | return crypto_tfm_alg_alignmask(crypto_ahash_tfm(tfm)); | ||
1344 | } | ||
1345 | |||
1346 | static inline struct ahash_tfm *crypto_ahash_crt(struct crypto_ahash *tfm) | ||
1347 | { | ||
1348 | return &crypto_ahash_tfm(tfm)->crt_ahash; | ||
1349 | } | ||
1350 | |||
1351 | static inline unsigned int crypto_ahash_digestsize(struct crypto_ahash *tfm) | ||
1352 | { | ||
1353 | return crypto_ahash_crt(tfm)->digestsize; | ||
1354 | } | ||
1355 | |||
1356 | static inline u32 crypto_ahash_get_flags(struct crypto_ahash *tfm) | ||
1357 | { | ||
1358 | return crypto_tfm_get_flags(crypto_ahash_tfm(tfm)); | ||
1359 | } | ||
1360 | |||
1361 | static inline void crypto_ahash_set_flags(struct crypto_ahash *tfm, u32 flags) | ||
1362 | { | ||
1363 | crypto_tfm_set_flags(crypto_ahash_tfm(tfm), flags); | ||
1364 | } | ||
1365 | |||
1366 | static inline void crypto_ahash_clear_flags(struct crypto_ahash *tfm, u32 flags) | ||
1367 | { | ||
1368 | crypto_tfm_clear_flags(crypto_ahash_tfm(tfm), flags); | ||
1369 | } | ||
1370 | |||
1371 | static inline struct crypto_ahash *crypto_ahash_reqtfm( | ||
1372 | struct ahash_request *req) | ||
1373 | { | ||
1374 | return __crypto_ahash_cast(req->base.tfm); | ||
1375 | } | ||
1376 | |||
1377 | static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm) | ||
1378 | { | ||
1379 | return crypto_ahash_crt(tfm)->reqsize; | ||
1380 | } | ||
1381 | |||
1382 | static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, | ||
1383 | const u8 *key, unsigned int keylen) | ||
1384 | { | ||
1385 | struct ahash_tfm *crt = crypto_ahash_crt(tfm); | ||
1386 | |||
1387 | return crt->setkey(crt->base, key, keylen); | ||
1388 | } | ||
1389 | |||
1390 | static inline int crypto_ahash_digest(struct ahash_request *req) | ||
1391 | { | ||
1392 | struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); | ||
1393 | return crt->digest(req); | ||
1394 | } | ||
1395 | |||
1396 | static inline void ahash_request_set_tfm(struct ahash_request *req, | ||
1397 | struct crypto_ahash *tfm) | ||
1398 | { | ||
1399 | req->base.tfm = crypto_ahash_tfm(crypto_ahash_crt(tfm)->base); | ||
1400 | } | ||
1401 | |||
1402 | static inline struct ahash_request *ahash_request_alloc( | ||
1403 | struct crypto_ahash *tfm, gfp_t gfp) | ||
1404 | { | ||
1405 | struct ahash_request *req; | ||
1406 | |||
1407 | req = kmalloc(sizeof(struct ahash_request) + | ||
1408 | crypto_ahash_reqsize(tfm), gfp); | ||
1409 | |||
1410 | if (likely(req)) | ||
1411 | ahash_request_set_tfm(req, tfm); | ||
1412 | |||
1413 | return req; | ||
1414 | } | ||
1415 | |||
1416 | static inline void ahash_request_free(struct ahash_request *req) | ||
1417 | { | ||
1418 | kfree(req); | ||
1419 | } | ||
1420 | |||
1421 | static inline struct ahash_request *ahash_request_cast( | ||
1422 | struct crypto_async_request *req) | ||
1423 | { | ||
1424 | return container_of(req, struct ahash_request, base); | ||
1425 | } | ||
1426 | |||
1427 | static inline void ahash_request_set_callback(struct ahash_request *req, | ||
1428 | u32 flags, | ||
1429 | crypto_completion_t complete, | ||
1430 | void *data) | ||
1431 | { | ||
1432 | req->base.complete = complete; | ||
1433 | req->base.data = data; | ||
1434 | req->base.flags = flags; | ||
1435 | } | ||
1436 | |||
1437 | static inline void ahash_request_set_crypt(struct ahash_request *req, | ||
1438 | struct scatterlist *src, u8 *result, | ||
1439 | unsigned int nbytes) | ||
1440 | { | ||
1441 | req->src = src; | ||
1442 | req->nbytes = nbytes; | ||
1443 | req->result = result; | ||
1444 | } | ||
1445 | |||
1267 | #endif /* _LINUX_CRYPTO_H */ | 1446 | #endif /* _LINUX_CRYPTO_H */ |
1268 | 1447 | ||