aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/digest.c
diff options
context:
space:
mode:
authorLoc Ho <lho@amcc.com>2008-05-14 08:41:47 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-07-10 08:35:13 -0400
commit004a403c2e954734090a69aedc7f4f822bdcc142 (patch)
treee8fadd76113132126e308e01e7cd7cdf6b9d44d6 /crypto/digest.c
parent534fe2c1c3ffbbc3db66dba0783c82d3b345fd33 (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.c81
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)
157void crypto_exit_digest_ops(struct crypto_tfm *tfm) 157void crypto_exit_digest_ops(struct crypto_tfm *tfm)
158{ 158{
159} 159}
160
161static 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
168static 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
178static 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
187static 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
199static 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
211static 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
222int 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}