123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <netinet/in.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <endian.h>
- #include <unistd.h>
- #include "sha1.h"
- static unsigned char
- padding[SHA1_BLOCK_SIZE] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
- static uint32_t
- F(uint32_t b, uint32_t c, uint32_t d)
- {
- return (b & c) | ((~b) & d);
- }
- static uint32_t
- G(uint32_t b, uint32_t c, uint32_t d)
- {
- return b ^ c ^ d;
- }
- static uint32_t
- H(uint32_t b, uint32_t c, uint32_t d)
- {
- return (b & c) | (b & d) | (c & d);
- }
- static uint32_t
- RL(uint32_t n, uint32_t s)
- {
- return (n << s) | (n >> (32 - s));
- }
- static uint32_t
- sha1_round(uint32_t (*FUNC)(uint32_t, uint32_t, uint32_t),
- uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
- uint32_t i, uint32_t n)
- {
- return RL(a, 5) + FUNC(b, c, d) + e + i + n;
- }
- void
- sha1_init(struct sha1_context *ctx)
- {
- memset(ctx, 0, sizeof(*ctx));
- ctx->a = 0x67452301;
- ctx->b = 0xefcdab89;
- ctx->c = 0x98badcfe;
- ctx->d = 0x10325476;
- ctx->e = 0xc3d2e1f0;
- }
- static void
- sha1_process(struct sha1_context *ctx, uint32_t buffer[SHA1_BLOCK_SIZE / 4])
- {
- uint32_t a, b, c, d, e, temp;
- uint32_t data[80];
- int i;
- for (i = 0; i < 16; i++) {
- data[i] = htonl(buffer[i]);
- }
- for (i = 16; i < 80; i++) {
- data[i] = RL(data[i - 3] ^ data[i - 8] ^ data[i - 14] ^ data[i - 16], 1);
- }
- a = ctx->a;
- b = ctx->b;
- c = ctx->c;
- d = ctx->d;
- e = ctx->e;
- for (i = 0; i < 20; i++) {
- temp = sha1_round(F, a, b, c, d, e, data[i], 0x5a827999);
- e = d; d = c; c = RL(b, 30); b = a; a = temp;
- }
- for (i = 20; i < 40; i++) {
- temp = sha1_round(G, a, b, c, d, e, data[i], 0x6ed9eba1);
- e = d; d = c; c = RL(b, 30); b = a; a = temp;
- }
- for (i = 40; i < 60; i++) {
- temp = sha1_round(H, a, b, c, d, e, data[i], 0x8f1bbcdc);
- e = d; d = c; c = RL(b, 30); b = a; a = temp;
- }
- for (i = 60; i < 80; i++) {
- temp = sha1_round(G, a, b, c, d, e, data[i], 0xca62c1d6);
- e = d; d = c; c = RL(b, 30); b = a; a = temp;
- }
- ctx->a += a;
- ctx->b += b;
- ctx->c += c;
- ctx->d += d;
- ctx->e += e;
- memset(buffer, 0, sizeof(buffer[0]) * SHA1_BLOCK_SIZE / 4);
- memset(data, 0, sizeof(data));
- }
- void
- sha1_update(struct sha1_context *ctx, const unsigned char *data, size_t length)
- {
- size_t i = 0, l = length, c, t;
- uint32_t count = 0;
-
- while (l + ctx->pending_count >= SHA1_BLOCK_SIZE) {
- c = ctx->pending_count;
- t = SHA1_BLOCK_SIZE - c;
- memcpy(ctx->pending.c + c, &data[i], t);
- sha1_process(ctx, ctx->pending.i);
- i += t;
- l -= t;
- ctx->pending_count = 0;
- }
-
- c = ctx->pending_count;
- memcpy(ctx->pending.c + c, &data[i], l);
- ctx->pending_count += l;
-
- ctx->count += length;
-
- if (length != 0) {
- count = ctx->counts[0];
- ctx->counts[0] += length;
- if (count >= ctx->counts[0]) {
- ctx->counts[1]++;
- }
- }
- }
- size_t
- sha1_output(struct sha1_context *ctx, unsigned char *out)
- {
- struct sha1_context ctx2;
-
- if (out != NULL) {
- uint32_t c;
- memcpy(&ctx2, ctx, sizeof(ctx2));
-
- c = ctx2.pending_count;
- memcpy(ctx2.pending.c + c,
- padding, SHA1_BLOCK_SIZE - c);
-
- if (c >= (SHA1_BLOCK_SIZE - (sizeof(uint32_t) * 2))) {
-
- sha1_process(&ctx2, ctx2.pending.i);
-
- ctx2.pending_count = 0;
- memset(ctx2.pending.c, 0, SHA1_BLOCK_SIZE);
- ctx2.pending.c[0] =
- (c == SHA1_BLOCK_SIZE) ? 0x80 : 0;
- }
-
- ctx2.counts[1] <<= 3;
- if (ctx2.counts[0] >> 29) {
- ctx2.counts[1] |=
- (ctx2.counts[0] >> 29);
- }
- ctx2.counts[0] <<= 3;
- ctx2.counts[0] = htonl(ctx2.counts[0]);
- ctx2.counts[1] = htonl(ctx2.counts[1]);
- memcpy(ctx2.pending.c + 56,
- &ctx2.counts[1], sizeof(uint32_t));
- memcpy(ctx2.pending.c + 60,
- &ctx2.counts[0], sizeof(uint32_t));
- sha1_process(&ctx2, ctx2.pending.i);
-
- out[ 3] = (ctx2.a >> 0) & 0xff;
- out[ 2] = (ctx2.a >> 8) & 0xff;
- out[ 1] = (ctx2.a >> 16) & 0xff;
- out[ 0] = (ctx2.a >> 24) & 0xff;
- out[ 7] = (ctx2.b >> 0) & 0xff;
- out[ 6] = (ctx2.b >> 8) & 0xff;
- out[ 5] = (ctx2.b >> 16) & 0xff;
- out[ 4] = (ctx2.b >> 24) & 0xff;
- out[11] = (ctx2.c >> 0) & 0xff;
- out[10] = (ctx2.c >> 8) & 0xff;
- out[ 9] = (ctx2.c >> 16) & 0xff;
- out[ 8] = (ctx2.c >> 24) & 0xff;
- out[15] = (ctx2.d >> 0) & 0xff;
- out[14] = (ctx2.d >> 8) & 0xff;
- out[13] = (ctx2.d >> 16) & 0xff;
- out[12] = (ctx2.d >> 24) & 0xff;
- out[19] = (ctx2.e >> 0) & 0xff;
- out[18] = (ctx2.e >> 8) & 0xff;
- out[17] = (ctx2.e >> 16) & 0xff;
- out[16] = (ctx2.e >> 24) & 0xff;
- }
- return SHA1_OUTPUT_SIZE;
- }
|