diff options
| author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-04-09 06:55:37 -0400 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-10 09:39:41 -0400 |
| commit | a2e5ba4fedd6e590bb2cd83817c2bf0cd0de69d1 (patch) | |
| tree | 25f6860a8439cf44ded9380229fe687b49d3c66a | |
| parent | 7c71f0f760d65f270aca0849caebb1fd5d53c66b (diff) | |
crypto: sha256-generic - move to generic glue implementation
This updates the generic SHA-256 implementation to use the
new shared SHA-256 glue code.
It also implements a .finup hook crypto_sha256_finup() and exports
it to other modules. The import and export() functions and the
.statesize member are dropped, since the default implementation
is perfectly suitable for this module.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
| -rw-r--r-- | crypto/sha256_generic.c | 133 | ||||
| -rw-r--r-- | include/crypto/sha.h | 3 |
2 files changed, 23 insertions, 113 deletions
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c index b001ff5c2efc..78431163ed3c 100644 --- a/crypto/sha256_generic.c +++ b/crypto/sha256_generic.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
| 25 | #include <crypto/sha.h> | 25 | #include <crypto/sha.h> |
| 26 | #include <crypto/sha256_base.h> | ||
| 26 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
| 27 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
| 28 | 29 | ||
| @@ -214,138 +215,43 @@ static void sha256_transform(u32 *state, const u8 *input) | |||
| 214 | memzero_explicit(W, 64 * sizeof(u32)); | 215 | memzero_explicit(W, 64 * sizeof(u32)); |
| 215 | } | 216 | } |
| 216 | 217 | ||
| 217 | static int sha224_init(struct shash_desc *desc) | 218 | static void sha256_generic_block_fn(struct sha256_state *sst, u8 const *src, |
| 219 | int blocks) | ||
| 218 | { | 220 | { |
| 219 | struct sha256_state *sctx = shash_desc_ctx(desc); | 221 | while (blocks--) { |
| 220 | sctx->state[0] = SHA224_H0; | 222 | sha256_transform(sst->state, src); |
| 221 | sctx->state[1] = SHA224_H1; | 223 | src += SHA256_BLOCK_SIZE; |
| 222 | sctx->state[2] = SHA224_H2; | 224 | } |
| 223 | sctx->state[3] = SHA224_H3; | ||
| 224 | sctx->state[4] = SHA224_H4; | ||
| 225 | sctx->state[5] = SHA224_H5; | ||
| 226 | sctx->state[6] = SHA224_H6; | ||
| 227 | sctx->state[7] = SHA224_H7; | ||
| 228 | sctx->count = 0; | ||
| 229 | |||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | static int sha256_init(struct shash_desc *desc) | ||
| 234 | { | ||
| 235 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
| 236 | sctx->state[0] = SHA256_H0; | ||
| 237 | sctx->state[1] = SHA256_H1; | ||
| 238 | sctx->state[2] = SHA256_H2; | ||
| 239 | sctx->state[3] = SHA256_H3; | ||
| 240 | sctx->state[4] = SHA256_H4; | ||
| 241 | sctx->state[5] = SHA256_H5; | ||
| 242 | sctx->state[6] = SHA256_H6; | ||
| 243 | sctx->state[7] = SHA256_H7; | ||
| 244 | sctx->count = 0; | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | 225 | } |
| 248 | 226 | ||
| 249 | int crypto_sha256_update(struct shash_desc *desc, const u8 *data, | 227 | int crypto_sha256_update(struct shash_desc *desc, const u8 *data, |
| 250 | unsigned int len) | 228 | unsigned int len) |
| 251 | { | 229 | { |
| 252 | struct sha256_state *sctx = shash_desc_ctx(desc); | 230 | return sha256_base_do_update(desc, data, len, sha256_generic_block_fn); |
| 253 | unsigned int partial, done; | ||
| 254 | const u8 *src; | ||
| 255 | |||
| 256 | partial = sctx->count & 0x3f; | ||
| 257 | sctx->count += len; | ||
| 258 | done = 0; | ||
| 259 | src = data; | ||
| 260 | |||
| 261 | if ((partial + len) > 63) { | ||
| 262 | if (partial) { | ||
| 263 | done = -partial; | ||
| 264 | memcpy(sctx->buf + partial, data, done + 64); | ||
| 265 | src = sctx->buf; | ||
| 266 | } | ||
| 267 | |||
| 268 | do { | ||
| 269 | sha256_transform(sctx->state, src); | ||
| 270 | done += 64; | ||
| 271 | src = data + done; | ||
| 272 | } while (done + 63 < len); | ||
| 273 | |||
| 274 | partial = 0; | ||
| 275 | } | ||
| 276 | memcpy(sctx->buf + partial, src, len - done); | ||
| 277 | |||
| 278 | return 0; | ||
| 279 | } | 231 | } |
| 280 | EXPORT_SYMBOL(crypto_sha256_update); | 232 | EXPORT_SYMBOL(crypto_sha256_update); |
| 281 | 233 | ||
| 282 | static int sha256_final(struct shash_desc *desc, u8 *out) | 234 | static int sha256_final(struct shash_desc *desc, u8 *out) |
| 283 | { | 235 | { |
| 284 | struct sha256_state *sctx = shash_desc_ctx(desc); | 236 | sha256_base_do_finalize(desc, sha256_generic_block_fn); |
| 285 | __be32 *dst = (__be32 *)out; | 237 | return sha256_base_finish(desc, out); |
| 286 | __be64 bits; | ||
| 287 | unsigned int index, pad_len; | ||
| 288 | int i; | ||
| 289 | static const u8 padding[64] = { 0x80, }; | ||
| 290 | |||
| 291 | /* Save number of bits */ | ||
| 292 | bits = cpu_to_be64(sctx->count << 3); | ||
| 293 | |||
| 294 | /* Pad out to 56 mod 64. */ | ||
| 295 | index = sctx->count & 0x3f; | ||
| 296 | pad_len = (index < 56) ? (56 - index) : ((64+56) - index); | ||
| 297 | crypto_sha256_update(desc, padding, pad_len); | ||
| 298 | |||
| 299 | /* Append length (before padding) */ | ||
| 300 | crypto_sha256_update(desc, (const u8 *)&bits, sizeof(bits)); | ||
| 301 | |||
| 302 | /* Store state in digest */ | ||
| 303 | for (i = 0; i < 8; i++) | ||
| 304 | dst[i] = cpu_to_be32(sctx->state[i]); | ||
| 305 | |||
| 306 | /* Zeroize sensitive information. */ | ||
| 307 | memset(sctx, 0, sizeof(*sctx)); | ||
| 308 | |||
| 309 | return 0; | ||
| 310 | } | 238 | } |
| 311 | 239 | ||
| 312 | static int sha224_final(struct shash_desc *desc, u8 *hash) | 240 | int crypto_sha256_finup(struct shash_desc *desc, const u8 *data, |
| 241 | unsigned int len, u8 *hash) | ||
| 313 | { | 242 | { |
| 314 | u8 D[SHA256_DIGEST_SIZE]; | 243 | sha256_base_do_update(desc, data, len, sha256_generic_block_fn); |
| 315 | 244 | return sha256_final(desc, hash); | |
| 316 | sha256_final(desc, D); | ||
| 317 | |||
| 318 | memcpy(hash, D, SHA224_DIGEST_SIZE); | ||
| 319 | memzero_explicit(D, SHA256_DIGEST_SIZE); | ||
| 320 | |||
| 321 | return 0; | ||
| 322 | } | ||
| 323 | |||
| 324 | static int sha256_export(struct shash_desc *desc, void *out) | ||
| 325 | { | ||
| 326 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
| 327 | |||
| 328 | memcpy(out, sctx, sizeof(*sctx)); | ||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | static int sha256_import(struct shash_desc *desc, const void *in) | ||
| 333 | { | ||
| 334 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
| 335 | |||
| 336 | memcpy(sctx, in, sizeof(*sctx)); | ||
| 337 | return 0; | ||
| 338 | } | 245 | } |
| 246 | EXPORT_SYMBOL(crypto_sha256_finup); | ||
| 339 | 247 | ||
| 340 | static struct shash_alg sha256_algs[2] = { { | 248 | static struct shash_alg sha256_algs[2] = { { |
| 341 | .digestsize = SHA256_DIGEST_SIZE, | 249 | .digestsize = SHA256_DIGEST_SIZE, |
| 342 | .init = sha256_init, | 250 | .init = sha256_base_init, |
| 343 | .update = crypto_sha256_update, | 251 | .update = crypto_sha256_update, |
| 344 | .final = sha256_final, | 252 | .final = sha256_final, |
| 345 | .export = sha256_export, | 253 | .finup = crypto_sha256_finup, |
| 346 | .import = sha256_import, | ||
| 347 | .descsize = sizeof(struct sha256_state), | 254 | .descsize = sizeof(struct sha256_state), |
| 348 | .statesize = sizeof(struct sha256_state), | ||
| 349 | .base = { | 255 | .base = { |
| 350 | .cra_name = "sha256", | 256 | .cra_name = "sha256", |
| 351 | .cra_driver_name= "sha256-generic", | 257 | .cra_driver_name= "sha256-generic", |
| @@ -355,9 +261,10 @@ static struct shash_alg sha256_algs[2] = { { | |||
| 355 | } | 261 | } |
| 356 | }, { | 262 | }, { |
| 357 | .digestsize = SHA224_DIGEST_SIZE, | 263 | .digestsize = SHA224_DIGEST_SIZE, |
| 358 | .init = sha224_init, | 264 | .init = sha224_base_init, |
| 359 | .update = crypto_sha256_update, | 265 | .update = crypto_sha256_update, |
| 360 | .final = sha224_final, | 266 | .final = sha256_final, |
| 267 | .finup = crypto_sha256_finup, | ||
| 361 | .descsize = sizeof(struct sha256_state), | 268 | .descsize = sizeof(struct sha256_state), |
| 362 | .base = { | 269 | .base = { |
| 363 | .cra_name = "sha224", | 270 | .cra_name = "sha224", |
diff --git a/include/crypto/sha.h b/include/crypto/sha.h index a754cdd749c6..e28c4b5e805d 100644 --- a/include/crypto/sha.h +++ b/include/crypto/sha.h | |||
| @@ -93,6 +93,9 @@ extern int crypto_sha1_finup(struct shash_desc *desc, const u8 *data, | |||
| 93 | extern int crypto_sha256_update(struct shash_desc *desc, const u8 *data, | 93 | extern int crypto_sha256_update(struct shash_desc *desc, const u8 *data, |
| 94 | unsigned int len); | 94 | unsigned int len); |
| 95 | 95 | ||
| 96 | extern int crypto_sha256_finup(struct shash_desc *desc, const u8 *data, | ||
| 97 | unsigned int len, u8 *hash); | ||
| 98 | |||
| 96 | extern int crypto_sha512_update(struct shash_desc *desc, const u8 *data, | 99 | extern int crypto_sha512_update(struct shash_desc *desc, const u8 *data, |
| 97 | unsigned int len); | 100 | unsigned int len); |
| 98 | #endif | 101 | #endif |
