From e1147d8f47eb8fef93f98a30858192145137d2b2 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 10 Apr 2006 08:42:35 +1000 Subject: [CRYPTO] digest: Add alignment handling Some hash modules load/store data words directly. The digest layer should pass properly aligned buffer to update()/final() method. This patch also add cra_alignmask to some hash modules. Signed-off-by: Atsushi Nemoto Signed-off-by: Herbert Xu --- crypto/digest.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'crypto/digest.c') diff --git a/crypto/digest.c b/crypto/digest.c index d9b6ac9..062d0a5 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -27,6 +27,7 @@ static void update(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg) { unsigned int i; + unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); for (i = 0; i < nsg; i++) { @@ -38,12 +39,24 @@ static void update(struct crypto_tfm *tfm, unsigned int bytes_from_page = min(l, ((unsigned int) (PAGE_SIZE)) - offset); - char *p = crypto_kmap(pg, 0) + offset; + char *src = crypto_kmap(pg, 0); + char *p = src + offset; + if (unlikely(offset & alignmask)) { + unsigned int bytes = + alignmask + 1 - (offset & alignmask); + bytes = min(bytes, bytes_from_page); + tfm->__crt_alg->cra_digest.dia_update + (crypto_tfm_ctx(tfm), p, + bytes); + p += bytes; + bytes_from_page -= bytes; + l -= bytes; + } tfm->__crt_alg->cra_digest.dia_update (crypto_tfm_ctx(tfm), p, bytes_from_page); - crypto_kunmap(p, 0); + crypto_kunmap(src, 0); crypto_yield(tfm); offset = 0; pg++; @@ -54,7 +67,15 @@ static void update(struct crypto_tfm *tfm, static void final(struct crypto_tfm *tfm, u8 *out) { - tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); + unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); + if (unlikely((unsigned long)out & alignmask)) { + unsigned int size = crypto_tfm_alg_digestsize(tfm); + u8 buffer[size + alignmask]; + u8 *dst = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), dst); + memcpy(out, dst, size); + } else + tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); } static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) @@ -69,18 +90,9 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) static void digest(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out) { - unsigned int i; - - tfm->crt_digest.dit_init(tfm); - - for (i = 0; i < nsg; i++) { - char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; - tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), - p, sg[i].length); - crypto_kunmap(p, 0); - crypto_yield(tfm); - } - crypto_digest_final(tfm, out); + init(tfm); + update(tfm, sg, nsg); + final(tfm, out); } int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) -- cgit v1.1 From 6c2bb98bc33ae33c7a33a133a4cd5a06395fece5 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 16 May 2006 22:09:29 +1000 Subject: [CRYPTO] all: Pass tfm instead of ctx to algorithms Up until now algorithms have been happy to get a context pointer since they know everything that's in the tfm already (e.g., alignment, block size). However, once we have parameterised algorithms, such information will be specific to each tfm. So the algorithm API needs to be changed to pass the tfm structure instead of the context pointer. This patch is basically a text substitution. The only tricky bit is the assembly routines that need to get the context pointer offset through asm-offsets.h. Signed-off-by: Herbert Xu --- crypto/digest.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'crypto/digest.c') diff --git a/crypto/digest.c b/crypto/digest.c index 062d0a5..2d9d509 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -20,7 +20,7 @@ static void init(struct crypto_tfm *tfm) { - tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm)); + tfm->__crt_alg->cra_digest.dia_init(tfm); } static void update(struct crypto_tfm *tfm, @@ -46,16 +46,14 @@ static void update(struct crypto_tfm *tfm, unsigned int bytes = alignmask + 1 - (offset & alignmask); bytes = min(bytes, bytes_from_page); - tfm->__crt_alg->cra_digest.dia_update - (crypto_tfm_ctx(tfm), p, - bytes); + tfm->__crt_alg->cra_digest.dia_update(tfm, p, + bytes); p += bytes; bytes_from_page -= bytes; l -= bytes; } - tfm->__crt_alg->cra_digest.dia_update - (crypto_tfm_ctx(tfm), p, - bytes_from_page); + tfm->__crt_alg->cra_digest.dia_update(tfm, p, + bytes_from_page); crypto_kunmap(src, 0); crypto_yield(tfm); offset = 0; @@ -83,8 +81,7 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) u32 flags; if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) return -ENOSYS; - return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), - key, keylen, &flags); + return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen, &flags); } static void digest(struct crypto_tfm *tfm, -- cgit v1.1 From 110bf1c0e932615cbe43a8af8a07bc3750ae4295 Mon Sep 17 00:00:00 2001 From: Michal Ludvig Date: Mon, 22 May 2006 08:28:06 +1000 Subject: [CRYPTO] api: Fixed incorrect passing of context instead of tfm Fix a few omissions in passing TFM instead of CTX to algorithms. Signed-off-by: Michal Ludvig Signed-off-by: Herbert Xu --- crypto/digest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crypto/digest.c') diff --git a/crypto/digest.c b/crypto/digest.c index 2d9d509..603006a 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -70,10 +70,10 @@ static void final(struct crypto_tfm *tfm, u8 *out) unsigned int size = crypto_tfm_alg_digestsize(tfm); u8 buffer[size + alignmask]; u8 *dst = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); - tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), dst); + tfm->__crt_alg->cra_digest.dia_final(tfm, dst); memcpy(out, dst, size); } else - tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); + tfm->__crt_alg->cra_digest.dia_final(tfm, out); } static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) -- cgit v1.1