SHA1.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*******************************************************************************
  2. * Copyright (c) 2018 Wind River Systems, Inc. All Rights Reserved.
  3. *
  4. * All rights reserved. This program and the accompanying materials
  5. * are made available under the terms of the Eclipse Public License v1.0
  6. * and Eclipse Distribution License v1.0 which accompany this distribution.
  7. *
  8. * The Eclipse Public License is available at
  9. * http://www.eclipse.org/legal/epl-v10.html
  10. * and the Eclipse Distribution License is available at
  11. * http://www.eclipse.org/org/documents/edl-v10.php.
  12. *
  13. * Contributors:
  14. * Keith Holman - initial implementation and documentation
  15. *******************************************************************************/
  16. #include "SHA1.h"
  17. #if !defined(OPENSSL)
  18. #if defined(WIN32) || defined(WIN64)
  19. #pragma comment(lib, "crypt32.lib")
  20. int SHA1_Init(SHA_CTX *c)
  21. {
  22. if (!CryptAcquireContext(&c->hProv, NULL, NULL,
  23. PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  24. return 0;
  25. if (!CryptCreateHash(c->hProv, CALG_SHA1, 0, 0, &c->hHash))
  26. {
  27. CryptReleaseContext(c->hProv, 0);
  28. return 0;
  29. }
  30. return 1;
  31. }
  32. int SHA1_Update(SHA_CTX *c, const void *data, size_t len)
  33. {
  34. int rv = 1;
  35. if (!CryptHashData(c->hHash, data, (DWORD)len, 0))
  36. rv = 0;
  37. return rv;
  38. }
  39. int SHA1_Final(unsigned char *md, SHA_CTX *c)
  40. {
  41. int rv = 0;
  42. DWORD md_len = SHA1_DIGEST_LENGTH;
  43. if (CryptGetHashParam(c->hHash, HP_HASHVAL, md, &md_len, 0))
  44. rv = 1;
  45. CryptDestroyHash(c->hHash);
  46. CryptReleaseContext(c->hProv, 0);
  47. return rv;
  48. }
  49. #else /* if defined(WIN32) || defined(WIN64) */
  50. #if defined(__linux__) || defined(__CYGWIN__)
  51. # include <endian.h>
  52. #elif defined(__APPLE__)
  53. # include <libkern/OSByteOrder.h>
  54. # define htobe32(x) OSSwapHostToBigInt32(x)
  55. # define be32toh(x) OSSwapBigToHostInt32(x)
  56. #elif defined(__FreeBSD__) || defined(__NetBSD__)
  57. # include <sys/endian.h>
  58. #endif
  59. #include <string.h>
  60. static unsigned char pad[64] = {
  61. 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  62. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  63. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  64. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  65. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  66. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  68. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  69. };
  70. int SHA1_Init(SHA_CTX *ctx)
  71. {
  72. int ret = 0;
  73. if ( ctx )
  74. {
  75. ctx->h[0] = 0x67452301;
  76. ctx->h[1] = 0xEFCDAB89;
  77. ctx->h[2] = 0x98BADCFE;
  78. ctx->h[3] = 0x10325476;
  79. ctx->h[4] = 0xC3D2E1F0;
  80. ctx->size = 0u;
  81. ctx->total = 0u;
  82. ret = 1;
  83. }
  84. return ret;
  85. }
  86. #define ROTATE_LEFT32(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
  87. static void SHA1_ProcessBlock(SHA_CTX *ctx)
  88. {
  89. uint32_t blks[5];
  90. uint32_t *w;
  91. int i;
  92. /* initialize */
  93. for ( i = 0; i < 5; ++i )
  94. blks[i] = ctx->h[i];
  95. w = ctx->w;
  96. /* perform SHA-1 hash */
  97. for ( i = 0; i < 16; ++i )
  98. w[i] = be32toh(w[i]);
  99. for( i = 0; i < 80; ++i )
  100. {
  101. int tmp;
  102. if ( i >= 16 )
  103. w[i & 0x0F] = ROTATE_LEFT32( w[(i+13) & 0x0F] ^ w[(i+8) & 0x0F] ^ w[(i+2) & 0x0F] ^ w[i & 0x0F], 1 );
  104. if ( i < 20 )
  105. tmp = ROTATE_LEFT32(blks[0], 5) + ((blks[1] & blks[2]) | (~(blks[1]) & blks[3])) + blks[4] + w[i & 0x0F] + 0x5A827999;
  106. else if ( i < 40 )
  107. tmp = ROTATE_LEFT32(blks[0], 5) + (blks[1]^blks[2]^blks[3]) + blks[4] + w[i & 0x0F] + 0x6ED9EBA1;
  108. else if ( i < 60 )
  109. tmp = ROTATE_LEFT32(blks[0], 5) + ((blks[1] & blks[2]) | (blks[1] & blks[3]) | (blks[2] & blks[3])) + blks[4] + w[i & 0x0F] + 0x8F1BBCDC;
  110. else
  111. tmp = ROTATE_LEFT32(blks[0], 5) + (blks[1]^blks[2]^blks[3]) + blks[4] + w[i & 0x0F] + 0xCA62C1D6;
  112. /* update registers */
  113. blks[4] = blks[3];
  114. blks[3] = blks[2];
  115. blks[2] = ROTATE_LEFT32(blks[1], 30);
  116. blks[1] = blks[0];
  117. blks[0] = tmp;
  118. }
  119. /* update of hash */
  120. for ( i = 0; i < 5; ++i )
  121. ctx->h[i] += blks[i];
  122. }
  123. int SHA1_Final(unsigned char *md, SHA_CTX *ctx)
  124. {
  125. int i;
  126. int ret = 0;
  127. size_t pad_amount;
  128. uint64_t total;
  129. /* length before pad */
  130. total = ctx->total * 8;
  131. if ( ctx->size < 56 )
  132. pad_amount = 56 - ctx->size;
  133. else
  134. pad_amount = 64 + 56 - ctx->size;
  135. SHA1_Update(ctx, pad, pad_amount);
  136. ctx->w[14] = htobe32((uint32_t)(total >> 32));
  137. ctx->w[15] = htobe32((uint32_t)total);
  138. SHA1_ProcessBlock(ctx);
  139. for ( i = 0; i < 5; ++i )
  140. ctx->h[i] = htobe32(ctx->h[i]);
  141. if ( md )
  142. {
  143. memcpy( md, &ctx->h[0], SHA1_DIGEST_LENGTH );
  144. ret = 1;
  145. }
  146. return ret;
  147. }
  148. int SHA1_Update(SHA_CTX *ctx, const void *data, size_t len)
  149. {
  150. while ( len > 0 )
  151. {
  152. unsigned int n = 64 - ctx->size;
  153. if ( len < n )
  154. n = len;
  155. memcpy(ctx->buffer + ctx->size, data, n);
  156. ctx->size += n;
  157. ctx->total += n;
  158. data = (uint8_t *)data + n;
  159. len -= n;
  160. if ( ctx->size == 64 )
  161. {
  162. SHA1_ProcessBlock(ctx);
  163. ctx->size = 0;
  164. }
  165. }
  166. return 1;
  167. }
  168. #endif /* else if defined(WIN32) || defined(WIN64) */
  169. #endif /* elif !defined(OPENSSL) */
  170. #if defined(SHA1_TEST)
  171. #include <stdio.h>
  172. #include <string.h>
  173. #define TEST_EXPECT(i,x) if (!(x)) {fprintf( stderr, "failed test: %s (for i == %d)\n", #x, i ); ++fails;}
  174. int main(int argc, char *argv[])
  175. {
  176. struct _td
  177. {
  178. const char *in;
  179. const char *out;
  180. };
  181. int i;
  182. unsigned int fails = 0u;
  183. struct _td test_data[] = {
  184. { "", "da39a3ee5e6b4b0d3255bfef95601890afd80709" },
  185. { "this string", "fda4e74bc7489a18b146abdf23346d166663dab8" },
  186. { NULL, NULL }
  187. };
  188. /* only 1 update */
  189. i = 0;
  190. while ( test_data[i].in != NULL )
  191. {
  192. int r[3] = { 1, 1, 1 };
  193. unsigned char sha_out[SHA1_DIGEST_LENGTH];
  194. char out[SHA1_DIGEST_LENGTH * 2 + 1];
  195. SHA_CTX c;
  196. int j;
  197. r[0] = SHA1_Init( &c );
  198. r[1] = SHA1_Update( &c, test_data[i].in, strlen(test_data[i].in));
  199. r[2] = SHA1_Final( sha_out, &c );
  200. for ( j = 0u; j < SHA1_DIGEST_LENGTH; ++j )
  201. snprintf( &out[j*2], 3u, "%02x", sha_out[j] );
  202. out[SHA1_DIGEST_LENGTH * 2] = '\0';
  203. TEST_EXPECT( i, r[0] == 1 && r[1] == 1 && r[2] == 1 && strncmp(out, test_data[i].out, strlen(test_data[i].out)) == 0 );
  204. ++i;
  205. }
  206. if ( fails )
  207. printf( "%u test failed!\n", fails );
  208. else
  209. printf( "all tests passed\n" );
  210. return fails;
  211. }
  212. #endif /* if defined(SHA1_TEST) */