diff options
author | Loc Ho <lho@amcc.com> | 2008-05-14 08:41:47 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-07-10 08:35:13 -0400 |
commit | 004a403c2e954734090a69aedc7f4f822bdcc142 (patch) | |
tree | e8fadd76113132126e308e01e7cd7cdf6b9d44d6 /crypto/hash.c | |
parent | 534fe2c1c3ffbbc3db66dba0783c82d3b345fd33 (diff) |
[CRYPTO] hash: Add asynchronous hash support
This patch adds asynchronous hash and digest support.
Signed-off-by: Loc Ho <lho@amcc.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/hash.c')
-rw-r--r-- | crypto/hash.c | 102 |
1 files changed, 93 insertions, 9 deletions
diff --git a/crypto/hash.c b/crypto/hash.c index 7dcff671c19b..f9400a014e74 100644 --- a/crypto/hash.c +++ b/crypto/hash.c | |||
@@ -59,24 +59,108 @@ static int hash_setkey(struct crypto_hash *crt, const u8 *key, | |||
59 | return alg->setkey(crt, key, keylen); | 59 | return alg->setkey(crt, key, keylen); |
60 | } | 60 | } |
61 | 61 | ||
62 | static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | 62 | static int hash_async_setkey(struct crypto_ahash *tfm_async, const u8 *key, |
63 | unsigned int keylen) | ||
64 | { | ||
65 | struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async); | ||
66 | struct crypto_hash *tfm_hash = __crypto_hash_cast(tfm); | ||
67 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
68 | |||
69 | return alg->setkey(tfm_hash, key, keylen); | ||
70 | } | ||
71 | |||
72 | static int hash_async_init(struct ahash_request *req) | ||
73 | { | ||
74 | struct crypto_tfm *tfm = req->base.tfm; | ||
75 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
76 | struct hash_desc desc = { | ||
77 | .tfm = __crypto_hash_cast(tfm), | ||
78 | .flags = req->base.flags, | ||
79 | }; | ||
80 | |||
81 | return alg->init(&desc); | ||
82 | } | ||
83 | |||
84 | static int hash_async_update(struct ahash_request *req) | ||
85 | { | ||
86 | struct crypto_tfm *tfm = req->base.tfm; | ||
87 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
88 | struct hash_desc desc = { | ||
89 | .tfm = __crypto_hash_cast(tfm), | ||
90 | .flags = req->base.flags, | ||
91 | }; | ||
92 | |||
93 | return alg->update(&desc, req->src, req->nbytes); | ||
94 | } | ||
95 | |||
96 | static int hash_async_final(struct ahash_request *req) | ||
97 | { | ||
98 | struct crypto_tfm *tfm = req->base.tfm; | ||
99 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
100 | struct hash_desc desc = { | ||
101 | .tfm = __crypto_hash_cast(tfm), | ||
102 | .flags = req->base.flags, | ||
103 | }; | ||
104 | |||
105 | return alg->final(&desc, req->result); | ||
106 | } | ||
107 | |||
108 | static int hash_async_digest(struct ahash_request *req) | ||
109 | { | ||
110 | struct crypto_tfm *tfm = req->base.tfm; | ||
111 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
112 | struct hash_desc desc = { | ||
113 | .tfm = __crypto_hash_cast(tfm), | ||
114 | .flags = req->base.flags, | ||
115 | }; | ||
116 | |||
117 | return alg->digest(&desc, req->src, req->nbytes, req->result); | ||
118 | } | ||
119 | |||
120 | static int crypto_init_hash_ops_async(struct crypto_tfm *tfm) | ||
121 | { | ||
122 | struct ahash_tfm *crt = &tfm->crt_ahash; | ||
123 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
124 | |||
125 | crt->init = hash_async_init; | ||
126 | crt->update = hash_async_update; | ||
127 | crt->final = hash_async_final; | ||
128 | crt->digest = hash_async_digest; | ||
129 | crt->setkey = hash_async_setkey; | ||
130 | crt->digestsize = alg->digestsize; | ||
131 | crt->base = __crypto_ahash_cast(tfm); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int crypto_init_hash_ops_sync(struct crypto_tfm *tfm) | ||
63 | { | 137 | { |
64 | struct hash_tfm *crt = &tfm->crt_hash; | 138 | struct hash_tfm *crt = &tfm->crt_hash; |
65 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | 139 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; |
66 | 140 | ||
67 | if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) | 141 | crt->init = alg->init; |
68 | return -EINVAL; | 142 | crt->update = alg->update; |
69 | 143 | crt->final = alg->final; | |
70 | crt->init = alg->init; | 144 | crt->digest = alg->digest; |
71 | crt->update = alg->update; | 145 | crt->setkey = hash_setkey; |
72 | crt->final = alg->final; | ||
73 | crt->digest = alg->digest; | ||
74 | crt->setkey = hash_setkey; | ||
75 | crt->digestsize = alg->digestsize; | 146 | crt->digestsize = alg->digestsize; |
76 | 147 | ||
77 | return 0; | 148 | return 0; |
78 | } | 149 | } |
79 | 150 | ||
151 | static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | ||
152 | { | ||
153 | struct hash_alg *alg = &tfm->__crt_alg->cra_hash; | ||
154 | |||
155 | if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) | ||
156 | return -EINVAL; | ||
157 | |||
158 | if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK) | ||
159 | return crypto_init_hash_ops_async(tfm); | ||
160 | else | ||
161 | return crypto_init_hash_ops_sync(tfm); | ||
162 | } | ||
163 | |||
80 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | 164 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) |
81 | __attribute__ ((unused)); | 165 | __attribute__ ((unused)); |
82 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | 166 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) |