diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-11-02 08:38:11 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-12-24 19:01:30 -0500 |
commit | dec8b78606ebd5f309c38f2fb10196ce996dd18d (patch) | |
tree | 005ef526f1b0e953a3a57e6c991e0921fcd5234b | |
parent | 3b2f6df08258e2875f42bd630eece7e7241a053b (diff) |
crypto: hash - Add import/export interface
It is often useful to save the partial state of a hash function
so that it can be used as a base for two or more computations.
The most prominent example is HMAC where all hashes start from
a base determined by the key. Having an import/export interface
means that we only have to compute that base once rather than
for each message.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/ahash.c | 14 | ||||
-rw-r--r-- | crypto/shash.c | 14 | ||||
-rw-r--r-- | include/crypto/hash.h | 21 | ||||
-rw-r--r-- | include/crypto/internal/hash.h | 5 | ||||
-rw-r--r-- | include/linux/crypto.h | 1 |
5 files changed, 50 insertions, 5 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c index 27128f2c687a..7d4e33dfe212 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
@@ -146,6 +146,20 @@ static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key, | |||
146 | return ahash->setkey(tfm, key, keylen); | 146 | return ahash->setkey(tfm, key, keylen); |
147 | } | 147 | } |
148 | 148 | ||
149 | int crypto_ahash_import(struct ahash_request *req, const u8 *in) | ||
150 | { | ||
151 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | ||
152 | struct ahash_alg *alg = crypto_ahash_alg(tfm); | ||
153 | |||
154 | memcpy(ahash_request_ctx(req), in, crypto_ahash_reqsize(tfm)); | ||
155 | |||
156 | if (alg->reinit) | ||
157 | alg->reinit(req); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | EXPORT_SYMBOL_GPL(crypto_ahash_import); | ||
162 | |||
149 | static unsigned int crypto_ahash_ctxsize(struct crypto_alg *alg, u32 type, | 163 | static unsigned int crypto_ahash_ctxsize(struct crypto_alg *alg, u32 type, |
150 | u32 mask) | 164 | u32 mask) |
151 | { | 165 | { |
diff --git a/crypto/shash.c b/crypto/shash.c index 3f4c713a21ea..26aff3feefc0 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
@@ -172,6 +172,20 @@ int crypto_shash_digest(struct shash_desc *desc, const u8 *data, | |||
172 | } | 172 | } |
173 | EXPORT_SYMBOL_GPL(crypto_shash_digest); | 173 | EXPORT_SYMBOL_GPL(crypto_shash_digest); |
174 | 174 | ||
175 | int crypto_shash_import(struct shash_desc *desc, const u8 *in) | ||
176 | { | ||
177 | struct crypto_shash *tfm = desc->tfm; | ||
178 | struct shash_alg *alg = crypto_shash_alg(tfm); | ||
179 | |||
180 | memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(tfm)); | ||
181 | |||
182 | if (alg->reinit) | ||
183 | alg->reinit(desc); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | EXPORT_SYMBOL_GPL(crypto_shash_import); | ||
188 | |||
175 | static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key, | 189 | static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key, |
176 | unsigned int keylen) | 190 | unsigned int keylen) |
177 | { | 191 | { |
diff --git a/include/crypto/hash.h b/include/crypto/hash.h index f9b51d408953..cd16d6e668ce 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h | |||
@@ -24,6 +24,7 @@ struct shash_desc { | |||
24 | 24 | ||
25 | struct shash_alg { | 25 | struct shash_alg { |
26 | int (*init)(struct shash_desc *desc); | 26 | int (*init)(struct shash_desc *desc); |
27 | int (*reinit)(struct shash_desc *desc); | ||
27 | int (*update)(struct shash_desc *desc, const u8 *data, | 28 | int (*update)(struct shash_desc *desc, const u8 *data, |
28 | unsigned int len); | 29 | unsigned int len); |
29 | int (*final)(struct shash_desc *desc, u8 *out); | 30 | int (*final)(struct shash_desc *desc, u8 *out); |
@@ -116,6 +117,11 @@ static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm) | |||
116 | return crypto_ahash_crt(tfm)->reqsize; | 117 | return crypto_ahash_crt(tfm)->reqsize; |
117 | } | 118 | } |
118 | 119 | ||
120 | static inline void *ahash_request_ctx(struct ahash_request *req) | ||
121 | { | ||
122 | return req->__ctx; | ||
123 | } | ||
124 | |||
119 | static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, | 125 | static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, |
120 | const u8 *key, unsigned int keylen) | 126 | const u8 *key, unsigned int keylen) |
121 | { | 127 | { |
@@ -130,6 +136,14 @@ static inline int crypto_ahash_digest(struct ahash_request *req) | |||
130 | return crt->digest(req); | 136 | return crt->digest(req); |
131 | } | 137 | } |
132 | 138 | ||
139 | static inline void crypto_ahash_export(struct ahash_request *req, u8 *out) | ||
140 | { | ||
141 | memcpy(out, ahash_request_ctx(req), | ||
142 | crypto_ahash_reqsize(crypto_ahash_reqtfm(req))); | ||
143 | } | ||
144 | |||
145 | int crypto_ahash_import(struct ahash_request *req, const u8 *in); | ||
146 | |||
133 | static inline int crypto_ahash_init(struct ahash_request *req) | 147 | static inline int crypto_ahash_init(struct ahash_request *req) |
134 | { | 148 | { |
135 | struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); | 149 | struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); |
@@ -262,6 +276,13 @@ int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key, | |||
262 | int crypto_shash_digest(struct shash_desc *desc, const u8 *data, | 276 | int crypto_shash_digest(struct shash_desc *desc, const u8 *data, |
263 | unsigned int len, u8 *out); | 277 | unsigned int len, u8 *out); |
264 | 278 | ||
279 | static inline void crypto_shash_export(struct shash_desc *desc, u8 *out) | ||
280 | { | ||
281 | memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm)); | ||
282 | } | ||
283 | |||
284 | int crypto_shash_import(struct shash_desc *desc, const u8 *in); | ||
285 | |||
265 | static inline int crypto_shash_init(struct shash_desc *desc) | 286 | static inline int crypto_shash_init(struct shash_desc *desc) |
266 | { | 287 | { |
267 | return crypto_shash_alg(desc->tfm)->init(desc); | 288 | return crypto_shash_alg(desc->tfm)->init(desc); |
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 32d3a8ed06de..92fbe7385856 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h | |||
@@ -66,11 +66,6 @@ static inline struct ahash_request *ahash_dequeue_request( | |||
66 | return ahash_request_cast(crypto_dequeue_request(queue)); | 66 | return ahash_request_cast(crypto_dequeue_request(queue)); |
67 | } | 67 | } |
68 | 68 | ||
69 | static inline void *ahash_request_ctx(struct ahash_request *req) | ||
70 | { | ||
71 | return req->__ctx; | ||
72 | } | ||
73 | |||
74 | static inline int ahash_tfm_in_queue(struct crypto_queue *queue, | 69 | static inline int ahash_tfm_in_queue(struct crypto_queue *queue, |
75 | struct crypto_ahash *tfm) | 70 | struct crypto_ahash *tfm) |
76 | { | 71 | { |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 44c72f0f9b05..77a1f3d9416d 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -221,6 +221,7 @@ struct ablkcipher_alg { | |||
221 | 221 | ||
222 | struct ahash_alg { | 222 | struct ahash_alg { |
223 | int (*init)(struct ahash_request *req); | 223 | int (*init)(struct ahash_request *req); |
224 | int (*reinit)(struct ahash_request *req); | ||
224 | int (*update)(struct ahash_request *req); | 225 | int (*update)(struct ahash_request *req); |
225 | int (*final)(struct ahash_request *req); | 226 | int (*final)(struct ahash_request *req); |
226 | int (*digest)(struct ahash_request *req); | 227 | int (*digest)(struct ahash_request *req); |