File Coverage

ulib/hash.c
Criterion Covered Total %
statement 295 310 95.1
branch 36 50 72.0
condition n/a
subroutine n/a
pod n/a
total 331 360 91.9


line stmt bran cond sub pod time code
1             #ifdef __cplusplus
2             extern "C" {
3             #endif
4              
5             #include "ulib/hash.h"
6             #include "ulib/pack.h"
7             #include "ulib/parse.h"
8              
9             #ifdef __cplusplus
10             }
11             #endif
12              
13             #ifdef MD5_DEBUG
14             #undef MD5_DEBUG
15             #endif
16              
17             static const char *hexdigits = "0123456789abcdef";
18              
19             /* borrowed from Digest::MD5 with gentle mangling */
20             /*----------------------------------------------------------------*/
21             /*
22             * This library is free software; you can redistribute it and/or
23             * modify it under the same terms as Perl itself.
24             *
25             * Copyright 1998-2000 Gisle Aas.
26             * Copyright 1995-1996 Neil Winton.
27             * Copyright 1991-1992 RSA Data Security, Inc.
28             *
29             * This code is derived from Neil Winton's MD5-1.7 Perl module, which in
30             * turn is derived from the reference implementation in RFC 1321 which
31             * comes with this message:
32             *
33             * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
34             * rights reserved.
35             *
36             * License to copy and use this software is granted provided that it
37             * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
38             * Algorithm" in all material mentioning or referencing this software
39             * or this function.
40             *
41             * License is also granted to make and use derivative works provided
42             * that such works are identified as "derived from the RSA Data
43             * Security, Inc. MD5 Message-Digest Algorithm" in all material
44             * mentioning or referencing the derived work.
45             *
46             * RSA Data Security, Inc. makes no representations concerning either
47             * the merchantability of this software or the suitability of this
48             * software for any particular purpose. It is provided "as is"
49             * without express or implied warranty of any kind.
50             *
51             * These notices must be retained in any copies of any part of this
52             * documentation and/or software.
53             */
54              
55             #ifndef PERL_UNUSED_VAR
56             # define PERL_UNUSED_VAR(x) ((void)x)
57             #endif
58              
59             #if PERL_VERSION < 8
60             # undef SvPVbyte
61             # define SvPVbyte(sv, lp) (sv_utf8_downgrade((sv), 0), SvPV((sv), (lp)))
62             #endif
63              
64             /* Perl does not guarantee that U32 is exactly 32 bits. Some system
65             * has no integral type with exactly 32 bits. For instance, A Cray has
66             * short, int and long all at 64 bits so we need to apply this macro
67             * to reduce U32 values to 32 bits at appropriate places. If U32
68             * really does have 32 bits then this is a no-op.
69             */
70             #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32)
71             #define TO32(x) ((x) & 0xFFFFffff)
72             #define TRUNC32(x) ((x) &= 0xFFFFffff)
73             #else
74             #define TO32(x) (x)
75             #define TRUNC32(x) /*nothing*/
76             #endif
77              
78             /* The MD5 algorithm is defined in terms of little endian 32-bit
79             * values. The following macros (and functions) allow us to convert
80             * between native integers and such values.
81             */
82 4320324           static void u2s(U32 u, U8* s)
83             {
84 4320324           *s++ = (U8)(u & 0xFF);
85 4320324           *s++ = (U8)((u >> 8) & 0xFF);
86 4320324           *s++ = (U8)((u >> 16) & 0xFF);
87 4320324           *s = (U8)((u >> 24) & 0xFF);
88 4320324           }
89              
90             #define s2u(s,u) ((u) = (U32)(*s) | \
91             ((U32)(*(s+1)) << 8) | \
92             ((U32)(*(s+2)) << 16) | \
93             ((U32)(*(s+3)) << 24))
94              
95             typedef struct {
96             U32 A, B, C, D; /* current digest */
97             U32 bytes_low; /* counts bytes in message */
98             U32 bytes_high; /* turn it into a 64-bit counter */
99             U8 buffer[128]; /* collect complete 64 byte blocks */
100             } MD5_CTX;
101              
102             /* Padding is added at the end of the message in order to fill a
103             * complete 64 byte block (- 8 bytes for the message length). The
104             * padding is also the reason the buffer in MD5_CTX have to be
105             * 128 bytes.
106             */
107             static const unsigned char PADDING[64] = {
108             0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
111             };
112              
113             /* Constants for MD5Transform routine.
114             */
115             #define S11 7
116             #define S12 12
117             #define S13 17
118             #define S14 22
119             #define S21 5
120             #define S22 9
121             #define S23 14
122             #define S24 20
123             #define S31 4
124             #define S32 11
125             #define S33 16
126             #define S34 23
127             #define S41 6
128             #define S42 10
129             #define S43 15
130             #define S44 21
131              
132             /* F, G, H and I are basic MD5 functions.
133             */
134             #define F(x, y, z) ((((x) & ((y) ^ (z))) ^ (z)))
135             #define G(x, y, z) F(z, x, y)
136             #define H(x, y, z) ((x) ^ (y) ^ (z))
137             #define I(x, y, z) ((y) ^ ((x) | (~z)))
138              
139             /* ROTATE_LEFT rotates x left n bits.
140             */
141             #define ROTATE_LEFT(x, n) (((x) << (n) | ((x) >> (32-(n)))))
142              
143             /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
144             * Rotation is separate from addition to prevent recomputation.
145             */
146             #define FF(a, b, c, d, s, ac) \
147             (a) += F ((b), (c), (d)) + (NEXTx) + (U32)(ac); \
148             TRUNC32((a)); \
149             (a) = ROTATE_LEFT ((a), (s)); \
150             (a) += (b); \
151             TRUNC32((a));
152              
153             #define GG(a, b, c, d, x, s, ac) \
154             (a) += G ((b), (c), (d)) + X[x] + (U32)(ac); \
155             TRUNC32((a)); \
156             (a) = ROTATE_LEFT ((a), (s)); \
157             (a) += (b); \
158             TRUNC32((a));
159              
160             #define HH(a, b, c, d, x, s, ac) \
161             (a) += H ((b), (c), (d)) + X[x] + (U32)(ac); \
162             TRUNC32((a)); \
163             (a) = ROTATE_LEFT ((a), (s)); \
164             (a) += (b); \
165             TRUNC32((a));
166              
167             #define II(a, b, c, d, x, s, ac) \
168             (a) += I ((b), (c), (d)) + X[x] + (U32)(ac); \
169             TRUNC32((a)); \
170             (a) = ROTATE_LEFT ((a), (s)); \
171             (a) += (b); \
172             TRUNC32((a));
173              
174 720054           static void MD5Init(MD5_CTX *ctx) {
175             /* Start state */
176 720054           ctx->A = 0x67452301;
177 720054           ctx->B = 0xefcdab89;
178 720054           ctx->C = 0x98badcfe;
179 720054           ctx->D = 0x10325476;
180              
181             /* message length */
182 720054           ctx->bytes_low = ctx->bytes_high = 0;
183 720054           }
184              
185 720054           static void MD5Transform(MD5_CTX* ctx, const U8* buf, STRLEN blocks) {
186             #ifdef MD5_DEBUG
187             static int tcount = 0;
188             #endif
189              
190 720054           U32 A = ctx->A;
191 720054           U32 B = ctx->B;
192 720054           U32 C = ctx->C;
193 720054           U32 D = ctx->D;
194              
195             do {
196 720054           U32 a = A;
197 720054           U32 b = B;
198 720054           U32 c = C;
199 720054           U32 d = D;
200              
201             U32 X[16]; /* little-endian values, used in round 2-4 */
202 720054           U32 *uptr = X;
203             U32 tmp;
204             #define NEXTx (s2u(buf,tmp), buf += 4, *uptr++ = tmp)
205              
206             #ifdef MD5_DEBUG
207             if (buf == ctx->buffer)
208             fprintf(stderr,"%5d: Transform ctx->buffer", ++tcount);
209             else
210             fprintf(stderr,"%5d: Transform %p (%d)", ++tcount, buf, blocks);
211              
212             {
213             int i;
214             fprintf(stderr,"[");
215             for (i = 0; i < 16; i++) {
216             fprintf(stderr,"%x,", X[i]); /* FIXME */
217             }
218             fprintf(stderr,"]\n");
219             }
220             #endif
221              
222             /* Round 1 */
223 720054           FF (a, b, c, d, S11, 0xd76aa478); /* 1 */
224 720054           FF (d, a, b, c, S12, 0xe8c7b756); /* 2 */
225 720054           FF (c, d, a, b, S13, 0x242070db); /* 3 */
226 720054           FF (b, c, d, a, S14, 0xc1bdceee); /* 4 */
227 720054           FF (a, b, c, d, S11, 0xf57c0faf); /* 5 */
228 720054           FF (d, a, b, c, S12, 0x4787c62a); /* 6 */
229 720054           FF (c, d, a, b, S13, 0xa8304613); /* 7 */
230 720054           FF (b, c, d, a, S14, 0xfd469501); /* 8 */
231 720054           FF (a, b, c, d, S11, 0x698098d8); /* 9 */
232 720054           FF (d, a, b, c, S12, 0x8b44f7af); /* 10 */
233 720054           FF (c, d, a, b, S13, 0xffff5bb1); /* 11 */
234 720054           FF (b, c, d, a, S14, 0x895cd7be); /* 12 */
235 720054           FF (a, b, c, d, S11, 0x6b901122); /* 13 */
236 720054           FF (d, a, b, c, S12, 0xfd987193); /* 14 */
237 720054           FF (c, d, a, b, S13, 0xa679438e); /* 15 */
238 720054           FF (b, c, d, a, S14, 0x49b40821); /* 16 */
239              
240             /* Round 2 */
241 720054           GG (a, b, c, d, 1, S21, 0xf61e2562); /* 17 */
242 720054           GG (d, a, b, c, 6, S22, 0xc040b340); /* 18 */
243 720054           GG (c, d, a, b, 11, S23, 0x265e5a51); /* 19 */
244 720054           GG (b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
245 720054           GG (a, b, c, d, 5, S21, 0xd62f105d); /* 21 */
246 720054           GG (d, a, b, c, 10, S22, 0x2441453); /* 22 */
247 720054           GG (c, d, a, b, 15, S23, 0xd8a1e681); /* 23 */
248 720054           GG (b, c, d, a, 4, S24, 0xe7d3fbc8); /* 24 */
249 720054           GG (a, b, c, d, 9, S21, 0x21e1cde6); /* 25 */
250 720054           GG (d, a, b, c, 14, S22, 0xc33707d6); /* 26 */
251 720054           GG (c, d, a, b, 3, S23, 0xf4d50d87); /* 27 */
252 720054           GG (b, c, d, a, 8, S24, 0x455a14ed); /* 28 */
253 720054           GG (a, b, c, d, 13, S21, 0xa9e3e905); /* 29 */
254 720054           GG (d, a, b, c, 2, S22, 0xfcefa3f8); /* 30 */
255 720054           GG (c, d, a, b, 7, S23, 0x676f02d9); /* 31 */
256 720054           GG (b, c, d, a, 12, S24, 0x8d2a4c8a); /* 32 */
257              
258             /* Round 3 */
259 720054           HH (a, b, c, d, 5, S31, 0xfffa3942); /* 33 */
260 720054           HH (d, a, b, c, 8, S32, 0x8771f681); /* 34 */
261 720054           HH (c, d, a, b, 11, S33, 0x6d9d6122); /* 35 */
262 720054           HH (b, c, d, a, 14, S34, 0xfde5380c); /* 36 */
263 720054           HH (a, b, c, d, 1, S31, 0xa4beea44); /* 37 */
264 720054           HH (d, a, b, c, 4, S32, 0x4bdecfa9); /* 38 */
265 720054           HH (c, d, a, b, 7, S33, 0xf6bb4b60); /* 39 */
266 720054           HH (b, c, d, a, 10, S34, 0xbebfbc70); /* 40 */
267 720054           HH (a, b, c, d, 13, S31, 0x289b7ec6); /* 41 */
268 720054           HH (d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
269 720054           HH (c, d, a, b, 3, S33, 0xd4ef3085); /* 43 */
270 720054           HH (b, c, d, a, 6, S34, 0x4881d05); /* 44 */
271 720054           HH (a, b, c, d, 9, S31, 0xd9d4d039); /* 45 */
272 720054           HH (d, a, b, c, 12, S32, 0xe6db99e5); /* 46 */
273 720054           HH (c, d, a, b, 15, S33, 0x1fa27cf8); /* 47 */
274 720054           HH (b, c, d, a, 2, S34, 0xc4ac5665); /* 48 */
275              
276             /* Round 4 */
277 720054           II (a, b, c, d, 0, S41, 0xf4292244); /* 49 */
278 720054           II (d, a, b, c, 7, S42, 0x432aff97); /* 50 */
279 720054           II (c, d, a, b, 14, S43, 0xab9423a7); /* 51 */
280 720054           II (b, c, d, a, 5, S44, 0xfc93a039); /* 52 */
281 720054           II (a, b, c, d, 12, S41, 0x655b59c3); /* 53 */
282 720054           II (d, a, b, c, 3, S42, 0x8f0ccc92); /* 54 */
283 720054           II (c, d, a, b, 10, S43, 0xffeff47d); /* 55 */
284 720054           II (b, c, d, a, 1, S44, 0x85845dd1); /* 56 */
285 720054           II (a, b, c, d, 8, S41, 0x6fa87e4f); /* 57 */
286 720054           II (d, a, b, c, 15, S42, 0xfe2ce6e0); /* 58 */
287 720054           II (c, d, a, b, 6, S43, 0xa3014314); /* 59 */
288 720054           II (b, c, d, a, 13, S44, 0x4e0811a1); /* 60 */
289 720054           II (a, b, c, d, 4, S41, 0xf7537e82); /* 61 */
290 720054           II (d, a, b, c, 11, S42, 0xbd3af235); /* 62 */
291 720054           II (c, d, a, b, 2, S43, 0x2ad7d2bb); /* 63 */
292 720054           II (b, c, d, a, 9, S44, 0xeb86d391); /* 64 */
293              
294 720054           A += a; TRUNC32(A);
295 720054           B += b; TRUNC32(B);
296 720054           C += c; TRUNC32(C);
297 720054           D += d; TRUNC32(D);
298              
299 720054 50         } while (--blocks);
300 720054           ctx->A = A;
301 720054           ctx->B = B;
302 720054           ctx->C = C;
303 720054           ctx->D = D;
304 720054           }
305              
306             #ifdef MD5_DEBUG
307             static char*
308             ctx_dump(MD5_CTX* ctx)
309             {
310             static char buf[1024];
311             sprintf(buf, "{A=%x,B=%x,C=%x,D=%x,%d,%d(%d)}",
312             ctx->A, ctx->B, ctx->C, ctx->D,
313             ctx->bytes_low, ctx->bytes_high, (ctx->bytes_low&0x3F));
314             return buf;
315             }
316             #endif
317              
318 1440108           static void MD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len) {
319             STRLEN blocks;
320 1440108           STRLEN fill = ctx->bytes_low & 0x3F;
321              
322             #ifdef MD5_DEBUG
323             static int ucount = 0;
324             fprintf(stderr,"%5i: Update(%s, %p, %d)\n", ++ucount, ctx_dump(ctx), buf, len);
325             #endif
326              
327 1440108           ctx->bytes_low += (U32)len;
328 1440108 50         if (ctx->bytes_low < len) /* wrap around */
329 0           ctx->bytes_high++;
330              
331 1440108 100         if (fill) {
332 720054           STRLEN missing = 64 - fill;
333 720054 50         if (len < missing) {
334 720054           Copy(buf, ctx->buffer + fill, len, U8);
335 720054           return;
336             }
337 0           Copy(buf, ctx->buffer + fill, missing, U8);
338 0           MD5Transform(ctx, ctx->buffer, 1);
339 0           buf += missing;
340 0           len -= missing;
341             }
342              
343 720054           blocks = len >> 6;
344 720054 50         if (blocks)
345 0           MD5Transform(ctx, buf, blocks);
346 720054 50         if ( (len &= 0x3F)) {
347 720054           Copy(buf + (blocks << 6), ctx->buffer, len, U8);
348             }
349             }
350              
351 720054           static void MD5Final(U8* digest, MD5_CTX *ctx) {
352 720054           STRLEN fill = ctx->bytes_low & 0x3F;
353 720054 50         STRLEN padlen = (fill < 56 ? 56 : 120) - fill;
354             U32 bits_low, bits_high;
355             #ifdef MD5_DEBUG
356             fprintf(stderr," Final: %s\n", ctx_dump(ctx));
357             #endif
358 720054           Copy(PADDING, ctx->buffer + fill, padlen, U8);
359 720054           fill += padlen;
360              
361 720054           bits_low = ctx->bytes_low << 3;
362 720054           bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low >> 29);
363 720054           u2s(bits_low, ctx->buffer + fill); fill += 4;
364 720054           u2s(bits_high, ctx->buffer + fill); fill += 4;
365              
366 720054           MD5Transform(ctx, ctx->buffer, fill >> 6);
367             #ifdef MD5_DEBUG
368             fprintf(stderr," Result: %s\n", ctx_dump(ctx));
369             #endif
370              
371 720054           u2s(ctx->A, digest);
372 720054           u2s(ctx->B, digest+4);
373 720054           u2s(ctx->C, digest+8);
374 720054           u2s(ctx->D, digest+12);
375 720054           }
376             /*----------------------------------------------------------------*/
377              
378             /* declared above since also used in sha1
379             static const char *hexdigits = "0123456789abcdef";
380             */
381              
382 720054           static void hex_16(const unsigned char* from, char* to) {
383 720054           const unsigned char *end = from + 16;
384 720054           char *d = to;
385              
386 12240918 100         while (from < end) {
387 11520864           *d++ = hexdigits[(*from >> 4)];
388 11520864           *d++ = hexdigits[(*from & 0x0F)];
389 11520864           from++;
390             }
391 720054           *d = '\0';
392 720054           }
393              
394 720054           void uu_hash_md5(pUCXT, struct_uu_t *io, char *name) {
395             /* io is assumed to be a v1 namespace uuid coming in. */
396             /* name is... a name. */
397             MD5_CTX context;
398             char tmp[37];
399             char vardig;
400             unsigned char digeststr[21];
401             uu_t packed;
402              
403 720054           uu_pack_v1(io, (U8*)&packed);
404              
405 720054           MD5Init(&context);
406              
407 720054           MD5Update(&context, (U8*)&packed, sizeof(packed));
408 720054 50         if (name)
409 720054           MD5Update(&context, (U8*)name, strlen(name));
410              
411 720054           MD5Final((U8*)digeststr, &context);
412 720054           digeststr[20] = '\0';
413              
414 720054           hex_16(digeststr, tmp);
415 720054           tmp[32] = '\0';
416              
417             /* hyphenate */
418 720054           Move(&tmp[20], &tmp[21], 12, char); tmp[20] = '-';
419 720054           Move(&tmp[16], &tmp[17], 17, char); tmp[16] = '-';
420 720054           Move(&tmp[12], &tmp[13], 22, char); tmp[12] = '-';
421 720054           Move(&tmp[ 8], &tmp[ 9], 27, char); tmp[ 8] = '-';
422 720054           tmp[36] = '\0';
423              
424             /* version */
425 720054           tmp[14] = '3';
426              
427             /* variant */
428 720054           vardig = tmp[19] - 48;
429 720054 100         if (vardig > 9) vardig -= 7;
430 720054 100         if (vardig > 15) vardig -= 32;
431 720054           vardig = (vardig & 0x3) | 0x8;
432 720054 100         if (vardig > 9) vardig += 87;
433 200047           else vardig += 48;
434 720054           tmp[19] = vardig;
435              
436 720054           uu_parse(tmp, io);
437 720054           }
438              
439              
440             /******************************************************************/
441             /******************************************************************/
442             /******************************************************************/
443              
444              
445             /* borrowed from Digest::SHA1 */
446             /*----------------------------------------------------------------*/
447             /* NIST Secure Hash Algorithm */
448             /* heavily modified by Uwe Hollerbach */
449             /* from Peter C. Gutmann's implementation as found in */
450             /* Applied Cryptography by Bruce Schneier */
451             /* Further modifications to include the "UNRAVEL" stuff, below */
452              
453             /* This code is in the public domain */
454              
455             /* Useful defines & typedefs */
456              
457             #if defined(U64TYPE) && (defined(USE_64_BIT_INT) || ((BYTEORDER != 0x1234) && (BYTEORDER != 0x4321)))
458             typedef U64TYPE ULONGx;
459             # if BYTEORDER == 0x1234
460             # undef BYTEORDER
461             # define BYTEORDER 0x12345678
462             # elif BYTEORDER == 0x4321
463             # undef BYTEORDER
464             # define BYTEORDER 0x87654321
465             # endif
466             #else
467             typedef unsigned long ULONGx; /* 32-or-more-bit quantity */
468             #endif
469              
470             #define SHA_BLOCKSIZE 64
471             #define SHA_DIGESTSIZE 20
472              
473             typedef struct {
474             ULONGx digest[5]; /* message digest */
475             ULONGx count_lo, count_hi; /* 64-bit bit count */
476             U8 data[SHA_BLOCKSIZE]; /* SHA data buffer */
477             int local; /* unprocessed amount in data */
478             } SHA_INFO;
479              
480              
481             /* UNRAVEL should be fastest & biggest */
482             /* UNROLL_LOOPS should be just as big, but slightly slower */
483             /* both undefined should be smallest and slowest */
484              
485             #define SHA_VERSION 1
486             #define UNRAVEL
487             /* #define UNROLL_LOOPS */
488             /* SHA f()-functions */
489             #define f1(x,y,z) ((x & y) | (~x & z))
490             #define f2(x,y,z) (x ^ y ^ z)
491             #define f3(x,y,z) ((x & y) | (x & z) | (y & z))
492             #define f4(x,y,z) (x ^ y ^ z)
493              
494             /* SHA constants */
495             #define CONST1 0x5a827999L
496             #define CONST2 0x6ed9eba1L
497             #define CONST3 0x8f1bbcdcL
498             #define CONST4 0xca62c1d6L
499              
500             /* truncate to 32 bits -- should be a null op on 32-bit machines */
501             #define T32(x) ((x) & 0xffffffffL)
502              
503             /* 32-bit rotate */
504             #define R32(x,n) T32(((x << n) | (x >> (32 - n))))
505              
506             /* the generic case, for when the overall rotation is not unraveled */
507             #define FG(n) \
508             T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); \
509             E = D; D = C; C = R32(B,30); B = A; A = T
510              
511             /* specific cases, for when the overall rotation is unraveled */
512             #define FA(n) \
513             T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); B = R32(B,30)
514              
515             #define FB(n) \
516             E = T32(R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n); A = R32(A,30)
517              
518             #define FC(n) \
519             D = T32(R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n); T = R32(T,30)
520              
521             #define FD(n) \
522             C = T32(R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n); E = R32(E,30)
523              
524             #define FE(n) \
525             B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30)
526              
527             #define FT(n) \
528             A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30)
529              
530 720048           static void sha_transform(SHA_INFO *sha_info)
531             {
532             int i;
533             U8 *dp;
534             ULONGx T, A, B, C, D, E, W[80], *WP;
535              
536 720048           dp = sha_info->data;
537              
538             /*
539             the following makes sure that at least one code block below is
540             traversed or an error is reported, without the necessity for nested
541             preprocessor if/else/endif blocks, which are a great pain in the
542             nether regions of the anatomy...
543             */
544             #undef SWAP_DONE
545              
546             #if BYTEORDER == 0x1234
547             #define SWAP_DONE
548             /* assert(sizeof(ULONGx) == 4); */
549             for (i = 0; i < 16; ++i) {
550             T = *((ULONGx *) dp);
551             dp += 4;
552             W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
553             ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
554             }
555             #endif
556              
557             #if BYTEORDER == 0x4321
558             #define SWAP_DONE
559             /* assert(sizeof(ULONGx) == 4); */
560             for (i = 0; i < 16; ++i) {
561             T = *((ULONGx *) dp);
562             dp += 4;
563             W[i] = T32(T);
564             }
565             #endif
566              
567             #if BYTEORDER == 0x12345678
568             #define SWAP_DONE
569             /* assert(sizeof(ULONGx) == 8); */
570 6480432 100         for (i = 0; i < 16; i += 2) {
571 5760384           T = *((ULONGx *) dp);
572 5760384           dp += 8;
573 5760384           W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
574 5760384           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
575 5760384           T >>= 32;
576 5760384           W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
577 5760384           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
578             }
579             #endif
580              
581             #if BYTEORDER == 0x87654321
582             #define SWAP_DONE
583             /* assert(sizeof(ULONGx) == 8); */
584             for (i = 0; i < 16; i += 2) {
585             T = *((ULONGx *) dp);
586             dp += 8;
587             W[i] = T32(T >> 32);
588             W[i+1] = T32(T);
589             }
590             #endif
591              
592             #ifndef SWAP_DONE
593             #error Unknown byte order -- you need to add code here
594             #endif /* SWAP_DONE */
595              
596 46803120 100         for (i = 16; i < 80; ++i) {
597 46083072           W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
598             #if (SHA_VERSION == 1)
599 46083072           W[i] = R32(W[i], 1);
600             #endif /* SHA_VERSION */
601             }
602 720048           A = sha_info->digest[0];
603 720048           B = sha_info->digest[1];
604 720048           C = sha_info->digest[2];
605 720048           D = sha_info->digest[3];
606 720048           E = sha_info->digest[4];
607 720048           WP = W;
608             #ifdef UNRAVEL
609 720048           FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
610 720048           FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
611 720048           FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
612 720048           FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
613 720048           FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
614 720048           FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
615 720048           FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
616 720048           FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
617 720048           sha_info->digest[0] = T32(sha_info->digest[0] + E);
618 720048           sha_info->digest[1] = T32(sha_info->digest[1] + T);
619 720048           sha_info->digest[2] = T32(sha_info->digest[2] + A);
620 720048           sha_info->digest[3] = T32(sha_info->digest[3] + B);
621 720048           sha_info->digest[4] = T32(sha_info->digest[4] + C);
622             #else /* !UNRAVEL */
623             #ifdef UNROLL_LOOPS
624             FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
625             FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
626             FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
627             FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
628             FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
629             FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
630             FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
631             FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
632             #else /* !UNROLL_LOOPS */
633             for (i = 0; i < 20; ++i) { FG(1); }
634             for (i = 20; i < 40; ++i) { FG(2); }
635             for (i = 40; i < 60; ++i) { FG(3); }
636             for (i = 60; i < 80; ++i) { FG(4); }
637             #endif /* !UNROLL_LOOPS */
638             sha_info->digest[0] = T32(sha_info->digest[0] + A);
639             sha_info->digest[1] = T32(sha_info->digest[1] + B);
640             sha_info->digest[2] = T32(sha_info->digest[2] + C);
641             sha_info->digest[3] = T32(sha_info->digest[3] + D);
642             sha_info->digest[4] = T32(sha_info->digest[4] + E);
643             #endif /* !UNRAVEL */
644 720048           }
645              
646             /* initialize the SHA digest */
647              
648 720048           static void sha_init(SHA_INFO *sha_info)
649             {
650 720048           sha_info->digest[0] = 0x67452301L;
651 720048           sha_info->digest[1] = 0xefcdab89L;
652 720048           sha_info->digest[2] = 0x98badcfeL;
653 720048           sha_info->digest[3] = 0x10325476L;
654 720048           sha_info->digest[4] = 0xc3d2e1f0L;
655 720048           sha_info->count_lo = 0L;
656 720048           sha_info->count_hi = 0L;
657 720048           sha_info->local = 0;
658 720048           }
659              
660             /* update the SHA digest */
661              
662 1440096           static void sha_update(SHA_INFO *sha_info, U8 *buffer, int count)
663             {
664             int i;
665             ULONGx clo;
666              
667 1440096           clo = T32(sha_info->count_lo + ((ULONGx) count << 3));
668 1440096 50         if (clo < sha_info->count_lo) {
669 0           ++sha_info->count_hi;
670             }
671 1440096           sha_info->count_lo = clo;
672 1440096           sha_info->count_hi += (ULONGx) count >> 29;
673 1440096 100         if (sha_info->local) {
674 720048           i = SHA_BLOCKSIZE - sha_info->local;
675 720048 50         if (i > count) {
676 720048           i = count;
677             }
678 720048           memcpy(((U8 *) sha_info->data) + sha_info->local, buffer, i);
679 720048           count -= i;
680 720048           buffer += i;
681 720048           sha_info->local += i;
682 720048 50         if (sha_info->local == SHA_BLOCKSIZE) {
683 0           sha_transform(sha_info);
684             } else {
685 720048           return;
686             }
687             }
688 720048 50         while (count >= SHA_BLOCKSIZE) {
689 0           memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
690 0           buffer += SHA_BLOCKSIZE;
691 0           count -= SHA_BLOCKSIZE;
692 0           sha_transform(sha_info);
693             }
694 720048           memcpy(sha_info->data, buffer, count);
695 720048           sha_info->local = count;
696             }
697              
698              
699 720048           static void sha_transform_and_copy(unsigned char digest[20], SHA_INFO *sha_info)
700             {
701 720048           sha_transform(sha_info);
702 720048           digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
703 720048           digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
704 720048           digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
705 720048           digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
706 720048           digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
707 720048           digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
708 720048           digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
709 720048           digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
710 720048           digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
711 720048           digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
712 720048           digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
713 720048           digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
714 720048           digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
715 720048           digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
716 720048           digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
717 720048           digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
718 720048           digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
719 720048           digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
720 720048           digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
721 720048           digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
722 720048           }
723              
724             /* finish computing the SHA digest */
725 720048           static void sha_final(unsigned char digest[20], SHA_INFO *sha_info)
726             {
727             int count;
728             ULONGx lo_bit_count, hi_bit_count;
729              
730 720048           lo_bit_count = sha_info->count_lo;
731 720048           hi_bit_count = sha_info->count_hi;
732 720048           count = (int) ((lo_bit_count >> 3) & 0x3f);
733 720048           ((U8 *) sha_info->data)[count++] = 0x80;
734 720048 50         if (count > SHA_BLOCKSIZE - 8) {
735 0           memset(((U8 *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count);
736 0           sha_transform(sha_info);
737 0           memset((U8 *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
738             } else {
739 720048           memset(((U8 *) sha_info->data) + count, 0,
740 720048           SHA_BLOCKSIZE - 8 - count);
741             }
742 720048           sha_info->data[56] = (U8)((hi_bit_count >> 24) & 0xff);
743 720048           sha_info->data[57] = (U8)((hi_bit_count >> 16) & 0xff);
744 720048           sha_info->data[58] = (U8)((hi_bit_count >> 8) & 0xff);
745 720048           sha_info->data[59] = (U8)((hi_bit_count >> 0) & 0xff);
746 720048           sha_info->data[60] = (U8)((lo_bit_count >> 24) & 0xff);
747 720048           sha_info->data[61] = (U8)((lo_bit_count >> 16) & 0xff);
748 720048           sha_info->data[62] = (U8)((lo_bit_count >> 8) & 0xff);
749 720048           sha_info->data[63] = (U8)((lo_bit_count >> 0) & 0xff);
750 720048           sha_transform_and_copy(digest, sha_info);
751 720048           }
752             /*----------------------------------------------------------------*/
753              
754             /* declared above since also used in md5
755             static const char *hexdigits = "0123456789abcdef";
756             */
757              
758 720048           static void hex_20(const unsigned char* from, char* to) {
759 720048           const unsigned char *end = from + 20;
760 720048           char *d = to;
761              
762 15121008 100         while (from < end) {
763 14400960           *d++ = hexdigits[(*from >> 4)];
764 14400960           *d++ = hexdigits[(*from & 0x0F)];
765 14400960           from++;
766             }
767 720048           *d = '\0';
768 720048           }
769              
770 720048           void uu_hash_sha1(pUCXT, struct_uu_t *io, char *name) {
771             /* io is assumed to be a v1 namespace uuid coming in. */
772             /* do hton*() here. */
773             /* name is... a name. */
774             SHA_INFO context;
775             char tmp[41];
776             char vardig;
777             unsigned char digeststr[21];
778             uu_t packed;
779              
780 720048           uu_pack_v1(io, (U8*)&packed);
781              
782 720048           sha_init(&context);
783              
784 720048           sha_update(&context, (U8*)&packed, sizeof(packed));
785 720048 50         if (name)
786 720048           sha_update(&context, (U8*)name, (int)strlen(name));
787              
788 720048           sha_final((U8*)&digeststr, &context);
789 720048           digeststr[20] = '\0';
790              
791 720048           hex_20(digeststr, tmp);
792 720048           tmp[32] = '\0';
793              
794             /* hyphenate */
795 720048           Move(&tmp[20], &tmp[21], 12, char); tmp[20] = '-';
796 720048           Move(&tmp[16], &tmp[17], 17, char); tmp[16] = '-';
797 720048           Move(&tmp[12], &tmp[13], 22, char); tmp[12] = '-';
798 720048           Move(&tmp[ 8], &tmp[ 9], 27, char); tmp[ 8] = '-';
799 720048           tmp[36] = '\0';
800              
801             /* version */
802 720048           tmp[14] = '5';
803              
804             /* variant */
805 720048           vardig = tmp[19] - 48;
806 720048 100         if (vardig > 9) vardig -= 7;
807 720048 100         if (vardig > 15) vardig -= 32;
808 720048           vardig = (vardig & 0x3) | 0x8;
809 720048 50         if (vardig > 9) vardig += 87;
810 720048           else vardig += 48;
811 720048           tmp[19] = vardig;
812              
813 720048           uu_parse(tmp, io);
814 720048           }
815              
816             /* ex:set ts=2 sw=2 itab=spaces: */