… | |
… | |
3 | #include "XSUB.h" |
3 | #include "XSUB.h" |
4 | |
4 | |
5 | #include <time.h> |
5 | #include <time.h> |
6 | #include <stdlib.h> |
6 | #include <stdlib.h> |
7 | #include <stdint.h> |
7 | #include <stdint.h> |
|
|
8 | |
|
|
9 | #include "perlmulticore.h" |
8 | |
10 | |
9 | /* NIST Secure Hash Algorithm */ |
11 | /* NIST Secure Hash Algorithm */ |
10 | /* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */ |
12 | /* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */ |
11 | /* from Peter C. Gutmann's implementation as found in */ |
13 | /* from Peter C. Gutmann's implementation as found in */ |
12 | /* Applied Cryptography by Bruce Schneier */ |
14 | /* Applied Cryptography by Bruce Schneier */ |
… | |
… | |
51 | #define a_const __attribute__((__const__)) |
53 | #define a_const __attribute__((__const__)) |
52 | |
54 | |
53 | /* Useful defines & typedefs */ |
55 | /* Useful defines & typedefs */ |
54 | |
56 | |
55 | #if defined(U64TYPE) && (defined(USE_64_BIT_INT) || ((BYTEORDER != 0x1234) && (BYTEORDER != 0x4321))) |
57 | #if defined(U64TYPE) && (defined(USE_64_BIT_INT) || ((BYTEORDER != 0x1234) && (BYTEORDER != 0x4321))) |
56 | typedef U64TYPE ULONG; |
58 | typedef U64TYPE XULONG; |
57 | # if BYTEORDER == 0x1234 |
59 | # if BYTEORDER == 0x1234 |
58 | # undef BYTEORDER |
60 | # undef BYTEORDER |
59 | # define BYTEORDER 0x12345678 |
61 | # define BYTEORDER 0x12345678 |
60 | # elif BYTEORDER == 0x4321 |
62 | # elif BYTEORDER == 0x4321 |
61 | # undef BYTEORDER |
63 | # undef BYTEORDER |
62 | # define BYTEORDER 0x87654321 |
64 | # define BYTEORDER 0x87654321 |
63 | # endif |
65 | # endif |
64 | #else |
66 | #else |
65 | typedef uint_fast32_t ULONG; /* 32-or-more-bit quantity */ |
67 | typedef uint_fast32_t XULONG; /* 32-or-more-bit quantity */ |
66 | #endif |
68 | #endif |
67 | |
69 | |
68 | #if GCCX86ASM |
70 | #if GCCX86ASM |
69 | # define zprefix(n) ({ int _r; __asm__ ("bsrl %1, %0" : "=r" (_r) : "r" (n)); 31 - _r ; }) |
71 | # define zprefix(n) ({ int _r; __asm__ ("bsrl %1, %0" : "=r" (_r) : "r" (n)); 31 - _r ; }) |
70 | #elif __GNUC__ > 2 && __GNUC_MINOR__ > 3 |
72 | #elif __GNUC__ > 2 && __GNUC_MINOR__ > 3 |
71 | # define zprefix(n) (__extension__ ({ uint32_t n__ = (n); n ? __builtin_clz (n) : 32; })) |
73 | # define zprefix(n) (__extension__ ({ uint32_t n__ = (n); n ? __builtin_clz (n) : 32; })) |
72 | #else |
74 | #else |
73 | static int a_const zprefix (ULONG n) |
75 | static int a_const zprefix (U32 n) |
74 | { |
76 | { |
75 | static char zp[256] = |
77 | static char zp[256] = |
76 | { |
78 | { |
77 | 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, |
79 | 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, |
78 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
80 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
… | |
… | |
102 | |
104 | |
103 | #define SHA_BLOCKSIZE 64 |
105 | #define SHA_BLOCKSIZE 64 |
104 | #define SHA_DIGESTSIZE 20 |
106 | #define SHA_DIGESTSIZE 20 |
105 | |
107 | |
106 | typedef struct { |
108 | typedef struct { |
107 | ULONG digest[5]; /* message digest */ |
109 | U32 digest[5]; /* message digest */ |
108 | ULONG count; /* 32-bit bit count */ |
110 | U32 count; /* 32-bit bit count */ |
109 | int local; /* unprocessed amount in data */ |
111 | int local; /* unprocessed amount in data */ |
110 | U8 data[SHA_BLOCKSIZE]; /* SHA data buffer */ |
112 | U8 data[SHA_BLOCKSIZE]; /* SHA data buffer */ |
111 | } SHA_INFO; |
113 | } SHA_INFO; |
112 | |
114 | |
113 | |
115 | |
… | |
… | |
150 | |
152 | |
151 | static void a_regparm(1) sha_transform(SHA_INFO *restrict sha_info) |
153 | static void a_regparm(1) sha_transform(SHA_INFO *restrict sha_info) |
152 | { |
154 | { |
153 | int i; |
155 | int i; |
154 | U8 *restrict dp; |
156 | U8 *restrict dp; |
155 | ULONG T, A, B, C, D, E, W[80], *restrict WP; |
157 | U32 A, B, C, D, E, W[80], *restrict WP; |
|
|
158 | XULONG T; |
156 | |
159 | |
157 | dp = sha_info->data; |
160 | dp = sha_info->data; |
158 | |
161 | |
159 | #if BYTEORDER == 0x1234 |
162 | #if BYTEORDER == 0x1234 |
160 | assert(sizeof(ULONG) == 4); |
163 | assert(sizeof(XULONG) == 4); |
161 | # ifdef HAS_NTOHL |
164 | # ifdef HAS_NTOHL |
162 | for (i = 0; i < 16; ++i) { |
165 | for (i = 0; i < 16; ++i) { |
163 | T = *((ULONG *) dp); |
166 | T = *((XULONG *) dp); |
164 | dp += 4; |
167 | dp += 4; |
165 | W[i] = ntohl (T); |
168 | W[i] = ntohl (T); |
166 | } |
169 | } |
167 | # else |
170 | # else |
168 | for (i = 0; i < 16; ++i) { |
171 | for (i = 0; i < 16; ++i) { |
169 | T = *((ULONG *) dp); |
172 | T = *((XULONG *) dp); |
170 | dp += 4; |
173 | dp += 4; |
171 | W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | |
174 | W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | |
172 | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); |
175 | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); |
173 | } |
176 | } |
174 | # endif |
177 | # endif |
175 | #elif BYTEORDER == 0x4321 |
178 | #elif BYTEORDER == 0x4321 |
176 | assert(sizeof(ULONG) == 4); |
179 | assert(sizeof(XULONG) == 4); |
177 | for (i = 0; i < 16; ++i) { |
180 | for (i = 0; i < 16; ++i) { |
178 | T = *((ULONG *) dp); |
181 | T = *((XULONG *) dp); |
179 | dp += 4; |
182 | dp += 4; |
180 | W[i] = T32(T); |
183 | W[i] = T32(T); |
181 | } |
184 | } |
182 | #elif BYTEORDER == 0x12345678 |
185 | #elif BYTEORDER == 0x12345678 |
183 | assert(sizeof(ULONG) == 8); |
186 | assert(sizeof(XULONG) == 8); |
184 | for (i = 0; i < 16; i += 2) { |
187 | for (i = 0; i < 16; i += 2) { |
185 | T = *((ULONG *) dp); |
188 | T = *((XULONG *) dp); |
186 | dp += 8; |
189 | dp += 8; |
187 | W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | |
190 | W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | |
188 | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); |
191 | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); |
189 | T >>= 32; |
192 | T >>= 32; |
190 | W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | |
193 | W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | |
191 | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); |
194 | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); |
192 | } |
195 | } |
193 | #elif BYTEORDER == 0x87654321 |
196 | #elif BYTEORDER == 0x87654321 |
194 | assert(sizeof(ULONG) == 8); |
197 | assert(sizeof(XULONG) == 8); |
195 | for (i = 0; i < 16; i += 2) { |
198 | for (i = 0; i < 16; i += 2) { |
196 | T = *((ULONG *) dp); |
199 | T = *((XULONG *) dp); |
197 | dp += 8; |
200 | dp += 8; |
198 | W[i] = T32(T >> 32); |
201 | W[i] = T32(T >> 32); |
199 | W[i+1] = T32(T); |
202 | W[i+1] = T32(T); |
200 | } |
203 | } |
201 | #else |
204 | #else |
… | |
… | |
302 | : zprefix (sha_info->digest[1]) + 32; |
305 | : zprefix (sha_info->digest[1]) + 32; |
303 | } |
306 | } |
304 | |
307 | |
305 | #define TRIALCHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./;<=>?@[]{}^_|" |
308 | #define TRIALCHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&()*+,-./;<=>?@[]{}^_|" |
306 | |
309 | |
307 | static char nextenc[256]; |
310 | static char |
|
|
311 | nextenc[256]; |
308 | |
312 | |
309 | static char rand_char () |
313 | static char |
|
|
314 | rand_char () |
310 | { |
315 | { |
311 | return TRIALCHAR[rand () % sizeof (TRIALCHAR)]; |
316 | return TRIALCHAR[(int)(Drand01 () * sizeof (TRIALCHAR))]; |
312 | } |
317 | } |
313 | |
318 | |
314 | typedef double (*NVTime)(void); |
319 | typedef double (*NVTime)(void); |
315 | |
320 | |
316 | static double simple_nvtime (void) |
321 | static double |
|
|
322 | simple_nvtime (void) |
317 | { |
323 | { |
318 | return time (0); |
324 | return time (0); |
319 | } |
325 | } |
320 | |
326 | |
321 | static NVTime get_nvtime (void) |
327 | static NVTime |
|
|
328 | get_nvtime (void) |
322 | { |
329 | { |
323 | SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); |
330 | SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); |
324 | |
331 | |
325 | if (svp && SvIOK(*svp)) |
332 | if (svp && SvIOK(*svp)) |
326 | return INT2PTR(NVTime, SvIV(*svp)); |
333 | return INT2PTR(NVTime, SvIV(*svp)); |
… | |
… | |
404 | resource, trial); |
411 | resource, trial); |
405 | |
412 | |
406 | if (toklen > 8000) |
413 | if (toklen > 8000) |
407 | croak ("token length must be <= 8000 in this implementation\n"); |
414 | croak ("token length must be <= 8000 in this implementation\n"); |
408 | |
415 | |
|
|
416 | perlinterp_release (); |
|
|
417 | |
409 | i = toklen + extrarand; |
418 | i = toklen + extrarand; |
410 | while (toklen < i) |
419 | while (toklen < i) |
411 | token[toklen++] = rand_char (); |
420 | token[toklen++] = rand_char (); |
412 | |
421 | |
413 | sha_init (&ctx1); |
422 | sha_init (&ctx1); |
… | |
… | |
431 | do { |
440 | do { |
432 | *s = nextenc [*s]; |
441 | *s = nextenc [*s]; |
433 | } while (*s++ == 'a'); |
442 | } while (*s++ == 'a'); |
434 | } |
443 | } |
435 | |
444 | |
|
|
445 | perlinterp_acquire (); |
|
|
446 | |
436 | RETVAL = newSVpvn (token, toklen); |
447 | RETVAL = newSVpvn (token, toklen); |
437 | } |
448 | } |
438 | OUTPUT: |
449 | OUTPUT: |
439 | RETVAL |
450 | RETVAL |
440 | |
451 | |