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


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:11