diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-15 02:28:05 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-15 02:28:05 +0000 |
commit | e9afc468fac07f02c6e4ce160150e737928f8f07 (patch) | |
tree | a07c2491896901b6c2132ef7236ce90eba95c02a | |
parent | 7241e6d37781dc7e72e2b8b809f2643b98b66c25 (diff) | |
download | busybox-w32-e9afc468fac07f02c6e4ce160150e737928f8f07.tar.gz busybox-w32-e9afc468fac07f02c6e4ce160150e737928f8f07.tar.bz2 busybox-w32-e9afc468fac07f02c6e4ce160150e737928f8f07.zip |
sha: merge sha1/sha256 handling (they are similar enough for this),
shrink sha215 code
function old new delta
sha1_end 129 142 +13
sha1_process_block64 486 494 +8
sha256_begin 37 44 +7
sha1_begin 49 56 +7
sha1_hash 108 112 +4
...
sha512_end 204 184 -20
sha512_process_block128 1405 1334 -71
sha256_process_block64 520 446 -74
sha256_end 147 - -147
sha512_hash 297 130 -167
sha256_hash 260 - -260
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 11/9 up/down: 59/-752) Total: -693 bytes
-rw-r--r-- | include/libbb.h | 15 | ||||
-rw-r--r-- | libbb/sha1.c | 290 |
2 files changed, 94 insertions, 211 deletions
diff --git a/include/libbb.h b/include/libbb.h index b04488a54..b6eab6f24 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1321,24 +1321,21 @@ extern const char bb_uuenc_tbl_std[]; | |||
1321 | void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; | 1321 | void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; |
1322 | 1322 | ||
1323 | typedef struct sha1_ctx_t { | 1323 | typedef struct sha1_ctx_t { |
1324 | uint32_t hash[8]; /* 5, +3 elements for sha256 */ | ||
1324 | uint64_t total64; | 1325 | uint64_t total64; |
1325 | uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ | 1326 | uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ |
1326 | uint32_t hash[5]; | 1327 | void (*process_block)(struct sha1_ctx_t*); |
1327 | } sha1_ctx_t; | 1328 | } sha1_ctx_t; |
1328 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; | 1329 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; |
1329 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; | 1330 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; |
1330 | void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; | 1331 | void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; |
1331 | typedef struct sha256_ctx_t { | 1332 | typedef struct sha1_ctx_t sha256_ctx_t; |
1332 | uint64_t total64; | ||
1333 | uint32_t hash[8]; | ||
1334 | uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ | ||
1335 | } sha256_ctx_t; | ||
1336 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | 1333 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
1337 | void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC; | 1334 | #define sha256_hash sha1_hash |
1338 | void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC; | 1335 | #define sha256_end sha1_end |
1339 | typedef struct sha512_ctx_t { | 1336 | typedef struct sha512_ctx_t { |
1340 | uint64_t total64[2]; | ||
1341 | uint64_t hash[8]; | 1337 | uint64_t hash[8]; |
1338 | uint64_t total64[2]; | ||
1342 | uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */ | 1339 | uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */ |
1343 | } sha512_ctx_t; | 1340 | } sha512_ctx_t; |
1344 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 1341 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
diff --git a/libbb/sha1.c b/libbb/sha1.c index efdb0f58e..8ecf71a9d 100644 --- a/libbb/sha1.c +++ b/libbb/sha1.c | |||
@@ -203,9 +203,10 @@ static const uint32_t K512_lo[80] = { | |||
203 | 203 | ||
204 | /* Process LEN bytes of BUFFER, accumulating context into CTX. | 204 | /* Process LEN bytes of BUFFER, accumulating context into CTX. |
205 | LEN is rounded _down_ to 64. */ | 205 | LEN is rounded _down_ to 64. */ |
206 | static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t *ctx) | 206 | static void sha256_process_block64(sha256_ctx_t *ctx) |
207 | { | 207 | { |
208 | const uint32_t *words = buffer; | 208 | unsigned t; |
209 | uint32_t W[64]; | ||
209 | uint32_t a = ctx->hash[0]; | 210 | uint32_t a = ctx->hash[0]; |
210 | uint32_t b = ctx->hash[1]; | 211 | uint32_t b = ctx->hash[1]; |
211 | uint32_t c = ctx->hash[2]; | 212 | uint32_t c = ctx->hash[2]; |
@@ -214,15 +215,9 @@ static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t | |||
214 | uint32_t f = ctx->hash[5]; | 215 | uint32_t f = ctx->hash[5]; |
215 | uint32_t g = ctx->hash[6]; | 216 | uint32_t g = ctx->hash[6]; |
216 | uint32_t h = ctx->hash[7]; | 217 | uint32_t h = ctx->hash[7]; |
218 | const uint32_t *words = (uint32_t*) ctx->wbuffer; | ||
217 | 219 | ||
218 | /* Process all bytes in the buffer with 64 bytes in each round of | 220 | /* Operators defined in FIPS 180-2:4.1.2. */ |
219 | the loop. */ | ||
220 | len /= (sizeof(uint32_t) * 16); | ||
221 | while (len) { | ||
222 | unsigned t; | ||
223 | uint32_t W[64]; | ||
224 | |||
225 | /* Operators defined in FIPS 180-2:4.1.2. */ | ||
226 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) | 221 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) |
227 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | 222 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) |
228 | #define S0(x) (rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22)) | 223 | #define S0(x) (rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22)) |
@@ -230,54 +225,51 @@ static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t | |||
230 | #define R0(x) (rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3)) | 225 | #define R0(x) (rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3)) |
231 | #define R1(x) (rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10)) | 226 | #define R1(x) (rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10)) |
232 | 227 | ||
233 | /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ | 228 | /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ |
234 | for (t = 0; t < 16; ++t) { | 229 | for (t = 0; t < 16; ++t) { |
235 | W[t] = ntohl(*words); | 230 | W[t] = ntohl(*words); |
236 | words++; | 231 | words++; |
237 | } | 232 | } |
238 | 233 | ||
239 | for (/*t = 16*/; t < 64; ++t) | 234 | for (/*t = 16*/; t < 64; ++t) |
240 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; | 235 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; |
241 | 236 | ||
242 | /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ | 237 | /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ |
243 | for (t = 0; t < 64; ++t) { | 238 | for (t = 0; t < 64; ++t) { |
244 | uint32_t T1 = h + S1(e) + Ch(e, f, g) + K256[t] + W[t]; | 239 | uint32_t T1 = h + S1(e) + Ch(e, f, g) + K256[t] + W[t]; |
245 | uint32_t T2 = S0(a) + Maj(a, b, c); | 240 | uint32_t T2 = S0(a) + Maj(a, b, c); |
246 | h = g; | 241 | h = g; |
247 | g = f; | 242 | g = f; |
248 | f = e; | 243 | f = e; |
249 | e = d + T1; | 244 | e = d + T1; |
250 | d = c; | 245 | d = c; |
251 | c = b; | 246 | c = b; |
252 | b = a; | 247 | b = a; |
253 | a = T1 + T2; | 248 | a = T1 + T2; |
254 | } | 249 | } |
255 | #undef Ch | 250 | #undef Ch |
256 | #undef Maj | 251 | #undef Maj |
257 | #undef S0 | 252 | #undef S0 |
258 | #undef S1 | 253 | #undef S1 |
259 | #undef R0 | 254 | #undef R0 |
260 | #undef R1 | 255 | #undef R1 |
261 | /* Add the starting values of the context according to FIPS 180-2:6.2.2 | 256 | /* Add the starting values of the context according to FIPS 180-2:6.2.2 |
262 | step 4. */ | 257 | step 4. */ |
263 | ctx->hash[0] = a += ctx->hash[0]; | 258 | ctx->hash[0] += a; |
264 | ctx->hash[1] = b += ctx->hash[1]; | 259 | ctx->hash[1] += b; |
265 | ctx->hash[2] = c += ctx->hash[2]; | 260 | ctx->hash[2] += c; |
266 | ctx->hash[3] = d += ctx->hash[3]; | 261 | ctx->hash[3] += d; |
267 | ctx->hash[4] = e += ctx->hash[4]; | 262 | ctx->hash[4] += e; |
268 | ctx->hash[5] = f += ctx->hash[5]; | 263 | ctx->hash[5] += f; |
269 | ctx->hash[6] = g += ctx->hash[6]; | 264 | ctx->hash[6] += g; |
270 | ctx->hash[7] = h += ctx->hash[7]; | 265 | ctx->hash[7] += h; |
271 | |||
272 | /* Prepare for the next round. */ | ||
273 | len--; | ||
274 | } | ||
275 | } | 266 | } |
276 | /* Process LEN bytes of BUFFER, accumulating context into CTX. | 267 | /* Process LEN bytes of BUFFER, accumulating context into CTX. |
277 | LEN is rounded _down_ to 128. */ | 268 | LEN is rounded _down_ to 128. */ |
278 | static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t *ctx) | 269 | static void sha512_process_block128(sha512_ctx_t *ctx) |
279 | { | 270 | { |
280 | const uint64_t *words = buffer; | 271 | unsigned t; |
272 | uint64_t W[80]; | ||
281 | uint64_t a = ctx->hash[0]; | 273 | uint64_t a = ctx->hash[0]; |
282 | uint64_t b = ctx->hash[1]; | 274 | uint64_t b = ctx->hash[1]; |
283 | uint64_t c = ctx->hash[2]; | 275 | uint64_t c = ctx->hash[2]; |
@@ -286,13 +278,9 @@ static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t | |||
286 | uint64_t f = ctx->hash[5]; | 278 | uint64_t f = ctx->hash[5]; |
287 | uint64_t g = ctx->hash[6]; | 279 | uint64_t g = ctx->hash[6]; |
288 | uint64_t h = ctx->hash[7]; | 280 | uint64_t h = ctx->hash[7]; |
281 | const uint32_t *words = (uint32_t*) ctx->wbuffer; | ||
289 | 282 | ||
290 | len /= (sizeof(uint64_t) * 16); | 283 | /* Operators defined in FIPS 180-2:4.1.2. */ |
291 | while (len) { | ||
292 | unsigned t; | ||
293 | uint64_t W[80]; | ||
294 | |||
295 | /* Operators defined in FIPS 180-2:4.1.2. */ | ||
296 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) | 284 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) |
297 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | 285 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) |
298 | #define S0(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39)) | 286 | #define S0(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39)) |
@@ -300,58 +288,56 @@ static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t | |||
300 | #define R0(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7)) | 288 | #define R0(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7)) |
301 | #define R1(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6)) | 289 | #define R1(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6)) |
302 | 290 | ||
303 | /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ | 291 | /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ |
304 | for (t = 0; t < 16; ++t) { | 292 | for (t = 0; t < 16; ++t) { |
305 | W[t] = ntoh64(*words); | 293 | W[t] = ntoh64(*words); |
306 | words++; | 294 | words++; |
307 | } | 295 | } |
308 | for (/*t = 16*/; t < 80; ++t) | 296 | for (/*t = 16*/; t < 80; ++t) |
309 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; | 297 | W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; |
310 | 298 | ||
311 | /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ | 299 | /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ |
312 | for (t = 0; t < 80; ++t) { | 300 | for (t = 0; t < 80; ++t) { |
313 | uint64_t K512_t = ((uint64_t)(K256[t]) << 32) + K512_lo[t]; | 301 | uint64_t K512_t = ((uint64_t)(K256[t]) << 32) + K512_lo[t]; |
314 | uint64_t T1 = h + S1(e) + Ch(e, f, g) + K512_t + W[t]; | 302 | uint64_t T1 = h + S1(e) + Ch(e, f, g) + K512_t + W[t]; |
315 | uint64_t T2 = S0(a) + Maj(a, b, c); | 303 | uint64_t T2 = S0(a) + Maj(a, b, c); |
316 | h = g; | 304 | h = g; |
317 | g = f; | 305 | g = f; |
318 | f = e; | 306 | f = e; |
319 | e = d + T1; | 307 | e = d + T1; |
320 | d = c; | 308 | d = c; |
321 | c = b; | 309 | c = b; |
322 | b = a; | 310 | b = a; |
323 | a = T1 + T2; | 311 | a = T1 + T2; |
324 | } | 312 | } |
325 | #undef Ch | 313 | #undef Ch |
326 | #undef Maj | 314 | #undef Maj |
327 | #undef S0 | 315 | #undef S0 |
328 | #undef S1 | 316 | #undef S1 |
329 | #undef R0 | 317 | #undef R0 |
330 | #undef R1 | 318 | #undef R1 |
331 | /* Add the starting values of the context according to FIPS 180-2:6.3.2 | 319 | /* Add the starting values of the context according to FIPS 180-2:6.3.2 |
332 | step 4. */ | 320 | step 4. */ |
333 | ctx->hash[0] = a += ctx->hash[0]; | 321 | ctx->hash[0] += a; |
334 | ctx->hash[1] = b += ctx->hash[1]; | 322 | ctx->hash[1] += b; |
335 | ctx->hash[2] = c += ctx->hash[2]; | 323 | ctx->hash[2] += c; |
336 | ctx->hash[3] = d += ctx->hash[3]; | 324 | ctx->hash[3] += d; |
337 | ctx->hash[4] = e += ctx->hash[4]; | 325 | ctx->hash[4] += e; |
338 | ctx->hash[5] = f += ctx->hash[5]; | 326 | ctx->hash[5] += f; |
339 | ctx->hash[6] = g += ctx->hash[6]; | 327 | ctx->hash[6] += g; |
340 | ctx->hash[7] = h += ctx->hash[7]; | 328 | ctx->hash[7] += h; |
341 | |||
342 | len--; | ||
343 | } | ||
344 | } | 329 | } |
345 | 330 | ||
346 | 331 | ||
347 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | 332 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) |
348 | { | 333 | { |
349 | ctx->total64 = 0; | ||
350 | ctx->hash[0] = 0x67452301; | 334 | ctx->hash[0] = 0x67452301; |
351 | ctx->hash[1] = 0xefcdab89; | 335 | ctx->hash[1] = 0xefcdab89; |
352 | ctx->hash[2] = 0x98badcfe; | 336 | ctx->hash[2] = 0x98badcfe; |
353 | ctx->hash[3] = 0x10325476; | 337 | ctx->hash[3] = 0x10325476; |
354 | ctx->hash[4] = 0xc3d2e1f0; | 338 | ctx->hash[4] = 0xc3d2e1f0; |
339 | ctx->total64 = 0; | ||
340 | ctx->process_block = sha1_process_block64; | ||
355 | } | 341 | } |
356 | 342 | ||
357 | static const uint32_t init256[] = { | 343 | static const uint32_t init256[] = { |
@@ -380,6 +366,7 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |||
380 | { | 366 | { |
381 | memcpy(ctx->hash, init256, sizeof(init256)); | 367 | memcpy(ctx->hash, init256, sizeof(init256)); |
382 | ctx->total64 = 0; | 368 | ctx->total64 = 0; |
369 | ctx->process_block = sha256_process_block64; | ||
383 | } | 370 | } |
384 | /* Initialize structure containing state of computation. | 371 | /* Initialize structure containing state of computation. |
385 | (FIPS 180-2:5.3.3) */ | 372 | (FIPS 180-2:5.3.3) */ |
@@ -405,64 +392,16 @@ void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx) | |||
405 | len -= add; | 392 | len -= add; |
406 | add = SHA1_BLOCK_SIZE; | 393 | add = SHA1_BLOCK_SIZE; |
407 | in_buf = 0; | 394 | in_buf = 0; |
408 | sha1_process_block64(ctx); | 395 | ctx->process_block(ctx); |
409 | } | 396 | } |
410 | 397 | ||
411 | memcpy(ctx->wbuffer + in_buf, buffer, len); | 398 | memcpy(ctx->wbuffer + in_buf, buffer, len); |
412 | } | 399 | } |
413 | 400 | ||
414 | void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) | ||
415 | { | ||
416 | unsigned in_buf = ctx->total64 & 63; | ||
417 | |||
418 | /* First increment the byte count. FIPS 180-2 specifies the possible | ||
419 | length of the file up to 2^64 _bits_. | ||
420 | We compute the number of _bytes_ and convert to bits later. */ | ||
421 | ctx->total64 += len; | ||
422 | |||
423 | /* When we already have some bits in our internal buffer concatenate | ||
424 | both inputs first. */ | ||
425 | if (in_buf != 0) { | ||
426 | unsigned add; | ||
427 | |||
428 | add = sizeof(ctx->wbuffer) - in_buf; | ||
429 | if (add > len) | ||
430 | add = len; | ||
431 | memcpy(ctx->wbuffer + in_buf, buffer, add); | ||
432 | in_buf += add; | ||
433 | |||
434 | /* If we still didn't collect full wbuffer, bail out */ | ||
435 | if (in_buf < sizeof(ctx->wbuffer)) | ||
436 | return; | ||
437 | |||
438 | sha256_process_block64(ctx->wbuffer, 64, ctx); | ||
439 | buffer = (const char *)buffer + add; | ||
440 | len -= add; | ||
441 | } | ||
442 | |||
443 | /* Process available complete blocks. */ | ||
444 | if (len >= 64) { | ||
445 | if (UNALIGNED_P(buffer, uint32_t)) { | ||
446 | while (len >= 64) { | ||
447 | sha256_process_block64(memcpy(ctx->wbuffer, buffer, 64), 64, ctx); | ||
448 | buffer = (const char *)buffer + 64; | ||
449 | len -= 64; | ||
450 | } | ||
451 | } else { | ||
452 | sha256_process_block64(buffer, len /*& ~63*/, ctx); | ||
453 | buffer = (const char *)buffer + (len & ~63); | ||
454 | len &= 63; | ||
455 | } | ||
456 | } | ||
457 | |||
458 | /* Move remaining bytes into internal buffer. */ | ||
459 | if (len > 0) | ||
460 | memcpy(ctx->wbuffer, buffer, len); | ||
461 | } | ||
462 | |||
463 | void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) | 401 | void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) |
464 | { | 402 | { |
465 | unsigned in_buf = ctx->total64[0] & 127; | 403 | unsigned in_buf = ctx->total64[0] & 127; |
404 | unsigned add = 128 - in_buf; | ||
466 | 405 | ||
467 | /* First increment the byte count. FIPS 180-2 specifies the possible | 406 | /* First increment the byte count. FIPS 180-2 specifies the possible |
468 | length of the file up to 2^128 _bits_. | 407 | length of the file up to 2^128 _bits_. |
@@ -471,39 +410,16 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) | |||
471 | if (ctx->total64[0] < len) | 410 | if (ctx->total64[0] < len) |
472 | ctx->total64[1]++; | 411 | ctx->total64[1]++; |
473 | 412 | ||
474 | if (in_buf != 0) { | 413 | while (len >= add) { /* transfer whole blocks while possible */ |
475 | unsigned add; | ||
476 | |||
477 | add = sizeof(ctx->wbuffer) - in_buf; | ||
478 | if (add > len) | ||
479 | add = len; | ||
480 | memcpy(ctx->wbuffer + in_buf, buffer, add); | 414 | memcpy(ctx->wbuffer + in_buf, buffer, add); |
481 | in_buf += add; | ||
482 | |||
483 | if (in_buf < sizeof(ctx->wbuffer)) | ||
484 | return; | ||
485 | |||
486 | sha512_process_block128(ctx->wbuffer, 128, ctx); | ||
487 | buffer = (const char *)buffer + add; | 415 | buffer = (const char *)buffer + add; |
488 | len -= add; | 416 | len -= add; |
417 | add = 128; | ||
418 | in_buf = 0; | ||
419 | sha512_process_block128(ctx); | ||
489 | } | 420 | } |
490 | 421 | ||
491 | if (len >= 128) { | 422 | memcpy(ctx->wbuffer + in_buf, buffer, len); |
492 | if (UNALIGNED_P(buffer, uint64_t)) { | ||
493 | while (len >= 128) { | ||
494 | sha512_process_block128(memcpy(ctx->wbuffer, buffer, 128), 128, ctx); | ||
495 | buffer = (const char *)buffer + 128; | ||
496 | len -= 128; | ||
497 | } | ||
498 | } else { | ||
499 | sha512_process_block128(buffer, len /*& ~127*/, ctx); | ||
500 | buffer = (const char *)buffer + (len & ~127); | ||
501 | len &= 127; | ||
502 | } | ||
503 | } | ||
504 | |||
505 | if (len > 0) | ||
506 | memcpy(ctx->wbuffer, buffer, len); | ||
507 | } | 423 | } |
508 | 424 | ||
509 | 425 | ||
@@ -528,48 +444,18 @@ void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) | |||
528 | /* wbuffer is suitably aligned for this */ | 444 | /* wbuffer is suitably aligned for this */ |
529 | *(uint64_t *) (&ctx->wbuffer[SHA1_BLOCK_SIZE - 8]) = t; | 445 | *(uint64_t *) (&ctx->wbuffer[SHA1_BLOCK_SIZE - 8]) = t; |
530 | } | 446 | } |
531 | sha1_process_block64(ctx); | 447 | ctx->process_block(ctx); |
532 | if (pad >= 8) | 448 | if (pad >= 8) |
533 | break; | 449 | break; |
534 | } | 450 | } |
535 | 451 | ||
452 | in_buf = (ctx->process_block == sha1_process_block64) ? 5 : 8; | ||
536 | /* This way we do not impose alignment constraints on resbuf: */ | 453 | /* This way we do not impose alignment constraints on resbuf: */ |
537 | #if BB_LITTLE_ENDIAN | 454 | #if BB_LITTLE_ENDIAN |
538 | for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) | 455 | for (i = 0; i < in_buf; ++i) |
539 | ctx->hash[i] = htonl(ctx->hash[i]); | ||
540 | #endif | ||
541 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | ||
542 | } | ||
543 | |||
544 | void FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx) | ||
545 | { | ||
546 | unsigned i, pad, in_buf; | ||
547 | |||
548 | in_buf = ctx->total64 & 63; | ||
549 | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... | ||
550 | * (FIPS 180-2:5.1.1) | ||
551 | */ | ||
552 | ctx->wbuffer[in_buf++] = 0x80; | ||
553 | |||
554 | while (1) { | ||
555 | pad = 64 - in_buf; | ||
556 | memset(ctx->wbuffer + in_buf, 0, pad); | ||
557 | in_buf = 0; | ||
558 | if (pad >= 8) { | ||
559 | uint64_t t = ctx->total64 << 3; | ||
560 | t = hton64(t); | ||
561 | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; | ||
562 | } | ||
563 | sha256_process_block64(ctx->wbuffer, 64, ctx); | ||
564 | if (pad >= 8) | ||
565 | break; | ||
566 | } | ||
567 | |||
568 | #if BB_LITTLE_ENDIAN | ||
569 | for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) | ||
570 | ctx->hash[i] = htonl(ctx->hash[i]); | 456 | ctx->hash[i] = htonl(ctx->hash[i]); |
571 | #endif | 457 | #endif |
572 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | 458 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * in_buf); |
573 | } | 459 | } |
574 | 460 | ||
575 | void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) | 461 | void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) |
@@ -596,7 +482,7 @@ void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) | |||
596 | t = hton64(t); | 482 | t = hton64(t); |
597 | *(uint64_t *) (&ctx->wbuffer[128 - 16]) = t; | 483 | *(uint64_t *) (&ctx->wbuffer[128 - 16]) = t; |
598 | } | 484 | } |
599 | sha512_process_block128(ctx->wbuffer, 128, ctx); | 485 | sha512_process_block128(ctx); |
600 | if (pad >= 16) | 486 | if (pad >= 16) |
601 | break; | 487 | break; |
602 | } | 488 | } |