123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /*******************************************************************************
- * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Eclipse Distribution License v1.0 which accompany this distribution.
- *
- * The Eclipse Public License is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- * Keith Holman - initial implementation and documentation
- *******************************************************************************/
- #include "SHA1.h"
- #if !defined(OPENSSL)
- #if defined(WIN32) || defined(WIN64)
- #pragma comment(lib, "crypt32.lib")
- int SHA1_Init(SHA_CTX *c)
- {
- if (!CryptAcquireContext(&c->hProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
- return 0;
- if (!CryptCreateHash(c->hProv, CALG_SHA1, 0, 0, &c->hHash))
- {
- CryptReleaseContext(c->hProv, 0);
- return 0;
- }
- return 1;
- }
- int SHA1_Update(SHA_CTX *c, const void *data, size_t len)
- {
- int rv = 1;
- if (!CryptHashData(c->hHash, data, (DWORD)len, 0))
- rv = 0;
- return rv;
- }
- int SHA1_Final(unsigned char *md, SHA_CTX *c)
- {
- int rv = 0;
- DWORD md_len = SHA1_DIGEST_LENGTH;
- if (CryptGetHashParam(c->hHash, HP_HASHVAL, md, &md_len, 0))
- rv = 1;
- CryptDestroyHash(c->hHash);
- CryptReleaseContext(c->hProv, 0);
- return rv;
- }
- #else /* if defined(WIN32) || defined(WIN64) */
- #if defined(__linux__) || defined(__CYGWIN__)
- # include <endian.h>
- #elif defined(__APPLE__)
- # include <libkern/OSByteOrder.h>
- # define htobe32(x) OSSwapHostToBigInt32(x)
- # define be32toh(x) OSSwapBigToHostInt32(x)
- #elif defined(__FreeBSD__) || defined(__NetBSD__)
- # include <sys/endian.h>
- #endif
- #include <string.h>
- static unsigned char pad[64] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- int SHA1_Init(SHA_CTX *ctx)
- {
- int ret = 0;
- if ( ctx )
- {
- ctx->h[0] = 0x67452301;
- ctx->h[1] = 0xEFCDAB89;
- ctx->h[2] = 0x98BADCFE;
- ctx->h[3] = 0x10325476;
- ctx->h[4] = 0xC3D2E1F0;
- ctx->size = 0u;
- ctx->total = 0u;
- ret = 1;
- }
- return ret;
- }
- #define ROTATE_LEFT32(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
- static void SHA1_ProcessBlock(SHA_CTX *ctx)
- {
- uint32_t blks[5];
- uint32_t *w;
- int i;
- /* initialize */
- for ( i = 0; i < 5; ++i )
- blks[i] = ctx->h[i];
- w = ctx->w;
- /* perform SHA-1 hash */
- for ( i = 0; i < 16; ++i )
- w[i] = be32toh(w[i]);
- for( i = 0; i < 80; ++i )
- {
- int tmp;
- if ( i >= 16 )
- w[i & 0x0F] = ROTATE_LEFT32( w[(i+13) & 0x0F] ^ w[(i+8) & 0x0F] ^ w[(i+2) & 0x0F] ^ w[i & 0x0F], 1 );
- if ( i < 20 )
- tmp = ROTATE_LEFT32(blks[0], 5) + ((blks[1] & blks[2]) | (~(blks[1]) & blks[3])) + blks[4] + w[i & 0x0F] + 0x5A827999;
- else if ( i < 40 )
- tmp = ROTATE_LEFT32(blks[0], 5) + (blks[1]^blks[2]^blks[3]) + blks[4] + w[i & 0x0F] + 0x6ED9EBA1;
- else if ( i < 60 )
- tmp = ROTATE_LEFT32(blks[0], 5) + ((blks[1] & blks[2]) | (blks[1] & blks[3]) | (blks[2] & blks[3])) + blks[4] + w[i & 0x0F] + 0x8F1BBCDC;
- else
- tmp = ROTATE_LEFT32(blks[0], 5) + (blks[1]^blks[2]^blks[3]) + blks[4] + w[i & 0x0F] + 0xCA62C1D6;
- /* update registers */
- blks[4] = blks[3];
- blks[3] = blks[2];
- blks[2] = ROTATE_LEFT32(blks[1], 30);
- blks[1] = blks[0];
- blks[0] = tmp;
- }
- /* update of hash */
- for ( i = 0; i < 5; ++i )
- ctx->h[i] += blks[i];
- }
- int SHA1_Final(unsigned char *md, SHA_CTX *ctx)
- {
- int i;
- int ret = 0;
- size_t pad_amount;
- uint64_t total;
- /* length before pad */
- total = ctx->total * 8;
- if ( ctx->size < 56 )
- pad_amount = 56 - ctx->size;
- else
- pad_amount = 64 + 56 - ctx->size;
- SHA1_Update(ctx, pad, pad_amount);
- ctx->w[14] = htobe32((uint32_t)(total >> 32));
- ctx->w[15] = htobe32((uint32_t)total);
- SHA1_ProcessBlock(ctx);
- for ( i = 0; i < 5; ++i )
- ctx->h[i] = htobe32(ctx->h[i]);
- if ( md )
- {
- memcpy( md, &ctx->h[0], SHA1_DIGEST_LENGTH );
- ret = 1;
- }
- return ret;
- }
- int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len)
- {
- while ( len > 0 )
- {
- unsigned int n = 64 - ctx->size;
- if ( len < n )
- n = len;
- memcpy(ctx->buffer + ctx->size, data, n);
- ctx->size += n;
- ctx->total += n;
- data = (uint8_t *)data + n;
- len -= n;
- if ( ctx->size == 64 )
- {
- SHA1_ProcessBlock(ctx);
- ctx->size = 0;
- }
- }
- return 1;
- }
- #endif /* else if defined(WIN32) || defined(WIN64) */
- #endif /* elif !defined(OPENSSL) */
- #if defined(SHA1_TEST)
- #include <stdio.h>
- #include <string.h>
- #define TEST_EXPECT(i,x) if (!(x)) {fprintf( stderr, "failed test: %s (for i == %d)\n", #x, i ); ++fails;}
- int main(int argc, char *argv[])
- {
- struct _td
- {
- const char *in;
- const char *out;
- };
- int i;
- unsigned int fails = 0u;
- struct _td test_data[] = {
- { "", "da39a3ee5e6b4b0d3255bfef95601890afd80709" },
- { "this string", "fda4e74bc7489a18b146abdf23346d166663dab8" },
- { NULL, NULL }
- };
- /* only 1 update */
- i = 0;
- while ( test_data[i].in != NULL )
- {
- int r[3] = { 1, 1, 1 };
- unsigned char sha_out[SHA1_DIGEST_LENGTH];
- char out[SHA1_DIGEST_LENGTH * 2 + 1];
- SHA_CTX c;
- int j;
- r[0] = SHA1_Init( &c );
- r[1] = SHA1_Update( &c, test_data[i].in, strlen(test_data[i].in));
- r[2] = SHA1_Final( sha_out, &c );
- for ( j = 0u; j < SHA1_DIGEST_LENGTH; ++j )
- snprintf( &out[j*2], 3u, "%02x", sha_out[j] );
- out[SHA1_DIGEST_LENGTH * 2] = '\0';
- TEST_EXPECT( i, r[0] == 1 && r[1] == 1 && r[2] == 1 && strncmp(out, test_data[i].out, strlen(test_data[i].out)) == 0 );
- ++i;
- }
- if ( fails )
- printf( "%u test failed!\n", fails );
- else
- printf( "all tests passed\n" );
- return fails;
- }
- #endif /* if defined(SHA1_TEST) */
|