summaryrefslogtreecommitdiff
path: root/crypto/digest.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-18 13:39:39 +0400
committerDavid S. Miller <davem@davemloft.net>2008-07-18 13:39:39 +0400
commit49997d75152b3d23c53b0fa730599f2f74c92c65 (patch)
tree46e93126170d02cfec9505172e545732c1b69656 /crypto/digest.c
parenta0c80b80e0fb48129e4e9d6a9ede914f9ff1850d (diff)
parent5b664cb235e97afbf34db9c4d77f08ebd725335e (diff)
downloadlinux-49997d75152b3d23c53b0fa730599f2f74c92c65.tar.xz
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: Documentation/powerpc/booting-without-of.txt drivers/atm/Makefile drivers/net/fs_enet/fs_enet-main.c drivers/pci/pci-acpi.c net/8021q/vlan.c net/iucv/iucv.c
Diffstat (limited to 'crypto/digest.c')
-rw-r--r--crypto/digest.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/crypto/digest.c b/crypto/digest.c
index b526cc348b79..ac0919460d14 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -12,6 +12,7 @@
*
*/
+#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <linux/mm.h>
#include <linux/errno.h>
@@ -141,7 +142,7 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm)
struct hash_tfm *ops = &tfm->crt_hash;
struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
- if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm))
+ if (dalg->dia_digestsize > PAGE_SIZE / 8)
return -EINVAL;
ops->init = init;
@@ -157,3 +158,83 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm)
void crypto_exit_digest_ops(struct crypto_tfm *tfm)
{
}
+
+static int digest_async_nosetkey(struct crypto_ahash *tfm_async, const u8 *key,
+ unsigned int keylen)
+{
+ crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
+ return -ENOSYS;
+}
+
+static int digest_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async);
+ struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
+
+ crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
+ return dalg->dia_setkey(tfm, key, keylen);
+}
+
+static int digest_async_init(struct ahash_request *req)
+{
+ struct crypto_tfm *tfm = req->base.tfm;
+ struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
+
+ dalg->dia_init(tfm);
+ return 0;
+}
+
+static int digest_async_update(struct ahash_request *req)
+{
+ struct crypto_tfm *tfm = req->base.tfm;
+ struct hash_desc desc = {
+ .tfm = __crypto_hash_cast(tfm),
+ .flags = req->base.flags,
+ };
+
+ update(&desc, req->src, req->nbytes);
+ return 0;
+}
+
+static int digest_async_final(struct ahash_request *req)
+{
+ struct crypto_tfm *tfm = req->base.tfm;
+ struct hash_desc desc = {
+ .tfm = __crypto_hash_cast(tfm),
+ .flags = req->base.flags,
+ };
+
+ final(&desc, req->result);
+ return 0;
+}
+
+static int digest_async_digest(struct ahash_request *req)
+{
+ struct crypto_tfm *tfm = req->base.tfm;
+ struct hash_desc desc = {
+ .tfm = __crypto_hash_cast(tfm),
+ .flags = req->base.flags,
+ };
+
+ return digest(&desc, req->src, req->nbytes, req->result);
+}
+
+int crypto_init_digest_ops_async(struct crypto_tfm *tfm)
+{
+ struct ahash_tfm *crt = &tfm->crt_ahash;
+ struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
+
+ if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm))
+ return -EINVAL;
+
+ crt->init = digest_async_init;
+ crt->update = digest_async_update;
+ crt->final = digest_async_final;
+ crt->digest = digest_async_digest;
+ crt->setkey = dalg->dia_setkey ? digest_async_setkey :
+ digest_async_nosetkey;
+ crt->digestsize = dalg->dia_digestsize;
+
+ return 0;
+}