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 108324           static void u2s(U32 u, U8* s)
83             {
84 108324           *s++ = (U8)(u & 0xFF);
85 108324           *s++ = (U8)((u >> 8) & 0xFF);
86 108324           *s++ = (U8)((u >> 16) & 0xFF);
87 108324           *s = (U8)((u >> 24) & 0xFF);
88 108324           }
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 18054           static void MD5Init(MD5_CTX *ctx) {
175             /* Start state */
176 18054           ctx->A = 0x67452301;
177 18054           ctx->B = 0xefcdab89;
178 18054           ctx->C = 0x98badcfe;
179 18054           ctx->D = 0x10325476;
180              
181             /* message length */
182 18054           ctx->bytes_low = ctx->bytes_high = 0;
183 18054           }
184              
185 18054           static void MD5Transform(MD5_CTX* ctx, const U8* buf, STRLEN blocks) {
186             #ifdef MD5_DEBUG
187             static int tcount = 0;
188             #endif
189              
190 18054           U32 A = ctx->A;
191 18054           U32 B = ctx->B;
192 18054           U32 C = ctx->C;
193 18054           U32 D = ctx->D;
194              
195             do {
196 18054           U32 a = A;
197 18054           U32 b = B;
198 18054           U32 c = C;
199 18054           U32 d = D;
200              
201             U32 X[16]; /* little-endian values, used in round 2-4 */
202 18054           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 18054           FF (a, b, c, d, S11, 0xd76aa478); /* 1 */
224 18054           FF (d, a, b, c, S12, 0xe8c7b756); /* 2 */
225 18054           FF (c, d, a, b, S13, 0x242070db); /* 3 */
226 18054           FF (b, c, d, a, S14, 0xc1bdceee); /* 4 */
227 18054           FF (a, b, c, d, S11, 0xf57c0faf); /* 5 */
228 18054           FF (d, a, b, c, S12, 0x4787c62a); /* 6 */
229 18054           FF (c, d, a, b, S13, 0xa8304613); /* 7 */
230 18054           FF (b, c, d, a, S14, 0xfd469501); /* 8 */
231 18054           FF (a, b, c, d, S11, 0x698098d8); /* 9 */
232 18054           FF (d, a, b, c, S12, 0x8b44f7af); /* 10 */
233 18054           FF (c, d, a, b, S13, 0xffff5bb1); /* 11 */
234 18054           FF (b, c, d, a, S14, 0x895cd7be); /* 12 */
235 18054           FF (a, b, c, d, S11, 0x6b901122); /* 13 */
236 18054           FF (d, a, b, c, S12, 0xfd987193); /* 14 */
237 18054           FF (c, d, a, b, S13, 0xa679438e); /* 15 */
238 18054           FF (b, c, d, a, S14, 0x49b40821); /* 16 */
239              
240             /* Round 2 */
241 18054           GG (a, b, c, d, 1, S21, 0xf61e2562); /* 17 */
242 18054           GG (d, a, b, c, 6, S22, 0xc040b340); /* 18 */
243 18054           GG (c, d, a, b, 11, S23, 0x265e5a51); /* 19 */
244 18054           GG (b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
245 18054           GG (a, b, c, d, 5, S21, 0xd62f105d); /* 21 */
246 18054           GG (d, a, b, c, 10, S22, 0x2441453); /* 22 */
247 18054           GG (c, d, a, b, 15, S23, 0xd8a1e681); /* 23 */
248 18054           GG (b, c, d, a, 4, S24, 0xe7d3fbc8); /* 24 */
249 18054           GG (a, b, c, d, 9, S21, 0x21e1cde6); /* 25 */
250 18054           GG (d, a, b, c, 14, S22, 0xc33707d6); /* 26 */
251 18054           GG (c, d, a, b, 3, S23, 0xf4d50d87); /* 27 */
252 18054           GG (b, c, d, a, 8, S24, 0x455a14ed); /* 28 */
253 18054           GG (a, b, c, d, 13, S21, 0xa9e3e905); /* 29 */
254 18054           GG (d, a, b, c, 2, S22, 0xfcefa3f8); /* 30 */
255 18054           GG (c, d, a, b, 7, S23, 0x676f02d9); /* 31 */
256 18054           GG (b, c, d, a, 12, S24, 0x8d2a4c8a); /* 32 */
257              
258             /* Round 3 */
259 18054           HH (a, b, c, d, 5, S31, 0xfffa3942); /* 33 */
260 18054           HH (d, a, b, c, 8, S32, 0x8771f681); /* 34 */
261 18054           HH (c, d, a, b, 11, S33, 0x6d9d6122); /* 35 */
262 18054           HH (b, c, d, a, 14, S34, 0xfde5380c); /* 36 */
263 18054           HH (a, b, c, d, 1, S31, 0xa4beea44); /* 37 */
264 18054           HH (d, a, b, c, 4, S32, 0x4bdecfa9); /* 38 */
265 18054           HH (c, d, a, b, 7, S33, 0xf6bb4b60); /* 39 */
266 18054           HH (b, c, d, a, 10, S34, 0xbebfbc70); /* 40 */
267 18054           HH (a, b, c, d, 13, S31, 0x289b7ec6); /* 41 */
268 18054           HH (d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
269 18054           HH (c, d, a, b, 3, S33, 0xd4ef3085); /* 43 */
270 18054           HH (b, c, d, a, 6, S34, 0x4881d05); /* 44 */
271 18054           HH (a, b, c, d, 9, S31, 0xd9d4d039); /* 45 */
272 18054           HH (d, a, b, c, 12, S32, 0xe6db99e5); /* 46 */
273 18054           HH (c, d, a, b, 15, S33, 0x1fa27cf8); /* 47 */
274 18054           HH (b, c, d, a, 2, S34, 0xc4ac5665); /* 48 */
275              
276             /* Round 4 */
277 18054           II (a, b, c, d, 0, S41, 0xf4292244); /* 49 */
278 18054           II (d, a, b, c, 7, S42, 0x432aff97); /* 50 */
279 18054           II (c, d, a, b, 14, S43, 0xab9423a7); /* 51 */
280 18054           II (b, c, d, a, 5, S44, 0xfc93a039); /* 52 */
281 18054           II (a, b, c, d, 12, S41, 0x655b59c3); /* 53 */
282 18054           II (d, a, b, c, 3, S42, 0x8f0ccc92); /* 54 */
283 18054           II (c, d, a, b, 10, S43, 0xffeff47d); /* 55 */
284 18054           II (b, c, d, a, 1, S44, 0x85845dd1); /* 56 */
285 18054           II (a, b, c, d, 8, S41, 0x6fa87e4f); /* 57 */
286 18054           II (d, a, b, c, 15, S42, 0xfe2ce6e0); /* 58 */
287 18054           II (c, d, a, b, 6, S43, 0xa3014314); /* 59 */
288 18054           II (b, c, d, a, 13, S44, 0x4e0811a1); /* 60 */
289 18054           II (a, b, c, d, 4, S41, 0xf7537e82); /* 61 */
290 18054           II (d, a, b, c, 11, S42, 0xbd3af235); /* 62 */
291 18054           II (c, d, a, b, 2, S43, 0x2ad7d2bb); /* 63 */
292 18054           II (b, c, d, a, 9, S44, 0xeb86d391); /* 64 */
293              
294 18054           A += a; TRUNC32(A);
295 18054           B += b; TRUNC32(B);
296 18054           C += c; TRUNC32(C);
297 18054           D += d; TRUNC32(D);
298              
299 18054 50         } while (--blocks);
300 18054           ctx->A = A;
301 18054           ctx->B = B;
302 18054           ctx->C = C;
303 18054           ctx->D = D;
304 18054           }
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 36108           static void MD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len) {
319             STRLEN blocks;
320 36108           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 36108           ctx->bytes_low += (U32)len;
328 36108 50         if (ctx->bytes_low < len) /* wrap around */
329 0           ctx->bytes_high++;
330              
331 36108 100         if (fill) {
332 18054           STRLEN missing = 64 - fill;
333 18054 50         if (len < missing) {
334 18054           Copy(buf, ctx->buffer + fill, len, U8);
335 18054           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 18054           blocks = len >> 6;
344 18054 50         if (blocks)
345 0           MD5Transform(ctx, buf, blocks);
346 18054 50         if ( (len &= 0x3F)) {
347 18054           Copy(buf + (blocks << 6), ctx->buffer, len, U8);
348             }
349             }
350              
351 18054           static void MD5Final(U8* digest, MD5_CTX *ctx) {
352 18054           STRLEN fill = ctx->bytes_low & 0x3F;
353 18054 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 18054           Copy(PADDING, ctx->buffer + fill, padlen, U8);
359 18054           fill += padlen;
360              
361 18054           bits_low = ctx->bytes_low << 3;
362 18054           bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low >> 29);
363 18054           u2s(bits_low, ctx->buffer + fill); fill += 4;
364 18054           u2s(bits_high, ctx->buffer + fill); fill += 4;
365              
366 18054           MD5Transform(ctx, ctx->buffer, fill >> 6);
367             #ifdef MD5_DEBUG
368             fprintf(stderr," Result: %s\n", ctx_dump(ctx));
369             #endif
370              
371 18054           u2s(ctx->A, digest);
372 18054           u2s(ctx->B, digest+4);
373 18054           u2s(ctx->C, digest+8);
374 18054           u2s(ctx->D, digest+12);
375 18054           }
376             /*----------------------------------------------------------------*/
377              
378             /* declared above since also used in sha1
379             static const char *hexdigits = "0123456789abcdef";
380             */
381              
382 18054           static void hex_16(const unsigned char* from, char* to) {
383 18054           const unsigned char *end = from + 16;
384 18054           char *d = to;
385              
386 306918 100         while (from < end) {
387 288864           *d++ = hexdigits[(*from >> 4)];
388 288864           *d++ = hexdigits[(*from & 0x0F)];
389 288864           from++;
390             }
391 18054           *d = '\0';
392 18054           }
393              
394 18054           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 18054           uu_pack_v1(io, (U8*)&packed);
404              
405 18054           MD5Init(&context);
406              
407 18054           MD5Update(&context, (U8*)&packed, sizeof(packed));
408 18054 50         if (name)
409 18054           MD5Update(&context, (U8*)name, strlen(name));
410              
411 18054           MD5Final((U8*)digeststr, &context);
412 18054           digeststr[20] = '\0';
413              
414 18054           hex_16(digeststr, tmp);
415 18054           tmp[32] = '\0';
416              
417             /* hyphenate */
418 18054           Move(&tmp[20], &tmp[21], 12, char); tmp[20] = '-';
419 18054           Move(&tmp[16], &tmp[17], 17, char); tmp[16] = '-';
420 18054           Move(&tmp[12], &tmp[13], 22, char); tmp[12] = '-';
421 18054           Move(&tmp[ 8], &tmp[ 9], 27, char); tmp[ 8] = '-';
422 18054           tmp[36] = '\0';
423              
424             /* version */
425 18054           tmp[14] = '3';
426              
427             /* variant */
428 18054           vardig = tmp[19] - 48;
429 18054 100         if (vardig > 9) vardig -= 7;
430 18054 100         if (vardig > 15) vardig -= 32;
431 18054           vardig = (vardig & 0x3) | 0x8;
432 18054 100         if (vardig > 9) vardig += 87;
433 4047           else vardig += 48;
434 18054           tmp[19] = vardig;
435              
436 18054           uu_parse(tmp, io);
437 18054           }
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 18048           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 18048           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 162432 100         for (i = 0; i < 16; i += 2) {
571 144384           T = *((ULONGx *) dp);
572 144384           dp += 8;
573 144384           W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
574 144384           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
575 144384           T >>= 32;
576 144384           W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
577 144384           ((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 1173120 100         for (i = 16; i < 80; ++i) {
597 1155072           W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
598             #if (SHA_VERSION == 1)
599 1155072           W[i] = R32(W[i], 1);
600             #endif /* SHA_VERSION */
601             }
602 18048           A = sha_info->digest[0];
603 18048           B = sha_info->digest[1];
604 18048           C = sha_info->digest[2];
605 18048           D = sha_info->digest[3];
606 18048           E = sha_info->digest[4];
607 18048           WP = W;
608             #ifdef UNRAVEL
609 18048           FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
610 18048           FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
611 18048           FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
612 18048           FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
613 18048           FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
614 18048           FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
615 18048           FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
616 18048           FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
617 18048           sha_info->digest[0] = T32(sha_info->digest[0] + E);
618 18048           sha_info->digest[1] = T32(sha_info->digest[1] + T);
619 18048           sha_info->digest[2] = T32(sha_info->digest[2] + A);
620 18048           sha_info->digest[3] = T32(sha_info->digest[3] + B);
621 18048           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 18048           }
645              
646             /* initialize the SHA digest */
647              
648 18048           static void sha_init(SHA_INFO *sha_info)
649             {
650 18048           sha_info->digest[0] = 0x67452301L;
651 18048           sha_info->digest[1] = 0xefcdab89L;
652 18048           sha_info->digest[2] = 0x98badcfeL;
653 18048           sha_info->digest[3] = 0x10325476L;
654 18048           sha_info->digest[4] = 0xc3d2e1f0L;
655 18048           sha_info->count_lo = 0L;
656 18048           sha_info->count_hi = 0L;
657 18048           sha_info->local = 0;
658 18048           }
659              
660             /* update the SHA digest */
661              
662 36096           static void sha_update(SHA_INFO *sha_info, U8 *buffer, int count)
663             {
664             int i;
665             ULONGx clo;
666              
667 36096           clo = T32(sha_info->count_lo + ((ULONGx) count << 3));
668 36096 50         if (clo < sha_info->count_lo) {
669 0           ++sha_info->count_hi;
670             }
671 36096           sha_info->count_lo = clo;
672 36096           sha_info->count_hi += (ULONGx) count >> 29;
673 36096 100         if (sha_info->local) {
674 18048           i = SHA_BLOCKSIZE - sha_info->local;
675 18048 50         if (i > count) {
676 18048           i = count;
677             }
678 18048           memcpy(((U8 *) sha_info->data) + sha_info->local, buffer, i);
679 18048           count -= i;
680 18048           buffer += i;
681 18048           sha_info->local += i;
682 18048 50         if (sha_info->local == SHA_BLOCKSIZE) {
683 0           sha_transform(sha_info);
684             } else {
685 18048           return;
686             }
687             }
688 18048 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 18048           memcpy(sha_info->data, buffer, count);
695 18048           sha_info->local = count;
696             }
697              
698              
699 18048           static void sha_transform_and_copy(unsigned char digest[20], SHA_INFO *sha_info)
700             {
701 18048           sha_transform(sha_info);
702 18048           digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
703 18048           digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
704 18048           digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
705 18048           digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
706 18048           digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
707 18048           digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
708 18048           digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
709 18048           digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
710 18048           digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
711 18048           digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
712 18048           digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
713 18048           digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
714 18048           digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
715 18048           digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
716 18048           digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
717 18048           digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
718 18048           digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
719 18048           digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
720 18048           digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
721 18048           digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
722 18048           }
723              
724             /* finish computing the SHA digest */
725 18048           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 18048           lo_bit_count = sha_info->count_lo;
731 18048           hi_bit_count = sha_info->count_hi;
732 18048           count = (int) ((lo_bit_count >> 3) & 0x3f);
733 18048           ((U8 *) sha_info->data)[count++] = 0x80;
734 18048 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 18048           memset(((U8 *) sha_info->data) + count, 0,
740 18048           SHA_BLOCKSIZE - 8 - count);
741             }
742 18048           sha_info->data[56] = (U8)((hi_bit_count >> 24) & 0xff);
743 18048           sha_info->data[57] = (U8)((hi_bit_count >> 16) & 0xff);
744 18048           sha_info->data[58] = (U8)((hi_bit_count >> 8) & 0xff);
745 18048           sha_info->data[59] = (U8)((hi_bit_count >> 0) & 0xff);
746 18048           sha_info->data[60] = (U8)((lo_bit_count >> 24) & 0xff);
747 18048           sha_info->data[61] = (U8)((lo_bit_count >> 16) & 0xff);
748 18048           sha_info->data[62] = (U8)((lo_bit_count >> 8) & 0xff);
749 18048           sha_info->data[63] = (U8)((lo_bit_count >> 0) & 0xff);
750 18048           sha_transform_and_copy(digest, sha_info);
751 18048           }
752             /*----------------------------------------------------------------*/
753              
754             /* declared above since also used in md5
755             static const char *hexdigits = "0123456789abcdef";
756             */
757              
758 18048           static void hex_20(const unsigned char* from, char* to) {
759 18048           const unsigned char *end = from + 20;
760 18048           char *d = to;
761              
762 379008 100         while (from < end) {
763 360960           *d++ = hexdigits[(*from >> 4)];
764 360960           *d++ = hexdigits[(*from & 0x0F)];
765 360960           from++;
766             }
767 18048           *d = '\0';
768 18048           }
769              
770 18048           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 18048           uu_pack_v1(io, (U8*)&packed);
781              
782 18048           sha_init(&context);
783              
784 18048           sha_update(&context, (U8*)&packed, sizeof(packed));
785 18048 50         if (name)
786 18048           sha_update(&context, (U8*)name, (int)strlen(name));
787              
788 18048           sha_final((U8*)&digeststr, &context);
789 18048           digeststr[20] = '\0';
790              
791 18048           hex_20(digeststr, tmp);
792 18048           tmp[32] = '\0';
793              
794             /* hyphenate */
795 18048           Move(&tmp[20], &tmp[21], 12, char); tmp[20] = '-';
796 18048           Move(&tmp[16], &tmp[17], 17, char); tmp[16] = '-';
797 18048           Move(&tmp[12], &tmp[13], 22, char); tmp[12] = '-';
798 18048           Move(&tmp[ 8], &tmp[ 9], 27, char); tmp[ 8] = '-';
799 18048           tmp[36] = '\0';
800              
801             /* version */
802 18048           tmp[14] = '5';
803              
804             /* variant */
805 18048           vardig = tmp[19] - 48;
806 18048 100         if (vardig > 9) vardig -= 7;
807 18048 100         if (vardig > 15) vardig -= 32;
808 18048           vardig = (vardig & 0x3) | 0x8;
809 18048 50         if (vardig > 9) vardig += 87;
810 18048           else vardig += 48;
811 18048           tmp[19] = vardig;
812              
813 18048           uu_parse(tmp, io);
814 18048           }
815              
816             /* ex:set ts=2 sw=2 itab=spaces: */