aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/digest.c16
-rw-r--r--crypto/internal.h9
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,
66static void final(struct crypto_tfm *tfm, u8 *out) 66static 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
79static int nosetkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) 83static 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)
99static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, 99static 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
105static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, 112static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg,