diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-07-15 00:40:40 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-07-15 00:40:40 -0400 |
commit | 66f6ce5e52f2f209d5bf1f06167cec888f4f4c13 (patch) | |
tree | aa7b21af00649d2f458b72ebfba071816cb340c3 /crypto/shash.c | |
parent | 093900c2b964da73daf234374225b5ce5d49f941 (diff) |
crypto: ahash - Add unaligned handling and default operations
This patch exports the finup operation where available and adds
a default finup operation for ahash. The operations final, finup
and digest also will now deal with unaligned result pointers by
copying it. Finally export/import operations are will now be
exported too.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/shash.c')
-rw-r--r-- | crypto/shash.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/crypto/shash.c b/crypto/shash.c index 171c8f052f89..834d9d24cdae 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
@@ -235,6 +235,33 @@ static int shash_async_final(struct ahash_request *req) | |||
235 | return crypto_shash_final(ahash_request_ctx(req), req->result); | 235 | return crypto_shash_final(ahash_request_ctx(req), req->result); |
236 | } | 236 | } |
237 | 237 | ||
238 | int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc) | ||
239 | { | ||
240 | struct crypto_hash_walk walk; | ||
241 | int nbytes; | ||
242 | |||
243 | for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0; | ||
244 | nbytes = crypto_hash_walk_done(&walk, nbytes)) | ||
245 | nbytes = crypto_hash_walk_last(&walk) ? | ||
246 | crypto_shash_finup(desc, walk.data, nbytes, | ||
247 | req->result) : | ||
248 | crypto_shash_update(desc, walk.data, nbytes); | ||
249 | |||
250 | return nbytes; | ||
251 | } | ||
252 | EXPORT_SYMBOL_GPL(shash_ahash_finup); | ||
253 | |||
254 | static int shash_async_finup(struct ahash_request *req) | ||
255 | { | ||
256 | struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); | ||
257 | struct shash_desc *desc = ahash_request_ctx(req); | ||
258 | |||
259 | desc->tfm = *ctx; | ||
260 | desc->flags = req->base.flags; | ||
261 | |||
262 | return shash_ahash_finup(req, desc); | ||
263 | } | ||
264 | |||
238 | int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) | 265 | int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) |
239 | { | 266 | { |
240 | struct scatterlist *sg = req->src; | 267 | struct scatterlist *sg = req->src; |
@@ -252,8 +279,7 @@ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) | |||
252 | crypto_yield(desc->flags); | 279 | crypto_yield(desc->flags); |
253 | } else | 280 | } else |
254 | err = crypto_shash_init(desc) ?: | 281 | err = crypto_shash_init(desc) ?: |
255 | shash_ahash_update(req, desc) ?: | 282 | shash_ahash_finup(req, desc); |
256 | crypto_shash_final(desc, req->result); | ||
257 | 283 | ||
258 | return err; | 284 | return err; |
259 | } | 285 | } |
@@ -270,6 +296,16 @@ static int shash_async_digest(struct ahash_request *req) | |||
270 | return shash_ahash_digest(req, desc); | 296 | return shash_ahash_digest(req, desc); |
271 | } | 297 | } |
272 | 298 | ||
299 | static int shash_async_export(struct ahash_request *req, void *out) | ||
300 | { | ||
301 | return crypto_shash_export(ahash_request_ctx(req), out); | ||
302 | } | ||
303 | |||
304 | static int shash_async_import(struct ahash_request *req, const void *in) | ||
305 | { | ||
306 | return crypto_shash_import(ahash_request_ctx(req), in); | ||
307 | } | ||
308 | |||
273 | static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) | 309 | static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) |
274 | { | 310 | { |
275 | struct crypto_shash **ctx = crypto_tfm_ctx(tfm); | 311 | struct crypto_shash **ctx = crypto_tfm_ctx(tfm); |
@@ -280,6 +316,7 @@ static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) | |||
280 | int crypto_init_shash_ops_async(struct crypto_tfm *tfm) | 316 | int crypto_init_shash_ops_async(struct crypto_tfm *tfm) |
281 | { | 317 | { |
282 | struct crypto_alg *calg = tfm->__crt_alg; | 318 | struct crypto_alg *calg = tfm->__crt_alg; |
319 | struct shash_alg *alg = __crypto_shash_alg(calg); | ||
283 | struct crypto_ahash *crt = __crypto_ahash_cast(tfm); | 320 | struct crypto_ahash *crt = __crypto_ahash_cast(tfm); |
284 | struct crypto_shash **ctx = crypto_tfm_ctx(tfm); | 321 | struct crypto_shash **ctx = crypto_tfm_ctx(tfm); |
285 | struct crypto_shash *shash; | 322 | struct crypto_shash *shash; |
@@ -298,9 +335,16 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm) | |||
298 | 335 | ||
299 | crt->init = shash_async_init; | 336 | crt->init = shash_async_init; |
300 | crt->update = shash_async_update; | 337 | crt->update = shash_async_update; |
301 | crt->final = shash_async_final; | 338 | crt->final = shash_async_final; |
339 | crt->finup = shash_async_finup; | ||
302 | crt->digest = shash_async_digest; | 340 | crt->digest = shash_async_digest; |
303 | crt->setkey = shash_async_setkey; | 341 | |
342 | if (alg->setkey) | ||
343 | crt->setkey = shash_async_setkey; | ||
344 | if (alg->export) | ||
345 | crt->export = shash_async_export; | ||
346 | if (alg->setkey) | ||
347 | crt->import = shash_async_import; | ||
304 | 348 | ||
305 | crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash); | 349 | crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash); |
306 | 350 | ||