diff options
-rw-r--r-- | crypto/ahash.c | 16 | ||||
-rw-r--r-- | crypto/authenc.c | 3 | ||||
-rw-r--r-- | crypto/hmac.c | 10 | ||||
-rw-r--r-- | crypto/shash.c | 109 | ||||
-rw-r--r-- | include/crypto/algapi.h | 5 | ||||
-rw-r--r-- | include/crypto/internal/hash.h | 3 | ||||
-rw-r--r-- | include/linux/crypto.h | 4 |
7 files changed, 144 insertions, 6 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c index 7d4e33dfe212..9f98956b17fc 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
@@ -112,6 +112,22 @@ int crypto_hash_walk_first(struct ahash_request *req, | |||
112 | } | 112 | } |
113 | EXPORT_SYMBOL_GPL(crypto_hash_walk_first); | 113 | EXPORT_SYMBOL_GPL(crypto_hash_walk_first); |
114 | 114 | ||
115 | int crypto_hash_walk_first_compat(struct hash_desc *hdesc, | ||
116 | struct crypto_hash_walk *walk, | ||
117 | struct scatterlist *sg, unsigned int len) | ||
118 | { | ||
119 | walk->total = len; | ||
120 | |||
121 | if (!walk->total) | ||
122 | return 0; | ||
123 | |||
124 | walk->alignmask = crypto_hash_alignmask(hdesc->tfm); | ||
125 | walk->sg = sg; | ||
126 | walk->flags = hdesc->flags; | ||
127 | |||
128 | return hash_walk_new_entry(walk); | ||
129 | } | ||
130 | |||
115 | static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, | 131 | static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, |
116 | unsigned int keylen) | 132 | unsigned int keylen) |
117 | { | 133 | { |
diff --git a/crypto/authenc.c b/crypto/authenc.c index fd9f06c63d76..40b6e9ec9e3a 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <crypto/aead.h> | 13 | #include <crypto/aead.h> |
14 | #include <crypto/internal/hash.h> | ||
14 | #include <crypto/internal/skcipher.h> | 15 | #include <crypto/internal/skcipher.h> |
15 | #include <crypto/authenc.h> | 16 | #include <crypto/authenc.h> |
16 | #include <crypto/scatterwalk.h> | 17 | #include <crypto/scatterwalk.h> |
@@ -431,6 +432,8 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
431 | inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize; | 432 | inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize; |
432 | inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ? | 433 | inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ? |
433 | auth->cra_hash.digestsize : | 434 | auth->cra_hash.digestsize : |
435 | auth->cra_type ? | ||
436 | __crypto_shash_alg(auth)->digestsize : | ||
434 | auth->cra_digest.dia_digestsize; | 437 | auth->cra_digest.dia_digestsize; |
435 | 438 | ||
436 | inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); | 439 | inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); |
diff --git a/crypto/hmac.c b/crypto/hmac.c index 7ff2d6a8c7d0..0ad39c374963 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <crypto/algapi.h> | 19 | #include <crypto/internal/hash.h> |
20 | #include <crypto/scatterwalk.h> | 20 | #include <crypto/scatterwalk.h> |
21 | #include <linux/err.h> | 21 | #include <linux/err.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
@@ -238,9 +238,11 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb) | |||
238 | return ERR_CAST(alg); | 238 | return ERR_CAST(alg); |
239 | 239 | ||
240 | inst = ERR_PTR(-EINVAL); | 240 | inst = ERR_PTR(-EINVAL); |
241 | ds = (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | 241 | ds = alg->cra_type == &crypto_hash_type ? |
242 | CRYPTO_ALG_TYPE_HASH ? alg->cra_hash.digestsize : | 242 | alg->cra_hash.digestsize : |
243 | alg->cra_digest.dia_digestsize; | 243 | alg->cra_type ? |
244 | __crypto_shash_alg(alg)->digestsize : | ||
245 | alg->cra_digest.dia_digestsize; | ||
244 | if (ds > alg->cra_blocksize) | 246 | if (ds > alg->cra_blocksize) |
245 | goto out_put_alg; | 247 | goto out_put_alg; |
246 | 248 | ||
diff --git a/crypto/shash.c b/crypto/shash.c index 26aff3feefc0..50d69a4e4b61 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
@@ -301,9 +301,114 @@ static int crypto_init_shash_ops_async(struct crypto_tfm *tfm) | |||
301 | return 0; | 301 | return 0; |
302 | } | 302 | } |
303 | 303 | ||
304 | static int shash_compat_setkey(struct crypto_hash *tfm, const u8 *key, | ||
305 | unsigned int keylen) | ||
306 | { | ||
307 | struct shash_desc *desc = crypto_hash_ctx(tfm); | ||
308 | |||
309 | return crypto_shash_setkey(desc->tfm, key, keylen); | ||
310 | } | ||
311 | |||
312 | static int shash_compat_init(struct hash_desc *hdesc) | ||
313 | { | ||
314 | struct shash_desc *desc = crypto_hash_ctx(hdesc->tfm); | ||
315 | |||
316 | desc->flags = hdesc->flags; | ||
317 | |||
318 | return crypto_shash_init(desc); | ||
319 | } | ||
320 | |||
321 | static int shash_compat_update(struct hash_desc *hdesc, struct scatterlist *sg, | ||
322 | unsigned int len) | ||
323 | { | ||
324 | struct shash_desc *desc = crypto_hash_ctx(hdesc->tfm); | ||
325 | struct crypto_hash_walk walk; | ||
326 | int nbytes; | ||
327 | |||
328 | for (nbytes = crypto_hash_walk_first_compat(hdesc, &walk, sg, len); | ||
329 | nbytes > 0; nbytes = crypto_hash_walk_done(&walk, nbytes)) | ||
330 | nbytes = crypto_shash_update(desc, walk.data, nbytes); | ||
331 | |||
332 | return nbytes; | ||
333 | } | ||
334 | |||
335 | static int shash_compat_final(struct hash_desc *hdesc, u8 *out) | ||
336 | { | ||
337 | return crypto_shash_final(crypto_hash_ctx(hdesc->tfm), out); | ||
338 | } | ||
339 | |||
340 | static int shash_compat_digest(struct hash_desc *hdesc, struct scatterlist *sg, | ||
341 | unsigned int nbytes, u8 *out) | ||
342 | { | ||
343 | unsigned int offset = sg->offset; | ||
344 | int err; | ||
345 | |||
346 | if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { | ||
347 | struct shash_desc *desc = crypto_hash_ctx(hdesc->tfm); | ||
348 | void *data; | ||
349 | |||
350 | desc->flags = hdesc->flags; | ||
351 | |||
352 | data = crypto_kmap(sg_page(sg), 0); | ||
353 | err = crypto_shash_digest(desc, data + offset, nbytes, out); | ||
354 | crypto_kunmap(data, 0); | ||
355 | crypto_yield(desc->flags); | ||
356 | goto out; | ||
357 | } | ||
358 | |||
359 | err = shash_compat_init(hdesc); | ||
360 | if (err) | ||
361 | goto out; | ||
362 | |||
363 | err = shash_compat_update(hdesc, sg, nbytes); | ||
364 | if (err) | ||
365 | goto out; | ||
366 | |||
367 | err = shash_compat_final(hdesc, out); | ||
368 | |||
369 | out: | ||
370 | return err; | ||
371 | } | ||
372 | |||
373 | static void crypto_exit_shash_ops_compat(struct crypto_tfm *tfm) | ||
374 | { | ||
375 | struct shash_desc *desc= crypto_tfm_ctx(tfm); | ||
376 | |||
377 | crypto_free_shash(desc->tfm); | ||
378 | } | ||
379 | |||
380 | static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm) | ||
381 | { | ||
382 | struct hash_tfm *crt = &tfm->crt_hash; | ||
383 | struct crypto_alg *calg = tfm->__crt_alg; | ||
384 | struct shash_alg *alg = __crypto_shash_alg(calg); | ||
385 | struct shash_desc *desc = crypto_tfm_ctx(tfm); | ||
386 | struct crypto_shash *shash; | ||
387 | |||
388 | shash = __crypto_shash_cast(crypto_create_tfm( | ||
389 | calg, &crypto_shash_type)); | ||
390 | if (IS_ERR(shash)) | ||
391 | return PTR_ERR(shash); | ||
392 | |||
393 | desc->tfm = shash; | ||
394 | tfm->exit = crypto_exit_shash_ops_compat; | ||
395 | |||
396 | crt->init = shash_compat_init; | ||
397 | crt->update = shash_compat_update; | ||
398 | crt->final = shash_compat_final; | ||
399 | crt->digest = shash_compat_digest; | ||
400 | crt->setkey = shash_compat_setkey; | ||
401 | |||
402 | crt->digestsize = alg->digestsize; | ||
403 | |||
404 | return 0; | ||
405 | } | ||
406 | |||
304 | static int crypto_init_shash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | 407 | static int crypto_init_shash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) |
305 | { | 408 | { |
306 | switch (mask & CRYPTO_ALG_TYPE_MASK) { | 409 | switch (mask & CRYPTO_ALG_TYPE_MASK) { |
410 | case CRYPTO_ALG_TYPE_HASH_MASK: | ||
411 | return crypto_init_shash_ops_compat(tfm); | ||
307 | case CRYPTO_ALG_TYPE_AHASH_MASK: | 412 | case CRYPTO_ALG_TYPE_AHASH_MASK: |
308 | return crypto_init_shash_ops_async(tfm); | 413 | return crypto_init_shash_ops_async(tfm); |
309 | } | 414 | } |
@@ -314,7 +419,11 @@ static int crypto_init_shash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
314 | static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type, | 419 | static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type, |
315 | u32 mask) | 420 | u32 mask) |
316 | { | 421 | { |
422 | struct shash_alg *salg = __crypto_shash_alg(alg); | ||
423 | |||
317 | switch (mask & CRYPTO_ALG_TYPE_MASK) { | 424 | switch (mask & CRYPTO_ALG_TYPE_MASK) { |
425 | case CRYPTO_ALG_TYPE_HASH_MASK: | ||
426 | return sizeof(struct shash_desc) + salg->descsize; | ||
318 | case CRYPTO_ALG_TYPE_AHASH_MASK: | 427 | case CRYPTO_ALG_TYPE_AHASH_MASK: |
319 | return sizeof(struct crypto_shash *); | 428 | return sizeof(struct crypto_shash *); |
320 | } | 429 | } |
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 986db68548f6..010545436efa 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h | |||
@@ -248,6 +248,11 @@ static inline struct crypto_hash *crypto_spawn_hash(struct crypto_spawn *spawn) | |||
248 | return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask)); | 248 | return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask)); |
249 | } | 249 | } |
250 | 250 | ||
251 | static inline void *crypto_hash_ctx(struct crypto_hash *tfm) | ||
252 | { | ||
253 | return crypto_tfm_ctx(&tfm->base); | ||
254 | } | ||
255 | |||
251 | static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm) | 256 | static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm) |
252 | { | 257 | { |
253 | return crypto_tfm_ctx_aligned(&tfm->base); | 258 | return crypto_tfm_ctx_aligned(&tfm->base); |
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 92fbe7385856..82b70564bcab 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h | |||
@@ -39,6 +39,9 @@ extern const struct crypto_type crypto_ahash_type; | |||
39 | int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err); | 39 | int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err); |
40 | int crypto_hash_walk_first(struct ahash_request *req, | 40 | int crypto_hash_walk_first(struct ahash_request *req, |
41 | struct crypto_hash_walk *walk); | 41 | struct crypto_hash_walk *walk); |
42 | int crypto_hash_walk_first_compat(struct hash_desc *hdesc, | ||
43 | struct crypto_hash_walk *walk, | ||
44 | struct scatterlist *sg, unsigned int len); | ||
42 | 45 | ||
43 | int crypto_register_shash(struct shash_alg *alg); | 46 | int crypto_register_shash(struct shash_alg *alg); |
44 | int crypto_unregister_shash(struct shash_alg *alg); | 47 | int crypto_unregister_shash(struct shash_alg *alg); |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 77a1f3d9416d..3bacd71509fb 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -36,9 +36,9 @@ | |||
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_DIGEST 0x00000008 | 38 | #define CRYPTO_ALG_TYPE_DIGEST 0x00000008 |
39 | #define CRYPTO_ALG_TYPE_HASH 0x00000009 | 39 | #define CRYPTO_ALG_TYPE_HASH 0x00000008 |
40 | #define CRYPTO_ALG_TYPE_SHASH 0x00000009 | ||
40 | #define CRYPTO_ALG_TYPE_AHASH 0x0000000a | 41 | #define CRYPTO_ALG_TYPE_AHASH 0x0000000a |
41 | #define CRYPTO_ALG_TYPE_SHASH 0x0000000b | ||
42 | #define CRYPTO_ALG_TYPE_RNG 0x0000000c | 42 | #define CRYPTO_ALG_TYPE_RNG 0x0000000c |
43 | 43 | ||
44 | #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e | 44 | #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e |