xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

sha1.c
Go to the documentation of this file.
1 /* sha1.c - SHA1 hash function
2  * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
3  *
4  * This file was part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /* Borrowed and adapted slightly for use in JTE by Steve McIntyre
21  * <steve@einval.com> October 2010 */
22 
23 /* Test vectors:
24  *
25  * "abc"
26  * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D
27  *
28  * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
29  * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1
30  */
31 
32 #ifdef HAVE_CONFIG_H
33 #include "../config.h"
34 #endif
35 
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #ifdef HAVE_STDINT_H
42 #include <stdint.h>
43 #else
44 #ifdef HAVE_INTTYPES_H
45 #include <inttypes.h>
46 #endif
47 #endif
48 
49 #include "sha1.h"
50 
51 #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
52 #define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
53 
54 /* A macro to test whether P is properly aligned for an uint32_t type.
55  Note that config.h provides a suitable replacement for uintptr_t if
56  it does not exist in stdint.h. */
57 /* #if __GNUC__ >= 2 */
58 /* # define UINT32_T_ALIGNED_P(p) (!(((uintptr_t)p) % __alignof__ (uint32_t))) */
59 /* #else */
60 /* # define UINT32_T_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (uint32_t))) */
61 /* #endif */
62 
63 #define TRANSFORM(x,d,n) transform ((x), (d), (n))
64 
65 void sha1_init_ctx (void *context)
66 {
67  SHA1_CONTEXT *hd = context;
68 
69  hd->h0 = 0x67452301;
70  hd->h1 = 0xefcdab89;
71  hd->h2 = 0x98badcfe;
72  hd->h3 = 0x10325476;
73  hd->h4 = 0xc3d2e1f0;
74  hd->nblocks = 0;
75  hd->count = 0;
76 }
77 
78 
79 /* Round function macros. */
80 #define K1 0x5A827999L
81 #define K2 0x6ED9EBA1L
82 #define K3 0x8F1BBCDCL
83 #define K4 0xCA62C1D6L
84 #define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
85 #define F2(x,y,z) ( x ^ y ^ z )
86 #define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
87 #define F4(x,y,z) ( x ^ y ^ z )
88 #define M(i) ( tm = x[ i &0x0f] \
89  ^ x[(i-14)&0x0f] \
90  ^ x[(i-8) &0x0f] \
91  ^ x[(i-3) &0x0f], \
92  (x[i&0x0f] = rol(tm, 1)))
93 #define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \
94  + f( b, c, d ) \
95  + k \
96  + m; \
97  b = rol( b, 30 ); \
98  } while(0)
99 
100 
101 /*
102  * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
103  */
104 static void transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
105 {
106  register uint32_t a, b, c, d, e; /* Local copies of the chaining variables. */
107  register uint32_t tm; /* Helper. */
108  uint32_t x[16]; /* The array we work on. */
109 
110  /* Loop over all blocks. */
111  for ( ;nblocks; nblocks--)
112  {
113 #ifdef WORDS_BIGENDIAN
114  memcpy (x, data, 64);
115  data += 64;
116 #else
117  {
118  int i;
119  unsigned char *p;
120 
121  for(i=0, p=(unsigned char*)x; i < 16; i++, p += 4 )
122  {
123  p[3] = *data++;
124  p[2] = *data++;
125  p[1] = *data++;
126  p[0] = *data++;
127  }
128  }
129 #endif
130  /* Get the values of the chaining variables. */
131  a = hd->h0;
132  b = hd->h1;
133  c = hd->h2;
134  d = hd->h3;
135  e = hd->h4;
136 
137  /* Transform. */
138  R( a, b, c, d, e, F1, K1, x[ 0] );
139  R( e, a, b, c, d, F1, K1, x[ 1] );
140  R( d, e, a, b, c, F1, K1, x[ 2] );
141  R( c, d, e, a, b, F1, K1, x[ 3] );
142  R( b, c, d, e, a, F1, K1, x[ 4] );
143  R( a, b, c, d, e, F1, K1, x[ 5] );
144  R( e, a, b, c, d, F1, K1, x[ 6] );
145  R( d, e, a, b, c, F1, K1, x[ 7] );
146  R( c, d, e, a, b, F1, K1, x[ 8] );
147  R( b, c, d, e, a, F1, K1, x[ 9] );
148  R( a, b, c, d, e, F1, K1, x[10] );
149  R( e, a, b, c, d, F1, K1, x[11] );
150  R( d, e, a, b, c, F1, K1, x[12] );
151  R( c, d, e, a, b, F1, K1, x[13] );
152  R( b, c, d, e, a, F1, K1, x[14] );
153  R( a, b, c, d, e, F1, K1, x[15] );
154  R( e, a, b, c, d, F1, K1, M(16) );
155  R( d, e, a, b, c, F1, K1, M(17) );
156  R( c, d, e, a, b, F1, K1, M(18) );
157  R( b, c, d, e, a, F1, K1, M(19) );
158  R( a, b, c, d, e, F2, K2, M(20) );
159  R( e, a, b, c, d, F2, K2, M(21) );
160  R( d, e, a, b, c, F2, K2, M(22) );
161  R( c, d, e, a, b, F2, K2, M(23) );
162  R( b, c, d, e, a, F2, K2, M(24) );
163  R( a, b, c, d, e, F2, K2, M(25) );
164  R( e, a, b, c, d, F2, K2, M(26) );
165  R( d, e, a, b, c, F2, K2, M(27) );
166  R( c, d, e, a, b, F2, K2, M(28) );
167  R( b, c, d, e, a, F2, K2, M(29) );
168  R( a, b, c, d, e, F2, K2, M(30) );
169  R( e, a, b, c, d, F2, K2, M(31) );
170  R( d, e, a, b, c, F2, K2, M(32) );
171  R( c, d, e, a, b, F2, K2, M(33) );
172  R( b, c, d, e, a, F2, K2, M(34) );
173  R( a, b, c, d, e, F2, K2, M(35) );
174  R( e, a, b, c, d, F2, K2, M(36) );
175  R( d, e, a, b, c, F2, K2, M(37) );
176  R( c, d, e, a, b, F2, K2, M(38) );
177  R( b, c, d, e, a, F2, K2, M(39) );
178  R( a, b, c, d, e, F3, K3, M(40) );
179  R( e, a, b, c, d, F3, K3, M(41) );
180  R( d, e, a, b, c, F3, K3, M(42) );
181  R( c, d, e, a, b, F3, K3, M(43) );
182  R( b, c, d, e, a, F3, K3, M(44) );
183  R( a, b, c, d, e, F3, K3, M(45) );
184  R( e, a, b, c, d, F3, K3, M(46) );
185  R( d, e, a, b, c, F3, K3, M(47) );
186  R( c, d, e, a, b, F3, K3, M(48) );
187  R( b, c, d, e, a, F3, K3, M(49) );
188  R( a, b, c, d, e, F3, K3, M(50) );
189  R( e, a, b, c, d, F3, K3, M(51) );
190  R( d, e, a, b, c, F3, K3, M(52) );
191  R( c, d, e, a, b, F3, K3, M(53) );
192  R( b, c, d, e, a, F3, K3, M(54) );
193  R( a, b, c, d, e, F3, K3, M(55) );
194  R( e, a, b, c, d, F3, K3, M(56) );
195  R( d, e, a, b, c, F3, K3, M(57) );
196  R( c, d, e, a, b, F3, K3, M(58) );
197  R( b, c, d, e, a, F3, K3, M(59) );
198  R( a, b, c, d, e, F4, K4, M(60) );
199  R( e, a, b, c, d, F4, K4, M(61) );
200  R( d, e, a, b, c, F4, K4, M(62) );
201  R( c, d, e, a, b, F4, K4, M(63) );
202  R( b, c, d, e, a, F4, K4, M(64) );
203  R( a, b, c, d, e, F4, K4, M(65) );
204  R( e, a, b, c, d, F4, K4, M(66) );
205  R( d, e, a, b, c, F4, K4, M(67) );
206  R( c, d, e, a, b, F4, K4, M(68) );
207  R( b, c, d, e, a, F4, K4, M(69) );
208  R( a, b, c, d, e, F4, K4, M(70) );
209  R( e, a, b, c, d, F4, K4, M(71) );
210  R( d, e, a, b, c, F4, K4, M(72) );
211  R( c, d, e, a, b, F4, K4, M(73) );
212  R( b, c, d, e, a, F4, K4, M(74) );
213  R( a, b, c, d, e, F4, K4, M(75) );
214  R( e, a, b, c, d, F4, K4, M(76) );
215  R( d, e, a, b, c, F4, K4, M(77) );
216  R( c, d, e, a, b, F4, K4, M(78) );
217  R( b, c, d, e, a, F4, K4, M(79) );
218 
219  /* Update the chaining variables. */
220  hd->h0 += a;
221  hd->h1 += b;
222  hd->h2 += c;
223  hd->h3 += d;
224  hd->h4 += e;
225  }
226 }
227 
228 
229 /* Update the message digest with the contents
230  * of INBUF with length INLEN.
231  */
232 void sha1_write( void *context, const void *inbuf_arg, size_t inlen)
233 {
234  const unsigned char *inbuf = inbuf_arg;
235  SHA1_CONTEXT *hd = context;
236  size_t nblocks;
237 
238  if (hd->count == 64) /* Flush the buffer. */
239  {
240  TRANSFORM( hd, hd->buf, 1 );
241  hd->count = 0;
242  hd->nblocks++;
243  }
244  if (!inbuf)
245  return;
246 
247  if (hd->count)
248  {
249  for (; inlen && hd->count < 64; inlen--)
250  hd->buf[hd->count++] = *inbuf++;
251  sha1_write (hd, NULL, 0);
252  if (!inlen)
253  return;
254  }
255 
256  nblocks = inlen / 64;
257  if (nblocks)
258  {
259  TRANSFORM (hd, inbuf, nblocks);
260  hd->count = 0;
261  hd->nblocks += nblocks;
262  inlen -= nblocks * 64;
263  inbuf += nblocks * 64;
264  }
265 
266  /* Save remaining bytes. */
267  for (; inlen && hd->count < 64; inlen--)
268  hd->buf[hd->count++] = *inbuf++;
269 }
270 
271 
272 /* The routine final terminates the computation and
273  * returns the digest.
274  * The handle is prepared for a new cycle, but adding bytes to the
275  * handle will the destroy the returned buffer.
276  * Returns: 20 bytes representing the digest.
277  */
278 
279 void sha1_finish_ctx(void *context)
280 {
281  SHA1_CONTEXT *hd = context;
282 
283  uint32_t t, msb, lsb;
284  unsigned char *p;
285 
286  sha1_write(hd, NULL, 0); /* flush */;
287 
288  t = hd->nblocks;
289  /* multiply by 64 to make a byte count */
290  lsb = t << 6;
291  msb = t >> 26;
292  /* add the count */
293  t = lsb;
294  if( (lsb += hd->count) < t )
295  msb++;
296  /* multiply by 8 to make a bit count */
297  t = lsb;
298  lsb <<= 3;
299  msb <<= 3;
300  msb |= t >> 29;
301 
302  if( hd->count < 56 ) /* enough room */
303  {
304  hd->buf[hd->count++] = 0x80; /* pad */
305  while( hd->count < 56 )
306  hd->buf[hd->count++] = 0; /* pad */
307  }
308  else /* need one extra block */
309  {
310  hd->buf[hd->count++] = 0x80; /* pad character */
311  while( hd->count < 64 )
312  hd->buf[hd->count++] = 0;
313  sha1_write(hd, NULL, 0); /* flush */;
314  memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
315  }
316  /* append the 64 bit count */
317  hd->buf[56] = msb >> 24;
318  hd->buf[57] = msb >> 16;
319  hd->buf[58] = msb >> 8;
320  hd->buf[59] = msb ;
321  hd->buf[60] = lsb >> 24;
322  hd->buf[61] = lsb >> 16;
323  hd->buf[62] = lsb >> 8;
324  hd->buf[63] = lsb ;
325  TRANSFORM( hd, hd->buf, 1 );
326 
327  p = hd->buf;
328 #ifdef WORDS_BIGENDIAN
329 #define X(a) do { *(uint32_t*)p = hd->h##a ; p += 4; } while(0)
330 #else /* little endian */
331 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
332  *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
333 #endif
334  X(0);
335  X(1);
336  X(2);
337  X(3);
338  X(4);
339 #undef X
340 
341 }
342 
343 unsigned char *sha1_read( void *context )
344 {
345  SHA1_CONTEXT *hd = context;
346 
347  return hd->buf;
348 }
void sha1_write(void *context, const void *inbuf_arg, size_t inlen)
Definition: sha1.c:232
#define F1(x, y, z)
Definition: sha1.c:84
void sha1_finish_ctx(void *context)
Definition: sha1.c:279
#define R(a, b, c, d, e, f, k, m)
Definition: sha1.c:93
#define F4(x, y, z)
Definition: sha1.c:87
#define M(i)
Definition: sha1.c:88
#define TRANSFORM(x, d, n)
Definition: sha1.c:63
unsigned char * sha1_read(void *context)
Definition: sha1.c:343
#define F3(x, y, z)
Definition: sha1.c:86
#define K3
Definition: sha1.c:82
#define K1
Definition: sha1.c:80
#define K4
Definition: sha1.c:83
#define K2
Definition: sha1.c:81
static void transform(SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
Definition: sha1.c:104
#define X(a)
#define F2(x, y, z)
Definition: sha1.c:85
void sha1_init_ctx(void *context)
Definition: sha1.c:65
uint32_t nblocks
Definition: sha1.h:27
uint32_t h4
Definition: sha1.h:26
unsigned char buf[64]
Definition: sha1.h:28
uint32_t h2
Definition: sha1.h:26
uint32_t h0
Definition: sha1.h:26
uint32_t h1
Definition: sha1.h:26
int count
Definition: sha1.h:29
uint32_t h3
Definition: sha1.h:26