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/digest.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/digest.c')
-rw-r--r-- | crypto/digest.c | 81 |
1 files changed, 81 insertions, 0 deletions
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 | } | ||