diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/digest.c | 16 | ||||
-rw-r--r-- | crypto/internal.h | 9 |
2 files changed, 18 insertions, 7 deletions
diff --git a/crypto/digest.c b/crypto/digest.c index 0df7f392a56a..19e75563776b 100644 --- a/crypto/digest.c +++ b/crypto/digest.c | |||
@@ -66,14 +66,18 @@ static void update(struct crypto_tfm *tfm, | |||
66 | static void final(struct crypto_tfm *tfm, u8 *out) | 66 | static void final(struct crypto_tfm *tfm, u8 *out) |
67 | { | 67 | { |
68 | unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | 68 | unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); |
69 | struct digest_alg *digest = &tfm->__crt_alg->cra_digest; | ||
70 | |||
69 | if (unlikely((unsigned long)out & alignmask)) { | 71 | if (unlikely((unsigned long)out & alignmask)) { |
70 | unsigned int size = crypto_tfm_alg_digestsize(tfm); | 72 | unsigned long align = alignmask + 1; |
71 | u8 buffer[size + alignmask]; | 73 | unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm); |
72 | u8 *dst = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | 74 | u8 *dst = (u8 *)ALIGN(addr, align) + |
73 | tfm->__crt_alg->cra_digest.dia_final(tfm, dst); | 75 | ALIGN(tfm->__crt_alg->cra_ctxsize, align); |
74 | memcpy(out, dst, size); | 76 | |
77 | digest->dia_final(tfm, dst); | ||
78 | memcpy(out, dst, digest->dia_digestsize); | ||
75 | } else | 79 | } else |
76 | tfm->__crt_alg->cra_digest.dia_final(tfm, out); | 80 | digest->dia_final(tfm, out); |
77 | } | 81 | } |
78 | 82 | ||
79 | static int nosetkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) | 83 | static int nosetkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) |
diff --git a/crypto/internal.h b/crypto/internal.h index 03c00b0e6b60..b110b979b988 100644 --- a/crypto/internal.h +++ b/crypto/internal.h | |||
@@ -99,7 +99,14 @@ static inline void crypto_exit_proc(void) | |||
99 | static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, | 99 | static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, |
100 | int flags) | 100 | int flags) |
101 | { | 101 | { |
102 | return alg->cra_ctxsize; | 102 | unsigned int len = alg->cra_ctxsize; |
103 | |||
104 | if (alg->cra_alignmask) { | ||
105 | len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1); | ||
106 | len += alg->cra_digest.dia_digestsize; | ||
107 | } | ||
108 | |||
109 | return len; | ||
103 | } | 110 | } |
104 | 111 | ||
105 | static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, | 112 | static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, |