/** Process a block of memory though the hash @param state The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ int sha1_process(sha1_state* state, const unsigned char* in, unsigned long inlen) { unsigned long n; int err; if (state->curlen > sizeof(state->buf)) { return CRYPT_INVALID_ARG; } if ((state->length + inlen) < state->length) { return CRYPT_HASH_OVERFLOW; } while (inlen > 0) { if (state->curlen == 0 && inlen >= 64) { if ((err = sha1_compress(state, in)) != CRYPT_OK) { return err; } state->length += 64 * 8; in += 64; inlen -= 64; } else { n = ulmin(inlen, (64 - state->curlen)); memcpy(state->buf + state->curlen, in, (size_t)n); state->curlen += n; in += n; inlen -= n; if (state->curlen == 64) { if ((err = sha1_compress(state, state->buf)) != CRYPT_OK) { return err; } state->length += 8 * 64; state->curlen = 0; } } } return CRYPT_OK; }
void sha1_hash(uint8_t *message, uint32_t len, uint32_t *hash) { hash[0] = 0x67452301; hash[1] = 0xEFCDAB89; hash[2] = 0x98BADCFE; hash[3] = 0x10325476; hash[4] = 0xC3D2E1F0; int i; for (i = 0; i + 64 <= len; i += 64) sha1_compress(hash, (uint32_t*)(message + i)); uint32_t block[16]; uint8_t *byteBlock = (uint8_t*)block; int rem = len - i; memcpy(byteBlock, message + i, rem); byteBlock[rem] = 0x80; rem++; if (64 - rem >= 8) memset(byteBlock + rem, 0, 56 - rem); else { memset(byteBlock + rem, 0, 64 - rem); sha1_compress(hash, block); memset(block, 0, 56); } uint64_t longLen = ((uint64_t)len) << 3; for (i = 0; i < 8; i++) byteBlock[64 - 1 - i] = (uint8_t)(longLen >> (i * 8)); sha1_compress(hash, block); }
/*** Process a block of memory though the hash @param sha1 The hash state @param in The data to hash @param inlen The length of the data (octets) */ void sha1_process(struct sha1_state *sha1, const unsigned char *in, unsigned long inlen) { unsigned long n; // assert(sha1 != NULL); // assert(in != NULL); // assert(sha1->curlen <= sizeof(sha1->buf)); while (inlen > 0) { if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) { sha1_compress(sha1, (unsigned char *)in); sha1->length += SHA1_BLOCKSIZE * 8; in += SHA1_BLOCKSIZE; inlen -= SHA1_BLOCKSIZE; } else { n = MIN(inlen, (SHA1_BLOCKSIZE - sha1->curlen)); memcpy(sha1->buf + sha1->curlen, in, (size_t)n); sha1->curlen += n; in += n; inlen -= n; if (sha1->curlen == SHA1_BLOCKSIZE) { sha1_compress(sha1, sha1->buf); sha1->length += 8*SHA1_BLOCKSIZE; sha1->curlen = 0; } } } }
/** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ int sha1_process(sha1_state *state, const unsigned char *in, unsigned long inlen) { unsigned long n; int err; if (state == NULL) goto einval; if (in == NULL) goto einval; if (state->curlen > 64) goto einval; while (inlen > 0) { if (state->curlen == 0 && inlen >= 64) { sha1_compress(state, in); state->length += (64 * 8); in += 64; inlen -= 64; } else { n = (64 - state->curlen); if (inlen < n) n = inlen; memcpy(state->buf + state->curlen, in, n); state->curlen += n; inlen -= n; if (state->curlen == 64) { sha1_compress(state, state->buf); state->length += 64 * 8; state->curlen = 0; } } } return 0; einval: errno = EINVAL; return -1; }
void sha1_hash(const uint8_t *message, uint32_t len, uint32_t hash[5]) { hash[0] = UINT32_C(0x67452301); hash[1] = UINT32_C(0xEFCDAB89); hash[2] = UINT32_C(0x98BADCFE); hash[3] = UINT32_C(0x10325476); hash[4] = UINT32_C(0xC3D2E1F0); uint32_t i; for (i = 0; len - i >= 64; i += 64) sha1_compress(hash, message + i); uint8_t block[64]; uint32_t rem = len - i; memcpy(block, message + i, rem); block[rem] = 0x80; rem++; if (64 - rem >= 8) memset(block + rem, 0, 56 - rem); else { memset(block + rem, 0, 64 - rem); sha1_compress(hash, block); memset(block, 0, 56); } uint64_t longLen = ((uint64_t)len) << 3; for (i = 0; i < 8; i++) block[64 - 1 - i] = (uint8_t)(longLen >> (i * 8)); sha1_compress(hash, block); }
int main(int argc, char **argv) { struct timeval start_sha, end_sha; if (!self_check()) { printf("Self-check failed\n"); return 1; } printf("Self-check passed\n"); // Benchmark speed uint32_t state[5]; uint32_t block[16]; const unsigned long N = 10000000; clock_t start_time = clock(); int i; unsigned long diff; gettimeofday(&start_sha,NULL); for (i = 0; i < N; i++) sha1_compress(state, block); gettimeofday(&end_sha,NULL); diff = 1000000 * (end_sha.tv_sec-start_sha.tv_sec)+ end_sha.tv_usec-start_sha.tv_usec; printf("SHA1 Speed is %ld Mbps\n", (N * 64 * 8) / diff); printf("Speed: %.1f Mbps/s\n", (double)N * 64 * 8 / (clock() - start_time) * CLOCKS_PER_SEC / 1048576); return 0; }
void psSha1Update(psDigestContext_t * md, const unsigned char *buf, uint32 len) { uint32 n; psAssert(md != NULL); psAssert(buf != NULL); while (len > 0) { n = min(len, (64 - md->sha1.curlen)); memcpy(md->sha1.buf + md->sha1.curlen, buf, (size_t)n); md->sha1.curlen += n; buf += n; len -= n; /* is 64 bytes full? */ if (md->sha1.curlen == 64) { sha1_compress(md); #ifdef HAVE_NATIVE_INT64 md->sha1.length += 512; #else n = (md->sha1.lengthLo + 512) & 0xFFFFFFFFL; if (n < md->sha1.lengthLo) { md->sha1.lengthHi++; } md->sha1.lengthLo = n; #endif /* HAVE_NATIVE_INT64 */ md->sha1.curlen = 0; } } }
void matrixSha1Update(hash_state * md, const unsigned char *buf, unsigned long len) { unsigned long n; sslAssert(md != NULL); sslAssert(buf != NULL); while (len > 0) { n = MIN(len, (64 - md->sha1.curlen)); memcpy(md->sha1.buf + md->sha1.curlen, buf, (size_t)n); md->sha1.curlen += n; buf += n; len -= n; /* is 64 bytes full? */ if (md->sha1.curlen == 64) { sha1_compress(md); #ifdef USE_INT64 md->sha1.length += 512; #else n = (md->sha1.lengthLo + 512) & 0xFFFFFFFFL; if (n < md->sha1.lengthLo) { md->sha1.lengthHi++; } md->sha1.lengthLo = n; #endif /* USE_INT64 */ md->sha1.curlen = 0; } } }
/** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int sha1_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->sha1.curlen >= sizeof(md->sha1.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->sha1.length += md->sha1.curlen * 8; /* append the '1' bit */ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->sha1.curlen > 56) { while (md->sha1.curlen < 64) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } sha1_compress(md, md->sha1.buf); md->sha1.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->sha1.curlen < 56) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } /* store length */ STORE64H(md->sha1.length, md->sha1.buf+56); sha1_compress(md, md->sha1.buf); /* copy output */ for (i = 0; i < 5; i++) { STORE32H(md->sha1.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; }
/** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int sha1_done(sha1_state *state, unsigned char *out) { int i; if (state == NULL) goto einval; if (out == NULL) goto einval; if (state->curlen > 64) goto einval; /* increase the length of the message */ state->length += state->curlen * 8; /* append the '1' bit */ memset(state->buf + state->curlen++, 0x80, 1); /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (state->curlen > 56) { memset(state->buf + state->curlen, 0, (64 - state->curlen)); sha1_compress(state, state->buf); state->curlen = 0; } /* pad upto 56 bytes of zeroes */ if (state->curlen < 56) { memset(state->buf + state->curlen, 0, (56 - state->curlen)); state->curlen = 56; } /* store length */ ((uint32_t *)(state->buf))[14] = (state->length >> 32); ((uint32_t *)(state->buf))[15] = (state->length & 0xFFFFFFFFUL); sha1_compress(state, state->buf); /* copy output */ for (i = 0; i < 5; i++) ((uint32_t *)out)[i] = htonl(state->state[i]); return 0; einval: errno = EINVAL; return -1; }
/** Terminate the hash to get the digest @param state The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int sha1_done(sha1_state* state, unsigned char* out) { int i; if (state->curlen >= sizeof(state->buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ state->length += state->curlen * 8; /* append the '1' bit */ state->buf[state->curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (state->curlen > 56) { while (state->curlen < 64) { state->buf[state->curlen++] = (unsigned char)0; } sha1_compress(state, state->buf); state->curlen = 0; } /* pad upto 56 bytes of zeroes */ while (state->curlen < 56) { state->buf[state->curlen++] = (unsigned char)0; } /* store length */ STORE64H(state->length, state->buf + 56); sha1_compress(state, state->buf); /* copy output */ for (i = 0; i < 5; i++) { STORE32H(state->state[i], out + (4 * i)); } return CRYPT_OK; }
/*** Terminate the hash to get the digest @param sha1 The hash state @param out [out] The destination of the hash (20 bytes) */ void sha1_done(struct sha1_state *sha1, unsigned char *out) { int i; // assert(sha1 != NULL); // assert(out != NULL); // assert(sha1->curlen < sizeof(sha1->buf)); /** increase the length of the message */ sha1->length += sha1->curlen * 8; /** append the '1' bit */ sha1->buf[sha1->curlen++] = (unsigned char)0x80; /** if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (sha1->curlen > 56) { while (sha1->curlen < 64) { sha1->buf[sha1->curlen++] = (unsigned char)0; } sha1_compress(sha1, sha1->buf); sha1->curlen = 0; } /** pad upto 56 bytes of zeroes */ while (sha1->curlen < 56) { sha1->buf[sha1->curlen++] = (unsigned char)0; } /** store length */ STORE64H(sha1->length, sha1->buf+56); sha1_compress(sha1, sha1->buf); /** copy output */ for (i = 0; i < 5; i++) { STORE32H(sha1->state[i], out+(4*i)); } }
void sha1_process(hash_state * md, const unsigned char *buf, unsigned long len) { unsigned long n; _ARGCHK(md != NULL); _ARGCHK(buf != NULL); while (len > 0) { n = MIN(len, (64 - md->sha1.curlen)); memcpy(md->sha1.buf + md->sha1.curlen, buf, (size_t)n); md->sha1.curlen += n; buf += n; len -= n; /* is 64 bytes full? */ if (md->sha1.curlen == 64) { sha1_compress(md); md->sha1.length += 512; md->sha1.curlen = 0; } } }
int32 psSha1Final(psDigestContext_t * md, unsigned char *hash) { int32 i; #ifndef HAVE_NATIVE_INT64 uint32 n; #endif psAssert(md != NULL); if (md->sha1.curlen >= sizeof(md->sha1.buf) || hash == NULL) { psTraceCrypto("psSha1Final error\n"); return PS_ARG_FAIL; } /* increase the length of the message */ #ifdef HAVE_NATIVE_INT64 md->sha1.length += md->sha1.curlen << 3; #else n = (md->sha1.lengthLo + (md->sha1.curlen << 3)) & 0xFFFFFFFFL; if (n < md->sha1.lengthLo) { md->sha1.lengthHi++; } md->sha1.lengthHi += (md->sha1.curlen >> 29); md->sha1.lengthLo = n; #endif /* HAVE_NATIVE_INT64 */ /* append the '1' bit */ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal. */ if (md->sha1.curlen > 56) { while (md->sha1.curlen < 64) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } sha1_compress(md); md->sha1.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->sha1.curlen < 56) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } /* store length */ #ifdef HAVE_NATIVE_INT64 STORE64H(md->sha1.length, md->sha1.buf+56); #else STORE32H(md->sha1.lengthHi, md->sha1.buf+56); STORE32H(md->sha1.lengthLo, md->sha1.buf+60); #endif /* HAVE_NATIVE_INT64 */ sha1_compress(md); /* copy output */ for (i = 0; i < 5; i++) { STORE32H(md->sha1.state[i], hash+(4*i)); } memset(md, 0x0, sizeof(psDigestContext_t)); return SHA1_HASH_SIZE; }
int32 matrixSha1Final(hash_state * md, unsigned char *hash) { int32 i; #ifndef USE_INT64 unsigned long n; #endif sslAssert(md != NULL); if (md->sha1.curlen >= sizeof(md->sha1.buf) || hash == NULL) { return -1; } /* increase the length of the message */ #ifdef USE_INT64 md->sha1.length += md->sha1.curlen << 3; #else n = (md->sha1.lengthLo + (md->sha1.curlen << 3)) & 0xFFFFFFFFL; if (n < md->sha1.lengthLo) { md->sha1.lengthHi++; } md->sha1.lengthHi += (md->sha1.curlen >> 29); md->sha1.lengthLo = n; #endif /* USE_INT64 */ /* append the '1' bit */ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal. */ if (md->sha1.curlen > 56) { while (md->sha1.curlen < 64) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } sha1_compress(md); md->sha1.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->sha1.curlen < 56) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } /* store length */ #ifdef USE_INT64 STORE64H(md->sha1.length, md->sha1.buf+56); #else STORE32H(md->sha1.lengthHi, md->sha1.buf+56); STORE32H(md->sha1.lengthLo, md->sha1.buf+60); #endif /* USE_INT64 */ sha1_compress(md); /* copy output */ for (i = 0; i < 5; i++) { STORE32H(md->sha1.state[i], hash+(4*i)); } #ifdef CLEAN_STACK psZeromem(md, sizeof(hash_state)); #endif /* CLEAN_STACK */ return 20; }