File Coverage

Scrypt.xs
Criterion Covered Total %
statement 140 145 96.5
branch 24 30 80.0
condition n/a
subroutine n/a
pod n/a
total 164 175 93.7


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include
6             #include
7              
8             static const int SCRYPT_SCRATCHPAD_SIZE = 131072 + 63;
9              
10 32           static inline uint32_t le32dec(const void *pp)
11             {
12 32           const uint8_t *p = (uint8_t const *)pp;
13 32           return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
14 64           ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
15             }
16              
17 32           static inline void le32enc(void *pp, uint32_t x)
18             {
19 32           uint8_t *p = (uint8_t *)pp;
20 32           p[0] = x & 0xff;
21 32           p[1] = (x >> 8) & 0xff;
22 32           p[2] = (x >> 16) & 0xff;
23 32           p[3] = (x >> 24) & 0xff;
24 32           }
25              
26 5           static inline void be32enc(void *pp, uint32_t x)
27             {
28 5           uint8_t *p = (uint8_t *)pp;
29 5           p[3] = x & 0xff;
30 5           p[2] = (x >> 8) & 0xff;
31 5           p[1] = (x >> 16) & 0xff;
32 5           p[0] = (x >> 24) & 0xff;
33 5           }
34              
35             #define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
36              
37 4096           static inline void xor_salsa8(uint32_t B[16], const uint32_t Bx[16])
38             {
39             uint32_t x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15;
40             int i;
41              
42 4096           x00 = (B[ 0] ^= Bx[ 0]);
43 4096           x01 = (B[ 1] ^= Bx[ 1]);
44 4096           x02 = (B[ 2] ^= Bx[ 2]);
45 4096           x03 = (B[ 3] ^= Bx[ 3]);
46 4096           x04 = (B[ 4] ^= Bx[ 4]);
47 4096           x05 = (B[ 5] ^= Bx[ 5]);
48 4096           x06 = (B[ 6] ^= Bx[ 6]);
49 4096           x07 = (B[ 7] ^= Bx[ 7]);
50 4096           x08 = (B[ 8] ^= Bx[ 8]);
51 4096           x09 = (B[ 9] ^= Bx[ 9]);
52 4096           x10 = (B[10] ^= Bx[10]);
53 4096           x11 = (B[11] ^= Bx[11]);
54 4096           x12 = (B[12] ^= Bx[12]);
55 4096           x13 = (B[13] ^= Bx[13]);
56 4096           x14 = (B[14] ^= Bx[14]);
57 4096           x15 = (B[15] ^= Bx[15]);
58 20480 100         for (i = 0; i < 8; i += 2) {
59             /* Operate on columns. */
60 16384           x04 ^= ROTL(x00 + x12, 7); x09 ^= ROTL(x05 + x01, 7);
61 16384           x14 ^= ROTL(x10 + x06, 7); x03 ^= ROTL(x15 + x11, 7);
62              
63 16384           x08 ^= ROTL(x04 + x00, 9); x13 ^= ROTL(x09 + x05, 9);
64 16384           x02 ^= ROTL(x14 + x10, 9); x07 ^= ROTL(x03 + x15, 9);
65              
66 16384           x12 ^= ROTL(x08 + x04, 13); x01 ^= ROTL(x13 + x09, 13);
67 16384           x06 ^= ROTL(x02 + x14, 13); x11 ^= ROTL(x07 + x03, 13);
68              
69 16384           x00 ^= ROTL(x12 + x08, 18); x05 ^= ROTL(x01 + x13, 18);
70 16384           x10 ^= ROTL(x06 + x02, 18); x15 ^= ROTL(x11 + x07, 18);
71              
72             /* Operate on rows. */
73 16384           x01 ^= ROTL(x00 + x03, 7); x06 ^= ROTL(x05 + x04, 7);
74 16384           x11 ^= ROTL(x10 + x09, 7); x12 ^= ROTL(x15 + x14, 7);
75              
76 16384           x02 ^= ROTL(x01 + x00, 9); x07 ^= ROTL(x06 + x05, 9);
77 16384           x08 ^= ROTL(x11 + x10, 9); x13 ^= ROTL(x12 + x15, 9);
78              
79 16384           x03 ^= ROTL(x02 + x01, 13); x04 ^= ROTL(x07 + x06, 13);
80 16384           x09 ^= ROTL(x08 + x11, 13); x14 ^= ROTL(x13 + x12, 13);
81              
82 16384           x00 ^= ROTL(x03 + x02, 18); x05 ^= ROTL(x04 + x07, 18);
83 16384           x10 ^= ROTL(x09 + x08, 18); x15 ^= ROTL(x14 + x13, 18);
84             }
85 4096           B[ 0] += x00;
86 4096           B[ 1] += x01;
87 4096           B[ 2] += x02;
88 4096           B[ 3] += x03;
89 4096           B[ 4] += x04;
90 4096           B[ 5] += x05;
91 4096           B[ 6] += x06;
92 4096           B[ 7] += x07;
93 4096           B[ 8] += x08;
94 4096           B[ 9] += x09;
95 4096           B[10] += x10;
96 4096           B[11] += x11;
97 4096           B[12] += x12;
98 4096           B[13] += x13;
99 4096           B[14] += x14;
100 4096           B[15] += x15;
101 4096           }
102              
103             typedef struct HMAC_SHA256Context {
104             SHA256_CTX ictx;
105             SHA256_CTX octx;
106             } HMAC_SHA256_CTX;
107              
108             /* Initialize an HMAC-SHA256 operation with the given key. */
109             static void
110 2           HMAC_SHA256_Init(HMAC_SHA256_CTX *ctx, const void *_K, size_t Klen)
111             {
112             unsigned char pad[64];
113             unsigned char khash[32];
114 2           const unsigned char *K = (const unsigned char *)_K;
115             size_t i;
116              
117             /* If Klen > 64, the key is really SHA256(K). */
118 2 50         if (Klen > 64) {
119 2           SHA256_Init(&ctx->ictx);
120 2           SHA256_Update(&ctx->ictx, K, Klen);
121 2           SHA256_Final(khash, &ctx->ictx);
122 2           K = khash;
123 2           Klen = 32;
124             }
125              
126             /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
127 2           SHA256_Init(&ctx->ictx);
128 2           memset(pad, 0x36, 64);
129 66 100         for (i = 0; i < Klen; i++)
130 64           pad[i] ^= K[i];
131 2           SHA256_Update(&ctx->ictx, pad, 64);
132              
133             /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
134 2           SHA256_Init(&ctx->octx);
135 2           memset(pad, 0x5c, 64);
136 66 100         for (i = 0; i < Klen; i++)
137 64           pad[i] ^= K[i];
138 2           SHA256_Update(&ctx->octx, pad, 64);
139              
140             /* Clean the stack. */
141 2           memset(khash, 0, 32);
142 2           }
143              
144             /* Add bytes to the HMAC-SHA256 operation. */
145             static void
146 7           HMAC_SHA256_Update(HMAC_SHA256_CTX *ctx, const void *in, size_t len)
147             {
148             /* Feed data to the inner SHA256 operation. */
149 7           SHA256_Update(&ctx->ictx, in, len);
150 7           }
151              
152             /* Finish an HMAC-SHA256 operation. */
153             static void
154 5           HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX *ctx)
155             {
156             unsigned char ihash[32];
157              
158             /* Finish the inner SHA256 operation. */
159 5           SHA256_Final(ihash, &ctx->ictx);
160              
161             /* Feed the inner hash to the outer SHA256 operation. */
162 5           SHA256_Update(&ctx->octx, ihash, 32);
163              
164             /* Finish the outer SHA256 operation. */
165 5           SHA256_Final(digest, &ctx->octx);
166              
167             /* Clean the stack. */
168 5           memset(ihash, 0, 32);
169 5           }
170              
171             /**
172             * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
173             * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
174             * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
175             */
176             void
177 2           PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt,
178             size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen)
179             {
180             HMAC_SHA256_CTX PShctx, hctx;
181             size_t i;
182             uint8_t ivec[4];
183             uint8_t U[32];
184             uint8_t T[32];
185             uint64_t j;
186             int k;
187             size_t clen;
188              
189             /* Compute HMAC state after processing P and S. */
190 2           HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
191 2           HMAC_SHA256_Update(&PShctx, salt, saltlen);
192              
193             /* Iterate through the blocks. */
194 7 100         for (i = 0; i * 32 < dkLen; i++) {
195             /* Generate INT(i + 1). */
196 5           be32enc(ivec, (uint32_t)(i + 1));
197              
198             /* Compute U_1 = PRF(P, S || INT(i)). */
199 5           memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
200 5           HMAC_SHA256_Update(&hctx, ivec, 4);
201 5           HMAC_SHA256_Final(U, &hctx);
202              
203             /* T_i = U_1 ... */
204 5           memcpy(T, U, 32);
205              
206 5 50         for (j = 2; j <= c; j++) {
207             /* Compute U_j. */
208 0           HMAC_SHA256_Init(&hctx, passwd, passwdlen);
209 0           HMAC_SHA256_Update(&hctx, U, 32);
210 0           HMAC_SHA256_Final(U, &hctx);
211              
212             /* ... xor U_j ... */
213 0 0         for (k = 0; k < 32; k++)
214 0           T[k] ^= U[k];
215             }
216              
217             /* Copy as many bytes as necessary into buf. */
218 5           clen = dkLen - i * 32;
219 5 100         if (clen > 32)
220 3           clen = 32;
221 5           memcpy(&buf[i * 32], T, clen);
222             }
223              
224             /* Clean PShctx, since we never called _Final on it. */
225 2           memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
226 2           }
227              
228 1           void scrypt_1024_1_1_256(const char *input, size_t inputlen, char *output)
229 1           {
230             uint8_t B[128];
231             uint32_t X[32];
232             uint32_t *V;
233             uint32_t i, j, k;
234 1           char scratchpad[SCRYPT_SCRATCHPAD_SIZE];
235              
236 1           V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
237              
238 1           PBKDF2_SHA256((const uint8_t *)input, inputlen, (const uint8_t *)input, inputlen, 1, B, 128);
239              
240 33 100         for (k = 0; k < 32; k++)
241 32           X[k] = le32dec(&B[4 * k]);
242              
243 1025 100         for (i = 0; i < 1024; i++) {
244 1024           memcpy(&V[i * 32], X, 128);
245 1024           xor_salsa8(&X[0], &X[16]);
246 1024           xor_salsa8(&X[16], &X[0]);
247             }
248 1025 100         for (i = 0; i < 1024; i++) {
249 1024           j = 32 * (X[16] & 1023);
250 33792 100         for (k = 0; k < 32; k++)
251 32768           X[k] ^= V[j + k];
252 1024           xor_salsa8(&X[0], &X[16]);
253 1024           xor_salsa8(&X[16], &X[0]);
254             }
255              
256 33 100         for (k = 0; k < 32; k++)
257 32           le32enc(&B[4 * k], X[k]);
258              
259 1           PBKDF2_SHA256((const uint8_t *)input, inputlen, B, 128, 1, (uint8_t *)output, 32);
260 1           }
261              
262             MODULE = Crypt::Digest::Scrypt PACKAGE = Crypt::Digest::Scrypt
263              
264             PROTOTYPES: DISABLE
265              
266             void scrypt_1024_1_1_256(SV *svdata)
267             PPCODE:
268             {
269             char hash[32];
270             STRLEN len;
271 1 50         const char *data = (const char *)SvPV(svdata, len);
272 1           scrypt_1024_1_1_256(data, len, hash);
273 1           SV *pv = newSVpvn(hash, sizeof(hash));
274 1           SvPOK_only (pv);
275 1 50         XPUSHs(sv_2mortal(pv));
276             }